base_dyn_inst.hh revision 6429
1/* 2 * Copyright (c) 2004-2006 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Kevin Lim 29 */ 30 31#ifndef __CPU_BASE_DYN_INST_HH__ 32#define __CPU_BASE_DYN_INST_HH__ 33 34#include <bitset> 35#include <list> 36#include <string> 37 38#include "arch/faults.hh" 39#include "base/fast_alloc.hh" 40#include "base/trace.hh" 41#include "config/full_system.hh" 42#include "cpu/o3/comm.hh" 43#include "cpu/exetrace.hh" 44#include "cpu/inst_seq.hh" 45#include "cpu/op_class.hh" 46#include "cpu/static_inst.hh" 47#include "mem/packet.hh" 48#include "sim/system.hh" 49#include "sim/tlb.hh" 50 51/** 52 * @file 53 * Defines a dynamic instruction context. 54 */ 55 56// Forward declaration. 57class StaticInstPtr; 58 59template <class Impl> 60class BaseDynInst : public FastAlloc, public RefCounted 61{ 62 public: 63 // Typedef for the CPU. 64 typedef typename Impl::CPUType ImplCPU; 65 typedef typename ImplCPU::ImplState ImplState; 66 67 // Logical register index type. 68 typedef TheISA::RegIndex RegIndex; 69 // Integer register type. 70 typedef TheISA::IntReg IntReg; 71 // Floating point register type. 72 typedef TheISA::FloatReg FloatReg; 73 74 // The DynInstPtr type. 75 typedef typename Impl::DynInstPtr DynInstPtr; 76 77 // The list of instructions iterator type. 78 typedef typename std::list<DynInstPtr>::iterator ListIt; 79 80 enum { 81 MaxInstSrcRegs = TheISA::MaxInstSrcRegs, /// Max source regs 82 MaxInstDestRegs = TheISA::MaxInstDestRegs, /// Max dest regs 83 }; 84 85 /** The StaticInst used by this BaseDynInst. */ 86 StaticInstPtr staticInst; 87 88 //////////////////////////////////////////// 89 // 90 // INSTRUCTION EXECUTION 91 // 92 //////////////////////////////////////////// 93 /** InstRecord that tracks this instructions. */ 94 Trace::InstRecord *traceData; 95 96 void demapPage(Addr vaddr, uint64_t asn) 97 { 98 cpu->demapPage(vaddr, asn); 99 } 100 void demapInstPage(Addr vaddr, uint64_t asn) 101 { 102 cpu->demapPage(vaddr, asn); 103 } 104 void demapDataPage(Addr vaddr, uint64_t asn) 105 { 106 cpu->demapPage(vaddr, asn); 107 } 108 109 /** 110 * Does a read to a given address. 111 * @param addr The address to read. 112 * @param data The read's data is written into this parameter. 113 * @param flags The request's flags. 114 * @return Returns any fault due to the read. 115 */ 116 template <class T> 117 Fault read(Addr addr, T &data, unsigned flags); 118 119 /** 120 * Does a write to a given address. 121 * @param data The data to be written. 122 * @param addr The address to write to. 123 * @param flags The request's flags. 124 * @param res The result of the write (for load locked/store conditionals). 125 * @return Returns any fault due to the write. 126 */ 127 template <class T> 128 Fault write(T data, Addr addr, unsigned flags, 129 uint64_t *res); 130 131 void prefetch(Addr addr, unsigned flags); 132 void writeHint(Addr addr, int size, unsigned flags); 133 Fault copySrcTranslate(Addr src); 134 Fault copy(Addr dest); 135 136 /** @todo: Consider making this private. */ 137 public: 138 /** The sequence number of the instruction. */ 139 InstSeqNum seqNum; 140 141 enum Status { 142 IqEntry, /// Instruction is in the IQ 143 RobEntry, /// Instruction is in the ROB 144 LsqEntry, /// Instruction is in the LSQ 145 Completed, /// Instruction has completed 146 ResultReady, /// Instruction has its result 147 CanIssue, /// Instruction can issue and execute 148 Issued, /// Instruction has issued 149 Executed, /// Instruction has executed 150 CanCommit, /// Instruction can commit 151 AtCommit, /// Instruction has reached commit 152 Committed, /// Instruction has committed 153 Squashed, /// Instruction is squashed 154 SquashedInIQ, /// Instruction is squashed in the IQ 155 SquashedInLSQ, /// Instruction is squashed in the LSQ 156 SquashedInROB, /// Instruction is squashed in the ROB 157 RecoverInst, /// Is a recover instruction 158 BlockingInst, /// Is a blocking instruction 159 ThreadsyncWait, /// Is a thread synchronization instruction 160 SerializeBefore, /// Needs to serialize on 161 /// instructions ahead of it 162 SerializeAfter, /// Needs to serialize instructions behind it 163 SerializeHandled, /// Serialization has been handled 164 NumStatus 165 }; 166 167 /** The status of this BaseDynInst. Several bits can be set. */ 168 std::bitset<NumStatus> status; 169 170 /** The thread this instruction is from. */ 171 ThreadID threadNumber; 172 173 /** data address space ID, for loads & stores. */ 174 short asid; 175 176 /** How many source registers are ready. */ 177 unsigned readyRegs; 178 179 /** Pointer to the Impl's CPU object. */ 180 ImplCPU *cpu; 181 182 /** Pointer to the thread state. */ 183 ImplState *thread; 184 185 /** The kind of fault this instruction has generated. */ 186 Fault fault; 187 188 /** Pointer to the data for the memory access. */ 189 uint8_t *memData; 190 191 /** The effective virtual address (lds & stores only). */ 192 Addr effAddr; 193 194 /** Is the effective virtual address valid. */ 195 bool effAddrValid; 196 197 /** The effective physical address. */ 198 Addr physEffAddr; 199 200 /** Effective virtual address for a copy source. */ 201 Addr copySrcEffAddr; 202 203 /** Effective physical address for a copy source. */ 204 Addr copySrcPhysEffAddr; 205 206 /** The memory request flags (from translation). */ 207 unsigned memReqFlags; 208 209 union Result { 210 uint64_t integer; 211// float fp; 212 double dbl; 213 }; 214 215 /** The result of the instruction; assumes for now that there's only one 216 * destination register. 217 */ 218 Result instResult; 219 220 /** Records changes to result? */ 221 bool recordResult; 222 223 /** PC of this instruction. */ 224 Addr PC; 225 226 /** Micro PC of this instruction. */ 227 Addr microPC; 228 229 protected: 230 /** Next non-speculative PC. It is not filled in at fetch, but rather 231 * once the target of the branch is truly known (either decode or 232 * execute). 233 */ 234 Addr nextPC; 235 236 /** Next non-speculative NPC. Target PC for Mips or Sparc. */ 237 Addr nextNPC; 238 239 /** Next non-speculative micro PC. */ 240 Addr nextMicroPC; 241 242 /** Predicted next PC. */ 243 Addr predPC; 244 245 /** Predicted next NPC. */ 246 Addr predNPC; 247 248 /** Predicted next microPC */ 249 Addr predMicroPC; 250 251 /** If this is a branch that was predicted taken */ 252 bool predTaken; 253 254 public: 255 256#ifdef DEBUG 257 void dumpSNList(); 258#endif 259 260 /** Whether or not the source register is ready. 261 * @todo: Not sure this should be here vs the derived class. 262 */ 263 bool _readySrcRegIdx[MaxInstSrcRegs]; 264 265 protected: 266 /** Flattened register index of the destination registers of this 267 * instruction. 268 */ 269 TheISA::RegIndex _flatDestRegIdx[TheISA::MaxInstDestRegs]; 270 271 /** Flattened register index of the source registers of this 272 * instruction. 273 */ 274 TheISA::RegIndex _flatSrcRegIdx[TheISA::MaxInstSrcRegs]; 275 276 /** Physical register index of the destination registers of this 277 * instruction. 278 */ 279 PhysRegIndex _destRegIdx[TheISA::MaxInstDestRegs]; 280 281 /** Physical register index of the source registers of this 282 * instruction. 283 */ 284 PhysRegIndex _srcRegIdx[TheISA::MaxInstSrcRegs]; 285 286 /** Physical register index of the previous producers of the 287 * architected destinations. 288 */ 289 PhysRegIndex _prevDestRegIdx[TheISA::MaxInstDestRegs]; 290 291 public: 292 293 /** Returns the physical register index of the i'th destination 294 * register. 295 */ 296 PhysRegIndex renamedDestRegIdx(int idx) const 297 { 298 return _destRegIdx[idx]; 299 } 300 301 /** Returns the physical register index of the i'th source register. */ 302 PhysRegIndex renamedSrcRegIdx(int idx) const 303 { 304 return _srcRegIdx[idx]; 305 } 306 307 /** Returns the flattened register index of the i'th destination 308 * register. 309 */ 310 TheISA::RegIndex flattenedDestRegIdx(int idx) const 311 { 312 return _flatDestRegIdx[idx]; 313 } 314 315 /** Returns the flattened register index of the i'th source register */ 316 TheISA::RegIndex flattenedSrcRegIdx(int idx) const 317 { 318 return _flatSrcRegIdx[idx]; 319 } 320 321 /** Returns the physical register index of the previous physical register 322 * that remapped to the same logical register index. 323 */ 324 PhysRegIndex prevDestRegIdx(int idx) const 325 { 326 return _prevDestRegIdx[idx]; 327 } 328 329 /** Renames a destination register to a physical register. Also records 330 * the previous physical register that the logical register mapped to. 331 */ 332 void renameDestReg(int idx, 333 PhysRegIndex renamed_dest, 334 PhysRegIndex previous_rename) 335 { 336 _destRegIdx[idx] = renamed_dest; 337 _prevDestRegIdx[idx] = previous_rename; 338 } 339 340 /** Renames a source logical register to the physical register which 341 * has/will produce that logical register's result. 342 * @todo: add in whether or not the source register is ready. 343 */ 344 void renameSrcReg(int idx, PhysRegIndex renamed_src) 345 { 346 _srcRegIdx[idx] = renamed_src; 347 } 348 349 /** Flattens a source architectural register index into a logical index. 350 */ 351 void flattenSrcReg(int idx, TheISA::RegIndex flattened_src) 352 { 353 _flatSrcRegIdx[idx] = flattened_src; 354 } 355 356 /** Flattens a destination architectural register index into a logical 357 * index. 358 */ 359 void flattenDestReg(int idx, TheISA::RegIndex flattened_dest) 360 { 361 _flatDestRegIdx[idx] = flattened_dest; 362 } 363 /** BaseDynInst constructor given a binary instruction. 364 * @param staticInst A StaticInstPtr to the underlying instruction. 365 * @param PC The PC of the instruction. 366 * @param pred_PC The predicted next PC. 367 * @param pred_NPC The predicted next NPC. 368 * @param seq_num The sequence number of the instruction. 369 * @param cpu Pointer to the instruction's CPU. 370 */ 371 BaseDynInst(StaticInstPtr staticInst, Addr PC, Addr NPC, Addr microPC, 372 Addr pred_PC, Addr pred_NPC, Addr pred_MicroPC, 373 InstSeqNum seq_num, ImplCPU *cpu); 374 375 /** BaseDynInst constructor given a binary instruction. 376 * @param inst The binary instruction. 377 * @param PC The PC of the instruction. 378 * @param pred_PC The predicted next PC. 379 * @param pred_NPC The predicted next NPC. 380 * @param seq_num The sequence number of the instruction. 381 * @param cpu Pointer to the instruction's CPU. 382 */ 383 BaseDynInst(TheISA::ExtMachInst inst, Addr PC, Addr NPC, Addr microPC, 384 Addr pred_PC, Addr pred_NPC, Addr pred_MicroPC, 385 InstSeqNum seq_num, ImplCPU *cpu); 386 387 /** BaseDynInst constructor given a StaticInst pointer. 388 * @param _staticInst The StaticInst for this BaseDynInst. 389 */ 390 BaseDynInst(StaticInstPtr &_staticInst); 391 392 /** BaseDynInst destructor. */ 393 ~BaseDynInst(); 394 395 private: 396 /** Function to initialize variables in the constructors. */ 397 void initVars(); 398 399 public: 400 /** Dumps out contents of this BaseDynInst. */ 401 void dump(); 402 403 /** Dumps out contents of this BaseDynInst into given string. */ 404 void dump(std::string &outstring); 405 406 /** Read this CPU's ID. */ 407 int cpuId() { return cpu->cpuId(); } 408 409 /** Read this context's system-wide ID **/ 410 int contextId() { return thread->contextId(); } 411 412 /** Returns the fault type. */ 413 Fault getFault() { return fault; } 414 415 /** Checks whether or not this instruction has had its branch target 416 * calculated yet. For now it is not utilized and is hacked to be 417 * always false. 418 * @todo: Actually use this instruction. 419 */ 420 bool doneTargCalc() { return false; } 421 422 /** Returns the next PC. This could be the speculative next PC if it is 423 * called prior to the actual branch target being calculated. 424 */ 425 Addr readNextPC() { return nextPC; } 426 427 /** Returns the next NPC. This could be the speculative next NPC if it is 428 * called prior to the actual branch target being calculated. 429 */ 430 Addr readNextNPC() 431 { 432#if ISA_HAS_DELAY_SLOT 433 return nextNPC; 434#else 435 return nextPC + sizeof(TheISA::MachInst); 436#endif 437 } 438 439 Addr readNextMicroPC() 440 { 441 return nextMicroPC; 442 } 443 444 /** Set the predicted target of this current instruction. */ 445 void setPredTarg(Addr predicted_PC, Addr predicted_NPC, 446 Addr predicted_MicroPC) 447 { 448 predPC = predicted_PC; 449 predNPC = predicted_NPC; 450 predMicroPC = predicted_MicroPC; 451 } 452 453 /** Returns the predicted PC immediately after the branch. */ 454 Addr readPredPC() { return predPC; } 455 456 /** Returns the predicted PC two instructions after the branch */ 457 Addr readPredNPC() { return predNPC; } 458 459 /** Returns the predicted micro PC after the branch */ 460 Addr readPredMicroPC() { return predMicroPC; } 461 462 /** Returns whether the instruction was predicted taken or not. */ 463 bool readPredTaken() 464 { 465 return predTaken; 466 } 467 468 void setPredTaken(bool predicted_taken) 469 { 470 predTaken = predicted_taken; 471 } 472 473 /** Returns whether the instruction mispredicted. */ 474 bool mispredicted() 475 { 476 return readPredPC() != readNextPC() || 477 readPredNPC() != readNextNPC() || 478 readPredMicroPC() != readNextMicroPC(); 479 } 480 481 // 482 // Instruction types. Forward checks to StaticInst object. 483 // 484 bool isNop() const { return staticInst->isNop(); } 485 bool isMemRef() const { return staticInst->isMemRef(); } 486 bool isLoad() const { return staticInst->isLoad(); } 487 bool isStore() const { return staticInst->isStore(); } 488 bool isStoreConditional() const 489 { return staticInst->isStoreConditional(); } 490 bool isInstPrefetch() const { return staticInst->isInstPrefetch(); } 491 bool isDataPrefetch() const { return staticInst->isDataPrefetch(); } 492 bool isCopy() const { return staticInst->isCopy(); } 493 bool isInteger() const { return staticInst->isInteger(); } 494 bool isFloating() const { return staticInst->isFloating(); } 495 bool isControl() const { return staticInst->isControl(); } 496 bool isCall() const { return staticInst->isCall(); } 497 bool isReturn() const { return staticInst->isReturn(); } 498 bool isDirectCtrl() const { return staticInst->isDirectCtrl(); } 499 bool isIndirectCtrl() const { return staticInst->isIndirectCtrl(); } 500 bool isCondCtrl() const { return staticInst->isCondCtrl(); } 501 bool isUncondCtrl() const { return staticInst->isUncondCtrl(); } 502 bool isCondDelaySlot() const { return staticInst->isCondDelaySlot(); } 503 bool isThreadSync() const { return staticInst->isThreadSync(); } 504 bool isSerializing() const { return staticInst->isSerializing(); } 505 bool isSerializeBefore() const 506 { return staticInst->isSerializeBefore() || status[SerializeBefore]; } 507 bool isSerializeAfter() const 508 { return staticInst->isSerializeAfter() || status[SerializeAfter]; } 509 bool isMemBarrier() const { return staticInst->isMemBarrier(); } 510 bool isWriteBarrier() const { return staticInst->isWriteBarrier(); } 511 bool isNonSpeculative() const { return staticInst->isNonSpeculative(); } 512 bool isQuiesce() const { return staticInst->isQuiesce(); } 513 bool isIprAccess() const { return staticInst->isIprAccess(); } 514 bool isUnverifiable() const { return staticInst->isUnverifiable(); } 515 bool isSyscall() const { return staticInst->isSyscall(); } 516 bool isMacroop() const { return staticInst->isMacroop(); } 517 bool isMicroop() const { return staticInst->isMicroop(); } 518 bool isDelayedCommit() const { return staticInst->isDelayedCommit(); } 519 bool isLastMicroop() const { return staticInst->isLastMicroop(); } 520 bool isFirstMicroop() const { return staticInst->isFirstMicroop(); } 521 bool isMicroBranch() const { return staticInst->isMicroBranch(); } 522 523 /** Temporarily sets this instruction as a serialize before instruction. */ 524 void setSerializeBefore() { status.set(SerializeBefore); } 525 526 /** Clears the serializeBefore part of this instruction. */ 527 void clearSerializeBefore() { status.reset(SerializeBefore); } 528 529 /** Checks if this serializeBefore is only temporarily set. */ 530 bool isTempSerializeBefore() { return status[SerializeBefore]; } 531 532 /** Temporarily sets this instruction as a serialize after instruction. */ 533 void setSerializeAfter() { status.set(SerializeAfter); } 534 535 /** Clears the serializeAfter part of this instruction.*/ 536 void clearSerializeAfter() { status.reset(SerializeAfter); } 537 538 /** Checks if this serializeAfter is only temporarily set. */ 539 bool isTempSerializeAfter() { return status[SerializeAfter]; } 540 541 /** Sets the serialization part of this instruction as handled. */ 542 void setSerializeHandled() { status.set(SerializeHandled); } 543 544 /** Checks if the serialization part of this instruction has been 545 * handled. This does not apply to the temporary serializing 546 * state; it only applies to this instruction's own permanent 547 * serializing state. 548 */ 549 bool isSerializeHandled() { return status[SerializeHandled]; } 550 551 /** Returns the opclass of this instruction. */ 552 OpClass opClass() const { return staticInst->opClass(); } 553 554 /** Returns the branch target address. */ 555 Addr branchTarget() const { return staticInst->branchTarget(PC); } 556 557 /** Returns the number of source registers. */ 558 int8_t numSrcRegs() const { return staticInst->numSrcRegs(); } 559 560 /** Returns the number of destination registers. */ 561 int8_t numDestRegs() const { return staticInst->numDestRegs(); } 562 563 // the following are used to track physical register usage 564 // for machines with separate int & FP reg files 565 int8_t numFPDestRegs() const { return staticInst->numFPDestRegs(); } 566 int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); } 567 568 /** Returns the logical register index of the i'th destination register. */ 569 RegIndex destRegIdx(int i) const { return staticInst->destRegIdx(i); } 570 571 /** Returns the logical register index of the i'th source register. */ 572 RegIndex srcRegIdx(int i) const { return staticInst->srcRegIdx(i); } 573 574 /** Returns the result of an integer instruction. */ 575 uint64_t readIntResult() { return instResult.integer; } 576 577 /** Returns the result of a floating point instruction. */ 578 float readFloatResult() { return (float)instResult.dbl; } 579 580 /** Returns the result of a floating point (double) instruction. */ 581 double readDoubleResult() { return instResult.dbl; } 582 583 /** Records an integer register being set to a value. */ 584 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) 585 { 586 if (recordResult) 587 instResult.integer = val; 588 } 589 590 /** Records an fp register being set to a value. */ 591 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, 592 int width) 593 { 594 if (recordResult) { 595 if (width == 32) 596 instResult.dbl = (double)val; 597 else if (width == 64) 598 instResult.dbl = val; 599 else 600 panic("Unsupported width!"); 601 } 602 } 603 604 /** Records an fp register being set to a value. */ 605 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) 606 { 607 if (recordResult) 608 instResult.dbl = (double)val; 609 } 610 611 /** Records an fp register being set to an integer value. */ 612 void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val, 613 int width) 614 { 615 if (recordResult) 616 instResult.integer = val; 617 } 618 619 /** Records an fp register being set to an integer value. */ 620 void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val) 621 { 622 if (recordResult) 623 instResult.integer = val; 624 } 625 626 /** Records that one of the source registers is ready. */ 627 void markSrcRegReady(); 628 629 /** Marks a specific register as ready. */ 630 void markSrcRegReady(RegIndex src_idx); 631 632 /** Returns if a source register is ready. */ 633 bool isReadySrcRegIdx(int idx) const 634 { 635 return this->_readySrcRegIdx[idx]; 636 } 637 638 /** Sets this instruction as completed. */ 639 void setCompleted() { status.set(Completed); } 640 641 /** Returns whether or not this instruction is completed. */ 642 bool isCompleted() const { return status[Completed]; } 643 644 /** Marks the result as ready. */ 645 void setResultReady() { status.set(ResultReady); } 646 647 /** Returns whether or not the result is ready. */ 648 bool isResultReady() const { return status[ResultReady]; } 649 650 /** Sets this instruction as ready to issue. */ 651 void setCanIssue() { status.set(CanIssue); } 652 653 /** Returns whether or not this instruction is ready to issue. */ 654 bool readyToIssue() const { return status[CanIssue]; } 655 656 /** Clears this instruction being able to issue. */ 657 void clearCanIssue() { status.reset(CanIssue); } 658 659 /** Sets this instruction as issued from the IQ. */ 660 void setIssued() { status.set(Issued); } 661 662 /** Returns whether or not this instruction has issued. */ 663 bool isIssued() const { return status[Issued]; } 664 665 /** Clears this instruction as being issued. */ 666 void clearIssued() { status.reset(Issued); } 667 668 /** Sets this instruction as executed. */ 669 void setExecuted() { status.set(Executed); } 670 671 /** Returns whether or not this instruction has executed. */ 672 bool isExecuted() const { return status[Executed]; } 673 674 /** Sets this instruction as ready to commit. */ 675 void setCanCommit() { status.set(CanCommit); } 676 677 /** Clears this instruction as being ready to commit. */ 678 void clearCanCommit() { status.reset(CanCommit); } 679 680 /** Returns whether or not this instruction is ready to commit. */ 681 bool readyToCommit() const { return status[CanCommit]; } 682 683 void setAtCommit() { status.set(AtCommit); } 684 685 bool isAtCommit() { return status[AtCommit]; } 686 687 /** Sets this instruction as committed. */ 688 void setCommitted() { status.set(Committed); } 689 690 /** Returns whether or not this instruction is committed. */ 691 bool isCommitted() const { return status[Committed]; } 692 693 /** Sets this instruction as squashed. */ 694 void setSquashed() { status.set(Squashed); } 695 696 /** Returns whether or not this instruction is squashed. */ 697 bool isSquashed() const { return status[Squashed]; } 698 699 //Instruction Queue Entry 700 //----------------------- 701 /** Sets this instruction as a entry the IQ. */ 702 void setInIQ() { status.set(IqEntry); } 703 704 /** Sets this instruction as a entry the IQ. */ 705 void clearInIQ() { status.reset(IqEntry); } 706 707 /** Returns whether or not this instruction has issued. */ 708 bool isInIQ() const { return status[IqEntry]; } 709 710 /** Sets this instruction as squashed in the IQ. */ 711 void setSquashedInIQ() { status.set(SquashedInIQ); status.set(Squashed);} 712 713 /** Returns whether or not this instruction is squashed in the IQ. */ 714 bool isSquashedInIQ() const { return status[SquashedInIQ]; } 715 716 717 //Load / Store Queue Functions 718 //----------------------- 719 /** Sets this instruction as a entry the LSQ. */ 720 void setInLSQ() { status.set(LsqEntry); } 721 722 /** Sets this instruction as a entry the LSQ. */ 723 void removeInLSQ() { status.reset(LsqEntry); } 724 725 /** Returns whether or not this instruction is in the LSQ. */ 726 bool isInLSQ() const { return status[LsqEntry]; } 727 728 /** Sets this instruction as squashed in the LSQ. */ 729 void setSquashedInLSQ() { status.set(SquashedInLSQ);} 730 731 /** Returns whether or not this instruction is squashed in the LSQ. */ 732 bool isSquashedInLSQ() const { return status[SquashedInLSQ]; } 733 734 735 //Reorder Buffer Functions 736 //----------------------- 737 /** Sets this instruction as a entry the ROB. */ 738 void setInROB() { status.set(RobEntry); } 739 740 /** Sets this instruction as a entry the ROB. */ 741 void clearInROB() { status.reset(RobEntry); } 742 743 /** Returns whether or not this instruction is in the ROB. */ 744 bool isInROB() const { return status[RobEntry]; } 745 746 /** Sets this instruction as squashed in the ROB. */ 747 void setSquashedInROB() { status.set(SquashedInROB); } 748 749 /** Returns whether or not this instruction is squashed in the ROB. */ 750 bool isSquashedInROB() const { return status[SquashedInROB]; } 751 752 /** Read the PC of this instruction. */ 753 const Addr readPC() const { return PC; } 754 755 /**Read the micro PC of this instruction. */ 756 const Addr readMicroPC() const { return microPC; } 757 758 /** Set the next PC of this instruction (its actual target). */ 759 void setNextPC(Addr val) 760 { 761 nextPC = val; 762 } 763 764 /** Set the next NPC of this instruction (the target in Mips or Sparc).*/ 765 void setNextNPC(Addr val) 766 { 767#if ISA_HAS_DELAY_SLOT 768 nextNPC = val; 769#endif 770 } 771 772 void setNextMicroPC(Addr val) 773 { 774 nextMicroPC = val; 775 } 776 777 /** Sets the ASID. */ 778 void setASID(short addr_space_id) { asid = addr_space_id; } 779 780 /** Sets the thread id. */ 781 void setTid(ThreadID tid) { threadNumber = tid; } 782 783 /** Sets the pointer to the thread state. */ 784 void setThreadState(ImplState *state) { thread = state; } 785 786 /** Returns the thread context. */ 787 ThreadContext *tcBase() { return thread->getTC(); } 788 789 private: 790 /** Instruction effective address. 791 * @todo: Consider if this is necessary or not. 792 */ 793 Addr instEffAddr; 794 795 /** Whether or not the effective address calculation is completed. 796 * @todo: Consider if this is necessary or not. 797 */ 798 bool eaCalcDone; 799 800 /** Is this instruction's memory access uncacheable. */ 801 bool isUncacheable; 802 803 /** Has this instruction generated a memory request. */ 804 bool reqMade; 805 806 public: 807 /** Sets the effective address. */ 808 void setEA(Addr &ea) { instEffAddr = ea; eaCalcDone = true; } 809 810 /** Returns the effective address. */ 811 const Addr &getEA() const { return instEffAddr; } 812 813 /** Returns whether or not the eff. addr. calculation has been completed. */ 814 bool doneEACalc() { return eaCalcDone; } 815 816 /** Returns whether or not the eff. addr. source registers are ready. */ 817 bool eaSrcsReady(); 818 819 /** Whether or not the memory operation is done. */ 820 bool memOpDone; 821 822 /** Is this instruction's memory access uncacheable. */ 823 bool uncacheable() { return isUncacheable; } 824 825 /** Has this instruction generated a memory request. */ 826 bool hasRequest() { return reqMade; } 827 828 public: 829 /** Load queue index. */ 830 int16_t lqIdx; 831 832 /** Store queue index. */ 833 int16_t sqIdx; 834 835 /** Iterator pointing to this BaseDynInst in the list of all insts. */ 836 ListIt instListIt; 837 838 /** Returns iterator to this instruction in the list of all insts. */ 839 ListIt &getInstListIt() { return instListIt; } 840 841 /** Sets iterator for this instruction in the list of all insts. */ 842 void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; } 843 844 public: 845 /** Returns the number of consecutive store conditional failures. */ 846 unsigned readStCondFailures() 847 { return thread->storeCondFailures; } 848 849 /** Sets the number of consecutive store conditional failures. */ 850 void setStCondFailures(unsigned sc_failures) 851 { thread->storeCondFailures = sc_failures; } 852}; 853 854template<class Impl> 855template<class T> 856inline Fault 857BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags) 858{ 859 reqMade = true; 860 Request *req = new Request(asid, addr, sizeof(T), flags, this->PC, 861 thread->contextId(), threadNumber); 862 863 fault = cpu->dtb->translateAtomic(req, thread->getTC(), BaseTLB::Read); 864 865 if (req->isUncacheable()) 866 isUncacheable = true; 867 868 if (fault == NoFault) { 869 effAddr = req->getVaddr(); 870 effAddrValid = true; 871 physEffAddr = req->getPaddr(); 872 memReqFlags = req->getFlags(); 873 874#if 0 875 if (cpu->system->memctrl->badaddr(physEffAddr)) { 876 fault = TheISA::genMachineCheckFault(); 877 data = (T)-1; 878 this->setExecuted(); 879 } else { 880 fault = cpu->read(req, data, lqIdx); 881 } 882#else 883 fault = cpu->read(req, data, lqIdx); 884#endif 885 } else { 886 // Return a fixed value to keep simulation deterministic even 887 // along misspeculated paths. 888 data = (T)-1; 889 890 // Commit will have to clean up whatever happened. Set this 891 // instruction as executed. 892 this->setExecuted(); 893 delete req; 894 } 895 896 if (traceData) { 897 traceData->setAddr(addr); 898 traceData->setData(data); 899 } 900 901 return fault; 902} 903 904template<class Impl> 905template<class T> 906inline Fault 907BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res) 908{ 909 if (traceData) { 910 traceData->setAddr(addr); 911 traceData->setData(data); 912 } 913 914 reqMade = true; 915 Request *req = new Request(asid, addr, sizeof(T), flags, this->PC, 916 thread->contextId(), threadNumber); 917 918 fault = cpu->dtb->translateAtomic(req, thread->getTC(), BaseTLB::Write); 919 920 if (req->isUncacheable()) 921 isUncacheable = true; 922 923 if (fault == NoFault) { 924 effAddr = req->getVaddr(); 925 effAddrValid = true; 926 physEffAddr = req->getPaddr(); 927 memReqFlags = req->getFlags(); 928 929 if (req->isCondSwap()) { 930 assert(res); 931 req->setExtraData(*res); 932 } 933#if 0 934 if (cpu->system->memctrl->badaddr(physEffAddr)) { 935 fault = TheISA::genMachineCheckFault(); 936 } else { 937 fault = cpu->write(req, data, sqIdx); 938 } 939#else 940 fault = cpu->write(req, data, sqIdx); 941#endif 942 } else { 943 delete req; 944 } 945 946 return fault; 947} 948 949#endif // __CPU_BASE_DYN_INST_HH__ 950