base_dyn_inst.hh revision 13953:43ae8a30ec1f
110037SARM gem5 Developers/* 212271Sjose.marinho@arm.com * Copyright (c) 2011, 2013, 2016-2018 ARM Limited 312271Sjose.marinho@arm.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 410037SARM gem5 Developers * All rights reserved. 512271Sjose.marinho@arm.com * 612271Sjose.marinho@arm.com * The license below extends only to copyright in the software and shall 712271Sjose.marinho@arm.com * not be construed as granting a license to any other intellectual 812271Sjose.marinho@arm.com * property including but not limited to intellectual property relating 912271Sjose.marinho@arm.com * to a hardware implementation of the functionality of the software 1012271Sjose.marinho@arm.com * licensed hereunder. You may use the software subject to the license 1112271Sjose.marinho@arm.com * terms below provided that you ensure that this notice is replicated 1212271Sjose.marinho@arm.com * unmodified and in its entirety in all distributions of the software, 1310037SARM gem5 Developers * modified or unmodified, in source code or in binary form. 1412271Sjose.marinho@arm.com * 1512271Sjose.marinho@arm.com * Copyright (c) 2004-2006 The Regents of The University of Michigan 1612271Sjose.marinho@arm.com * Copyright (c) 2009 The University of Edinburgh 1712271Sjose.marinho@arm.com * All rights reserved. 1812271Sjose.marinho@arm.com * 1912271Sjose.marinho@arm.com * Redistribution and use in source and binary forms, with or without 2012271Sjose.marinho@arm.com * modification, are permitted provided that the following conditions are 2112271Sjose.marinho@arm.com * met: redistributions of source code must retain the above copyright 2212271Sjose.marinho@arm.com * notice, this list of conditions and the following disclaimer; 2312271Sjose.marinho@arm.com * redistributions in binary form must reproduce the above copyright 2412271Sjose.marinho@arm.com * notice, this list of conditions and the following disclaimer in the 2512271Sjose.marinho@arm.com * documentation and/or other materials provided with the distribution; 2612271Sjose.marinho@arm.com * neither the name of the copyright holders nor the names of its 2712271Sjose.marinho@arm.com * contributors may be used to endorse or promote products derived from 2812271Sjose.marinho@arm.com * this software without specific prior written permission. 2912271Sjose.marinho@arm.com * 3012271Sjose.marinho@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3112271Sjose.marinho@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3212271Sjose.marinho@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3312271Sjose.marinho@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3412271Sjose.marinho@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3512271Sjose.marinho@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3612271Sjose.marinho@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3710037SARM gem5 Developers * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3810037SARM gem5 Developers * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3910037SARM gem5 Developers * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 4010037SARM gem5 Developers * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4110037SARM gem5 Developers * 4210037SARM gem5 Developers * Authors: Kevin Lim 4310037SARM gem5 Developers * Timothy M. Jones 4410037SARM gem5 Developers */ 4510037SARM gem5 Developers 4610037SARM gem5 Developers#ifndef __CPU_BASE_DYN_INST_HH__ 4710037SARM gem5 Developers#define __CPU_BASE_DYN_INST_HH__ 4810037SARM gem5 Developers 4910037SARM gem5 Developers#include <array> 5010037SARM gem5 Developers#include <bitset> 5110037SARM gem5 Developers#include <deque> 5210037SARM gem5 Developers#include <list> 5310037SARM gem5 Developers#include <string> 5410037SARM gem5 Developers 5510037SARM gem5 Developers#include "arch/generic/tlb.hh" 5610037SARM gem5 Developers#include "arch/utility.hh" 5710037SARM gem5 Developers#include "base/trace.hh" 5810037SARM gem5 Developers#include "config/the_isa.hh" 5910037SARM gem5 Developers#include "cpu/checker/cpu.hh" 6010037SARM gem5 Developers#include "cpu/exec_context.hh" 6110037SARM gem5 Developers#include "cpu/exetrace.hh" 6210037SARM gem5 Developers#include "cpu/inst_res.hh" 6310037SARM gem5 Developers#include "cpu/inst_seq.hh" 6410037SARM gem5 Developers#include "cpu/op_class.hh" 6510037SARM gem5 Developers#include "cpu/static_inst.hh" 6611258Skarthik.sangaiah@arm.com#include "cpu/translation.hh" 6711258Skarthik.sangaiah@arm.com#include "mem/packet.hh" 6811258Skarthik.sangaiah@arm.com#include "mem/request.hh" 6911258Skarthik.sangaiah@arm.com#include "sim/byteswap.hh" 7011258Skarthik.sangaiah@arm.com#include "sim/system.hh" 7111258Skarthik.sangaiah@arm.com 7210037SARM gem5 Developers/** 7310037SARM gem5 Developers * @file 7410037SARM gem5 Developers * Defines a dynamic instruction context. 7510037SARM gem5 Developers */ 7610037SARM gem5 Developers 7710037SARM gem5 Developerstemplate <class Impl> 7810037SARM gem5 Developersclass BaseDynInst : public ExecContext, public RefCounted 7910037SARM gem5 Developers{ 8010037SARM gem5 Developers public: 8110037SARM gem5 Developers // Typedef for the CPU. 8210037SARM gem5 Developers typedef typename Impl::CPUType ImplCPU; 8310037SARM gem5 Developers typedef typename ImplCPU::ImplState ImplState; 8410037SARM gem5 Developers using VecRegContainer = TheISA::VecRegContainer; 8510037SARM gem5 Developers 8610037SARM gem5 Developers using LSQRequestPtr = typename Impl::CPUPol::LSQ::LSQRequest*; 8710037SARM gem5 Developers using LQIterator = typename Impl::CPUPol::LSQUnit::LQIterator; 8810037SARM gem5 Developers using SQIterator = typename Impl::CPUPol::LSQUnit::SQIterator; 8910037SARM gem5 Developers 9010037SARM gem5 Developers // The DynInstPtr type. 9110037SARM gem5 Developers typedef typename Impl::DynInstPtr DynInstPtr; 9210037SARM gem5 Developers typedef RefCountingPtr<BaseDynInst<Impl> > BaseDynInstPtr; 9310037SARM gem5 Developers 9410037SARM gem5 Developers // The list of instructions iterator type. 9510037SARM gem5 Developers typedef typename std::list<DynInstPtr>::iterator ListIt; 9610037SARM gem5 Developers 9710037SARM gem5 Developers enum { 9810037SARM gem5 Developers MaxInstSrcRegs = TheISA::MaxInstSrcRegs, /// Max source regs 9910037SARM gem5 Developers MaxInstDestRegs = TheISA::MaxInstDestRegs /// Max dest regs 10010037SARM gem5 Developers }; 10110037SARM gem5 Developers 10210037SARM gem5 Developers protected: 10310037SARM gem5 Developers enum Status { 10410037SARM gem5 Developers IqEntry, /// Instruction is in the IQ 10510037SARM gem5 Developers RobEntry, /// Instruction is in the ROB 10610037SARM gem5 Developers LsqEntry, /// Instruction is in the LSQ 10710037SARM gem5 Developers Completed, /// Instruction has completed 10810037SARM gem5 Developers ResultReady, /// Instruction has its result 10910037SARM gem5 Developers CanIssue, /// Instruction can issue and execute 11010037SARM gem5 Developers Issued, /// Instruction has issued 11110037SARM gem5 Developers Executed, /// Instruction has executed 11210037SARM gem5 Developers CanCommit, /// Instruction can commit 11311258Skarthik.sangaiah@arm.com AtCommit, /// Instruction has reached commit 11411258Skarthik.sangaiah@arm.com Committed, /// Instruction has committed 11511258Skarthik.sangaiah@arm.com Squashed, /// Instruction is squashed 11611258Skarthik.sangaiah@arm.com SquashedInIQ, /// Instruction is squashed in the IQ 11711258Skarthik.sangaiah@arm.com SquashedInLSQ, /// Instruction is squashed in the LSQ 11811258Skarthik.sangaiah@arm.com SquashedInROB, /// Instruction is squashed in the ROB 11911258Skarthik.sangaiah@arm.com RecoverInst, /// Is a recover instruction 12010037SARM gem5 Developers BlockingInst, /// Is a blocking instruction 12110037SARM gem5 Developers ThreadsyncWait, /// Is a thread synchronization instruction 12210037SARM gem5 Developers SerializeBefore, /// Needs to serialize on 12310037SARM gem5 Developers /// instructions ahead of it 12410037SARM gem5 Developers SerializeAfter, /// Needs to serialize instructions behind it 12510037SARM gem5 Developers SerializeHandled, /// Serialization has been handled 12610037SARM gem5 Developers NumStatus 12710037SARM gem5 Developers }; 12810037SARM gem5 Developers 12910037SARM gem5 Developers enum Flags { 13010037SARM gem5 Developers NotAnInst, 13110037SARM gem5 Developers TranslationStarted, 13210037SARM gem5 Developers TranslationCompleted, 13310037SARM gem5 Developers PossibleLoadViolation, 13410037SARM gem5 Developers HitExternalSnoop, 13510037SARM gem5 Developers EffAddrValid, 13610037SARM gem5 Developers RecordResult, 13710037SARM gem5 Developers Predicate, 13810037SARM gem5 Developers MemAccPredicate, 13910037SARM gem5 Developers PredTaken, 14010037SARM gem5 Developers IsStrictlyOrdered, 14110037SARM gem5 Developers ReqMade, 14210037SARM gem5 Developers MemOpDone, 14310037SARM gem5 Developers MaxFlags 14410037SARM gem5 Developers }; 14510037SARM gem5 Developers 14610037SARM gem5 Developers public: 14710037SARM gem5 Developers /** The sequence number of the instruction. */ 14810037SARM gem5 Developers InstSeqNum seqNum; 14910037SARM gem5 Developers 15010037SARM gem5 Developers /** The StaticInst used by this BaseDynInst. */ 15110037SARM gem5 Developers const StaticInstPtr staticInst; 15210037SARM gem5 Developers 15310037SARM gem5 Developers /** Pointer to the Impl's CPU object. */ 15410037SARM gem5 Developers ImplCPU *cpu; 15510037SARM gem5 Developers 15610037SARM gem5 Developers BaseCPU *getCpuPtr() { return cpu; } 15710037SARM gem5 Developers 15810037SARM gem5 Developers /** Pointer to the thread state. */ 15910037SARM gem5 Developers ImplState *thread; 16010037SARM gem5 Developers 16110037SARM gem5 Developers /** The kind of fault this instruction has generated. */ 16210037SARM gem5 Developers Fault fault; 163 164 /** InstRecord that tracks this instructions. */ 165 Trace::InstRecord *traceData; 166 167 protected: 168 /** The result of the instruction; assumes an instruction can have many 169 * destination registers. 170 */ 171 std::queue<InstResult> instResult; 172 173 /** PC state for this instruction. */ 174 TheISA::PCState pc; 175 176 /* An amalgamation of a lot of boolean values into one */ 177 std::bitset<MaxFlags> instFlags; 178 179 /** The status of this BaseDynInst. Several bits can be set. */ 180 std::bitset<NumStatus> status; 181 182 /** Whether or not the source register is ready. 183 * @todo: Not sure this should be here vs the derived class. 184 */ 185 std::bitset<MaxInstSrcRegs> _readySrcRegIdx; 186 187 public: 188 /** The thread this instruction is from. */ 189 ThreadID threadNumber; 190 191 /** Iterator pointing to this BaseDynInst in the list of all insts. */ 192 ListIt instListIt; 193 194 ////////////////////// Branch Data /////////////// 195 /** Predicted PC state after this instruction. */ 196 TheISA::PCState predPC; 197 198 /** The Macroop if one exists */ 199 const StaticInstPtr macroop; 200 201 /** How many source registers are ready. */ 202 uint8_t readyRegs; 203 204 public: 205 /////////////////////// Load Store Data ////////////////////// 206 /** The effective virtual address (lds & stores only). */ 207 Addr effAddr; 208 209 /** The effective physical address. */ 210 Addr physEffAddr; 211 212 /** The memory request flags (from translation). */ 213 unsigned memReqFlags; 214 215 /** data address space ID, for loads & stores. */ 216 short asid; 217 218 /** The size of the request */ 219 uint8_t effSize; 220 221 /** Pointer to the data for the memory access. */ 222 uint8_t *memData; 223 224 /** Load queue index. */ 225 int16_t lqIdx; 226 LQIterator lqIt; 227 228 /** Store queue index. */ 229 int16_t sqIdx; 230 SQIterator sqIt; 231 232 233 /////////////////////// TLB Miss ////////////////////// 234 /** 235 * Saved memory request (needed when the DTB address translation is 236 * delayed due to a hw page table walk). 237 */ 238 LSQRequestPtr savedReq; 239 240 /////////////////////// Checker ////////////////////// 241 // Need a copy of main request pointer to verify on writes. 242 RequestPtr reqToVerify; 243 244 protected: 245 /** Flattened register index of the destination registers of this 246 * instruction. 247 */ 248 std::array<RegId, TheISA::MaxInstDestRegs> _flatDestRegIdx; 249 250 /** Physical register index of the destination registers of this 251 * instruction. 252 */ 253 std::array<PhysRegIdPtr, TheISA::MaxInstDestRegs> _destRegIdx; 254 255 /** Physical register index of the source registers of this 256 * instruction. 257 */ 258 std::array<PhysRegIdPtr, TheISA::MaxInstSrcRegs> _srcRegIdx; 259 260 /** Physical register index of the previous producers of the 261 * architected destinations. 262 */ 263 std::array<PhysRegIdPtr, TheISA::MaxInstDestRegs> _prevDestRegIdx; 264 265 266 public: 267 /** Records changes to result? */ 268 void recordResult(bool f) { instFlags[RecordResult] = f; } 269 270 /** Is the effective virtual address valid. */ 271 bool effAddrValid() const { return instFlags[EffAddrValid]; } 272 void effAddrValid(bool b) { instFlags[EffAddrValid] = b; } 273 274 /** Whether or not the memory operation is done. */ 275 bool memOpDone() const { return instFlags[MemOpDone]; } 276 void memOpDone(bool f) { instFlags[MemOpDone] = f; } 277 278 bool notAnInst() const { return instFlags[NotAnInst]; } 279 void setNotAnInst() { instFlags[NotAnInst] = true; } 280 281 282 //////////////////////////////////////////// 283 // 284 // INSTRUCTION EXECUTION 285 // 286 //////////////////////////////////////////// 287 288 void demapPage(Addr vaddr, uint64_t asn) 289 { 290 cpu->demapPage(vaddr, asn); 291 } 292 void demapInstPage(Addr vaddr, uint64_t asn) 293 { 294 cpu->demapPage(vaddr, asn); 295 } 296 void demapDataPage(Addr vaddr, uint64_t asn) 297 { 298 cpu->demapPage(vaddr, asn); 299 } 300 301 Fault initiateMemRead(Addr addr, unsigned size, Request::Flags flags); 302 303 Fault writeMem(uint8_t *data, unsigned size, Addr addr, 304 Request::Flags flags, uint64_t *res); 305 306 Fault initiateMemAMO(Addr addr, unsigned size, Request::Flags flags, 307 AtomicOpFunctor *amo_op); 308 309 /** True if the DTB address translation has started. */ 310 bool translationStarted() const { return instFlags[TranslationStarted]; } 311 void translationStarted(bool f) { instFlags[TranslationStarted] = f; } 312 313 /** True if the DTB address translation has completed. */ 314 bool translationCompleted() const { return instFlags[TranslationCompleted]; } 315 void translationCompleted(bool f) { instFlags[TranslationCompleted] = f; } 316 317 /** True if this address was found to match a previous load and they issued 318 * out of order. If that happend, then it's only a problem if an incoming 319 * snoop invalidate modifies the line, in which case we need to squash. 320 * If nothing modified the line the order doesn't matter. 321 */ 322 bool possibleLoadViolation() const { return instFlags[PossibleLoadViolation]; } 323 void possibleLoadViolation(bool f) { instFlags[PossibleLoadViolation] = f; } 324 325 /** True if the address hit a external snoop while sitting in the LSQ. 326 * If this is true and a older instruction sees it, this instruction must 327 * reexecute 328 */ 329 bool hitExternalSnoop() const { return instFlags[HitExternalSnoop]; } 330 void hitExternalSnoop(bool f) { instFlags[HitExternalSnoop] = f; } 331 332 /** 333 * Returns true if the DTB address translation is being delayed due to a hw 334 * page table walk. 335 */ 336 bool isTranslationDelayed() const 337 { 338 return (translationStarted() && !translationCompleted()); 339 } 340 341 public: 342#ifdef DEBUG 343 void dumpSNList(); 344#endif 345 346 /** Returns the physical register index of the i'th destination 347 * register. 348 */ 349 PhysRegIdPtr renamedDestRegIdx(int idx) const 350 { 351 return _destRegIdx[idx]; 352 } 353 354 /** Returns the physical register index of the i'th source register. */ 355 PhysRegIdPtr renamedSrcRegIdx(int idx) const 356 { 357 assert(TheISA::MaxInstSrcRegs > idx); 358 return _srcRegIdx[idx]; 359 } 360 361 /** Returns the flattened register index of the i'th destination 362 * register. 363 */ 364 const RegId& flattenedDestRegIdx(int idx) const 365 { 366 return _flatDestRegIdx[idx]; 367 } 368 369 /** Returns the physical register index of the previous physical register 370 * that remapped to the same logical register index. 371 */ 372 PhysRegIdPtr prevDestRegIdx(int idx) const 373 { 374 return _prevDestRegIdx[idx]; 375 } 376 377 /** Renames a destination register to a physical register. Also records 378 * the previous physical register that the logical register mapped to. 379 */ 380 void renameDestReg(int idx, 381 PhysRegIdPtr renamed_dest, 382 PhysRegIdPtr previous_rename) 383 { 384 _destRegIdx[idx] = renamed_dest; 385 _prevDestRegIdx[idx] = previous_rename; 386 } 387 388 /** Renames a source logical register to the physical register which 389 * has/will produce that logical register's result. 390 * @todo: add in whether or not the source register is ready. 391 */ 392 void renameSrcReg(int idx, PhysRegIdPtr renamed_src) 393 { 394 _srcRegIdx[idx] = renamed_src; 395 } 396 397 /** Flattens a destination architectural register index into a logical 398 * index. 399 */ 400 void flattenDestReg(int idx, const RegId& flattened_dest) 401 { 402 _flatDestRegIdx[idx] = flattened_dest; 403 } 404 /** BaseDynInst constructor given a binary instruction. 405 * @param staticInst A StaticInstPtr to the underlying instruction. 406 * @param pc The PC state for the instruction. 407 * @param predPC The predicted next PC state for the instruction. 408 * @param seq_num The sequence number of the instruction. 409 * @param cpu Pointer to the instruction's CPU. 410 */ 411 BaseDynInst(const StaticInstPtr &staticInst, const StaticInstPtr ¯oop, 412 TheISA::PCState pc, TheISA::PCState predPC, 413 InstSeqNum seq_num, ImplCPU *cpu); 414 415 /** BaseDynInst constructor given a StaticInst pointer. 416 * @param _staticInst The StaticInst for this BaseDynInst. 417 */ 418 BaseDynInst(const StaticInstPtr &staticInst, const StaticInstPtr ¯oop); 419 420 /** BaseDynInst destructor. */ 421 ~BaseDynInst(); 422 423 private: 424 /** Function to initialize variables in the constructors. */ 425 void initVars(); 426 427 public: 428 /** Dumps out contents of this BaseDynInst. */ 429 void dump(); 430 431 /** Dumps out contents of this BaseDynInst into given string. */ 432 void dump(std::string &outstring); 433 434 /** Read this CPU's ID. */ 435 int cpuId() const { return cpu->cpuId(); } 436 437 /** Read this CPU's Socket ID. */ 438 uint32_t socketId() const { return cpu->socketId(); } 439 440 /** Read this CPU's data requestor ID */ 441 MasterID masterId() const { return cpu->dataMasterId(); } 442 443 /** Read this context's system-wide ID **/ 444 ContextID contextId() const { return thread->contextId(); } 445 446 /** Returns the fault type. */ 447 Fault getFault() const { return fault; } 448 /** TODO: This I added for the LSQRequest side to be able to modify the 449 * fault. There should be a better mechanism in place. */ 450 Fault& getFault() { return fault; } 451 452 /** Checks whether or not this instruction has had its branch target 453 * calculated yet. For now it is not utilized and is hacked to be 454 * always false. 455 * @todo: Actually use this instruction. 456 */ 457 bool doneTargCalc() { return false; } 458 459 /** Set the predicted target of this current instruction. */ 460 void setPredTarg(const TheISA::PCState &_predPC) 461 { 462 predPC = _predPC; 463 } 464 465 const TheISA::PCState &readPredTarg() { return predPC; } 466 467 /** Returns the predicted PC immediately after the branch. */ 468 Addr predInstAddr() { return predPC.instAddr(); } 469 470 /** Returns the predicted PC two instructions after the branch */ 471 Addr predNextInstAddr() { return predPC.nextInstAddr(); } 472 473 /** Returns the predicted micro PC after the branch */ 474 Addr predMicroPC() { return predPC.microPC(); } 475 476 /** Returns whether the instruction was predicted taken or not. */ 477 bool readPredTaken() 478 { 479 return instFlags[PredTaken]; 480 } 481 482 void setPredTaken(bool predicted_taken) 483 { 484 instFlags[PredTaken] = predicted_taken; 485 } 486 487 /** Returns whether the instruction mispredicted. */ 488 bool mispredicted() 489 { 490 TheISA::PCState tempPC = pc; 491 TheISA::advancePC(tempPC, staticInst); 492 return !(tempPC == predPC); 493 } 494 495 // 496 // Instruction types. Forward checks to StaticInst object. 497 // 498 bool isNop() const { return staticInst->isNop(); } 499 bool isMemRef() const { return staticInst->isMemRef(); } 500 bool isLoad() const { return staticInst->isLoad(); } 501 bool isStore() const { return staticInst->isStore(); } 502 bool isAtomic() const { return staticInst->isAtomic(); } 503 bool isStoreConditional() const 504 { return staticInst->isStoreConditional(); } 505 bool isInstPrefetch() const { return staticInst->isInstPrefetch(); } 506 bool isDataPrefetch() const { return staticInst->isDataPrefetch(); } 507 bool isInteger() const { return staticInst->isInteger(); } 508 bool isFloating() const { return staticInst->isFloating(); } 509 bool isVector() const { return staticInst->isVector(); } 510 bool isControl() const { return staticInst->isControl(); } 511 bool isCall() const { return staticInst->isCall(); } 512 bool isReturn() const { return staticInst->isReturn(); } 513 bool isDirectCtrl() const { return staticInst->isDirectCtrl(); } 514 bool isIndirectCtrl() const { return staticInst->isIndirectCtrl(); } 515 bool isCondCtrl() const { return staticInst->isCondCtrl(); } 516 bool isUncondCtrl() const { return staticInst->isUncondCtrl(); } 517 bool isCondDelaySlot() const { return staticInst->isCondDelaySlot(); } 518 bool isThreadSync() const { return staticInst->isThreadSync(); } 519 bool isSerializing() const { return staticInst->isSerializing(); } 520 bool isSerializeBefore() const 521 { return staticInst->isSerializeBefore() || status[SerializeBefore]; } 522 bool isSerializeAfter() const 523 { return staticInst->isSerializeAfter() || status[SerializeAfter]; } 524 bool isSquashAfter() const { return staticInst->isSquashAfter(); } 525 bool isMemBarrier() const { return staticInst->isMemBarrier(); } 526 bool isWriteBarrier() const { return staticInst->isWriteBarrier(); } 527 bool isNonSpeculative() const { return staticInst->isNonSpeculative(); } 528 bool isQuiesce() const { return staticInst->isQuiesce(); } 529 bool isIprAccess() const { return staticInst->isIprAccess(); } 530 bool isUnverifiable() const { return staticInst->isUnverifiable(); } 531 bool isSyscall() const { return staticInst->isSyscall(); } 532 bool isMacroop() const { return staticInst->isMacroop(); } 533 bool isMicroop() const { return staticInst->isMicroop(); } 534 bool isDelayedCommit() const { return staticInst->isDelayedCommit(); } 535 bool isLastMicroop() const { return staticInst->isLastMicroop(); } 536 bool isFirstMicroop() const { return staticInst->isFirstMicroop(); } 537 bool isMicroBranch() const { return staticInst->isMicroBranch(); } 538 539 /** Temporarily sets this instruction as a serialize before instruction. */ 540 void setSerializeBefore() { status.set(SerializeBefore); } 541 542 /** Clears the serializeBefore part of this instruction. */ 543 void clearSerializeBefore() { status.reset(SerializeBefore); } 544 545 /** Checks if this serializeBefore is only temporarily set. */ 546 bool isTempSerializeBefore() { return status[SerializeBefore]; } 547 548 /** Temporarily sets this instruction as a serialize after instruction. */ 549 void setSerializeAfter() { status.set(SerializeAfter); } 550 551 /** Clears the serializeAfter part of this instruction.*/ 552 void clearSerializeAfter() { status.reset(SerializeAfter); } 553 554 /** Checks if this serializeAfter is only temporarily set. */ 555 bool isTempSerializeAfter() { return status[SerializeAfter]; } 556 557 /** Sets the serialization part of this instruction as handled. */ 558 void setSerializeHandled() { status.set(SerializeHandled); } 559 560 /** Checks if the serialization part of this instruction has been 561 * handled. This does not apply to the temporary serializing 562 * state; it only applies to this instruction's own permanent 563 * serializing state. 564 */ 565 bool isSerializeHandled() { return status[SerializeHandled]; } 566 567 /** Returns the opclass of this instruction. */ 568 OpClass opClass() const { return staticInst->opClass(); } 569 570 /** Returns the branch target address. */ 571 TheISA::PCState branchTarget() const 572 { return staticInst->branchTarget(pc); } 573 574 /** Returns the number of source registers. */ 575 int8_t numSrcRegs() const { return staticInst->numSrcRegs(); } 576 577 /** Returns the number of destination registers. */ 578 int8_t numDestRegs() const { return staticInst->numDestRegs(); } 579 580 // the following are used to track physical register usage 581 // for machines with separate int & FP reg files 582 int8_t numFPDestRegs() const { return staticInst->numFPDestRegs(); } 583 int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); } 584 int8_t numCCDestRegs() const { return staticInst->numCCDestRegs(); } 585 int8_t numVecDestRegs() const { return staticInst->numVecDestRegs(); } 586 int8_t numVecElemDestRegs() const 587 { 588 return staticInst->numVecElemDestRegs(); 589 } 590 int8_t 591 numVecPredDestRegs() const 592 { 593 return staticInst->numVecPredDestRegs(); 594 } 595 596 /** Returns the logical register index of the i'th destination register. */ 597 const RegId& destRegIdx(int i) const { return staticInst->destRegIdx(i); } 598 599 /** Returns the logical register index of the i'th source register. */ 600 const RegId& srcRegIdx(int i) const { return staticInst->srcRegIdx(i); } 601 602 /** Return the size of the instResult queue. */ 603 uint8_t resultSize() { return instResult.size(); } 604 605 /** Pops a result off the instResult queue. 606 * If the result stack is empty, return the default value. 607 * */ 608 InstResult popResult(InstResult dflt = InstResult()) 609 { 610 if (!instResult.empty()) { 611 InstResult t = instResult.front(); 612 instResult.pop(); 613 return t; 614 } 615 return dflt; 616 } 617 618 /** Pushes a result onto the instResult queue. */ 619 /** @{ */ 620 /** Scalar result. */ 621 template<typename T> 622 void setScalarResult(T&& t) 623 { 624 if (instFlags[RecordResult]) { 625 instResult.push(InstResult(std::forward<T>(t), 626 InstResult::ResultType::Scalar)); 627 } 628 } 629 630 /** Full vector result. */ 631 template<typename T> 632 void setVecResult(T&& t) 633 { 634 if (instFlags[RecordResult]) { 635 instResult.push(InstResult(std::forward<T>(t), 636 InstResult::ResultType::VecReg)); 637 } 638 } 639 640 /** Vector element result. */ 641 template<typename T> 642 void setVecElemResult(T&& t) 643 { 644 if (instFlags[RecordResult]) { 645 instResult.push(InstResult(std::forward<T>(t), 646 InstResult::ResultType::VecElem)); 647 } 648 } 649 650 /** Predicate result. */ 651 template<typename T> 652 void setVecPredResult(T&& t) 653 { 654 if (instFlags[RecordResult]) { 655 instResult.push(InstResult(std::forward<T>(t), 656 InstResult::ResultType::VecPredReg)); 657 } 658 } 659 /** @} */ 660 661 /** Records an integer register being set to a value. */ 662 void setIntRegOperand(const StaticInst *si, int idx, RegVal val) 663 { 664 setScalarResult(val); 665 } 666 667 /** Records a CC register being set to a value. */ 668 void setCCRegOperand(const StaticInst *si, int idx, RegVal val) 669 { 670 setScalarResult(val); 671 } 672 673 /** Record a vector register being set to a value */ 674 void setVecRegOperand(const StaticInst *si, int idx, 675 const VecRegContainer& val) 676 { 677 setVecResult(val); 678 } 679 680 /** Records an fp register being set to an integer value. */ 681 void 682 setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) 683 { 684 setScalarResult(val); 685 } 686 687 /** Record a vector register being set to a value */ 688 void setVecElemOperand(const StaticInst *si, int idx, const VecElem val) 689 { 690 setVecElemResult(val); 691 } 692 693 /** Record a vector register being set to a value */ 694 void setVecPredRegOperand(const StaticInst *si, int idx, 695 const VecPredRegContainer& val) 696 { 697 setVecPredResult(val); 698 } 699 700 /** Records that one of the source registers is ready. */ 701 void markSrcRegReady(); 702 703 /** Marks a specific register as ready. */ 704 void markSrcRegReady(RegIndex src_idx); 705 706 /** Returns if a source register is ready. */ 707 bool isReadySrcRegIdx(int idx) const 708 { 709 return this->_readySrcRegIdx[idx]; 710 } 711 712 /** Sets this instruction as completed. */ 713 void setCompleted() { status.set(Completed); } 714 715 /** Returns whether or not this instruction is completed. */ 716 bool isCompleted() const { return status[Completed]; } 717 718 /** Marks the result as ready. */ 719 void setResultReady() { status.set(ResultReady); } 720 721 /** Returns whether or not the result is ready. */ 722 bool isResultReady() const { return status[ResultReady]; } 723 724 /** Sets this instruction as ready to issue. */ 725 void setCanIssue() { status.set(CanIssue); } 726 727 /** Returns whether or not this instruction is ready to issue. */ 728 bool readyToIssue() const { return status[CanIssue]; } 729 730 /** Clears this instruction being able to issue. */ 731 void clearCanIssue() { status.reset(CanIssue); } 732 733 /** Sets this instruction as issued from the IQ. */ 734 void setIssued() { status.set(Issued); } 735 736 /** Returns whether or not this instruction has issued. */ 737 bool isIssued() const { return status[Issued]; } 738 739 /** Clears this instruction as being issued. */ 740 void clearIssued() { status.reset(Issued); } 741 742 /** Sets this instruction as executed. */ 743 void setExecuted() { status.set(Executed); } 744 745 /** Returns whether or not this instruction has executed. */ 746 bool isExecuted() const { return status[Executed]; } 747 748 /** Sets this instruction as ready to commit. */ 749 void setCanCommit() { status.set(CanCommit); } 750 751 /** Clears this instruction as being ready to commit. */ 752 void clearCanCommit() { status.reset(CanCommit); } 753 754 /** Returns whether or not this instruction is ready to commit. */ 755 bool readyToCommit() const { return status[CanCommit]; } 756 757 void setAtCommit() { status.set(AtCommit); } 758 759 bool isAtCommit() { return status[AtCommit]; } 760 761 /** Sets this instruction as committed. */ 762 void setCommitted() { status.set(Committed); } 763 764 /** Returns whether or not this instruction is committed. */ 765 bool isCommitted() const { return status[Committed]; } 766 767 /** Sets this instruction as squashed. */ 768 void setSquashed() { status.set(Squashed); } 769 770 /** Returns whether or not this instruction is squashed. */ 771 bool isSquashed() const { return status[Squashed]; } 772 773 //Instruction Queue Entry 774 //----------------------- 775 /** Sets this instruction as a entry the IQ. */ 776 void setInIQ() { status.set(IqEntry); } 777 778 /** Sets this instruction as a entry the IQ. */ 779 void clearInIQ() { status.reset(IqEntry); } 780 781 /** Returns whether or not this instruction has issued. */ 782 bool isInIQ() const { return status[IqEntry]; } 783 784 /** Sets this instruction as squashed in the IQ. */ 785 void setSquashedInIQ() { status.set(SquashedInIQ); status.set(Squashed);} 786 787 /** Returns whether or not this instruction is squashed in the IQ. */ 788 bool isSquashedInIQ() const { return status[SquashedInIQ]; } 789 790 791 //Load / Store Queue Functions 792 //----------------------- 793 /** Sets this instruction as a entry the LSQ. */ 794 void setInLSQ() { status.set(LsqEntry); } 795 796 /** Sets this instruction as a entry the LSQ. */ 797 void removeInLSQ() { status.reset(LsqEntry); } 798 799 /** Returns whether or not this instruction is in the LSQ. */ 800 bool isInLSQ() const { return status[LsqEntry]; } 801 802 /** Sets this instruction as squashed in the LSQ. */ 803 void setSquashedInLSQ() { status.set(SquashedInLSQ);} 804 805 /** Returns whether or not this instruction is squashed in the LSQ. */ 806 bool isSquashedInLSQ() const { return status[SquashedInLSQ]; } 807 808 809 //Reorder Buffer Functions 810 //----------------------- 811 /** Sets this instruction as a entry the ROB. */ 812 void setInROB() { status.set(RobEntry); } 813 814 /** Sets this instruction as a entry the ROB. */ 815 void clearInROB() { status.reset(RobEntry); } 816 817 /** Returns whether or not this instruction is in the ROB. */ 818 bool isInROB() const { return status[RobEntry]; } 819 820 /** Sets this instruction as squashed in the ROB. */ 821 void setSquashedInROB() { status.set(SquashedInROB); } 822 823 /** Returns whether or not this instruction is squashed in the ROB. */ 824 bool isSquashedInROB() const { return status[SquashedInROB]; } 825 826 /** Read the PC state of this instruction. */ 827 TheISA::PCState pcState() const { return pc; } 828 829 /** Set the PC state of this instruction. */ 830 void pcState(const TheISA::PCState &val) { pc = val; } 831 832 /** Read the PC of this instruction. */ 833 Addr instAddr() const { return pc.instAddr(); } 834 835 /** Read the PC of the next instruction. */ 836 Addr nextInstAddr() const { return pc.nextInstAddr(); } 837 838 /**Read the micro PC of this instruction. */ 839 Addr microPC() const { return pc.microPC(); } 840 841 bool readPredicate() const 842 { 843 return instFlags[Predicate]; 844 } 845 846 void setPredicate(bool val) 847 { 848 instFlags[Predicate] = val; 849 850 if (traceData) { 851 traceData->setPredicate(val); 852 } 853 } 854 855 bool 856 readMemAccPredicate() const 857 { 858 return instFlags[MemAccPredicate]; 859 } 860 861 void 862 setMemAccPredicate(bool val) 863 { 864 instFlags[MemAccPredicate] = val; 865 } 866 867 /** Sets the ASID. */ 868 void setASID(short addr_space_id) { asid = addr_space_id; } 869 short getASID() { return asid; } 870 871 /** Sets the thread id. */ 872 void setTid(ThreadID tid) { threadNumber = tid; } 873 874 /** Sets the pointer to the thread state. */ 875 void setThreadState(ImplState *state) { thread = state; } 876 877 /** Returns the thread context. */ 878 ThreadContext *tcBase() { return thread->getTC(); } 879 880 public: 881 /** Returns whether or not the eff. addr. source registers are ready. */ 882 bool eaSrcsReady() const; 883 884 /** Is this instruction's memory access strictly ordered? */ 885 bool strictlyOrdered() const { return instFlags[IsStrictlyOrdered]; } 886 void strictlyOrdered(bool so) { instFlags[IsStrictlyOrdered] = so; } 887 888 /** Has this instruction generated a memory request. */ 889 bool hasRequest() const { return instFlags[ReqMade]; } 890 /** Assert this instruction has generated a memory request. */ 891 void setRequest() { instFlags[ReqMade] = true; } 892 893 /** Returns iterator to this instruction in the list of all insts. */ 894 ListIt &getInstListIt() { return instListIt; } 895 896 /** Sets iterator for this instruction in the list of all insts. */ 897 void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; } 898 899 public: 900 /** Returns the number of consecutive store conditional failures. */ 901 unsigned int readStCondFailures() const 902 { return thread->storeCondFailures; } 903 904 /** Sets the number of consecutive store conditional failures. */ 905 void setStCondFailures(unsigned int sc_failures) 906 { thread->storeCondFailures = sc_failures; } 907 908 public: 909 // monitor/mwait funtions 910 void armMonitor(Addr address) { cpu->armMonitor(threadNumber, address); } 911 bool mwait(PacketPtr pkt) { return cpu->mwait(threadNumber, pkt); } 912 void mwaitAtomic(ThreadContext *tc) 913 { return cpu->mwaitAtomic(threadNumber, tc, cpu->dtb); } 914 AddressMonitor *getAddrMonitor() 915 { return cpu->getCpuAddrMonitor(threadNumber); } 916}; 917 918template<class Impl> 919Fault 920BaseDynInst<Impl>::initiateMemRead(Addr addr, unsigned size, 921 Request::Flags flags) 922{ 923 return cpu->pushRequest( 924 dynamic_cast<typename DynInstPtr::PtrType>(this), 925 /* ld */ true, nullptr, size, addr, flags, nullptr); 926} 927 928template<class Impl> 929Fault 930BaseDynInst<Impl>::writeMem(uint8_t *data, unsigned size, Addr addr, 931 Request::Flags flags, uint64_t *res) 932{ 933 return cpu->pushRequest( 934 dynamic_cast<typename DynInstPtr::PtrType>(this), 935 /* st */ false, data, size, addr, flags, res); 936} 937 938template<class Impl> 939Fault 940BaseDynInst<Impl>::initiateMemAMO(Addr addr, unsigned size, 941 Request::Flags flags, 942 AtomicOpFunctor *amo_op) 943{ 944 // atomic memory instructions do not have data to be written to memory yet 945 // since the atomic operations will be executed directly in cache/memory. 946 // Therefore, its `data` field is nullptr. 947 // Atomic memory requests need to carry their `amo_op` fields to cache/ 948 // memory 949 return cpu->pushRequest( 950 dynamic_cast<typename DynInstPtr::PtrType>(this), 951 /* atomic */ false, nullptr, size, addr, flags, nullptr, amo_op); 952} 953 954#endif // __CPU_BASE_DYN_INST_HH__ 955