base_dyn_inst.hh revision 2678
1/* 2 * Copyright (c) 2004-2005 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 <list> 35#include <string> 36 37#include "arch/faults.hh" 38#include "base/fast_alloc.hh" 39#include "base/trace.hh" 40#include "config/full_system.hh" 41#include "cpu/exetrace.hh" 42#include "cpu/inst_seq.hh" 43#include "cpu/op_class.hh" 44#include "cpu/static_inst.hh" 45#include "mem/packet.hh" 46#include "sim/system.hh" 47/* 48#include "encumbered/cpu/full/bpred_update.hh" 49#include "encumbered/cpu/full/spec_memory.hh" 50#include "encumbered/cpu/full/spec_state.hh" 51#include "encumbered/mem/functional/main.hh" 52*/ 53 54/** 55 * @file 56 * Defines a dynamic instruction context. 57 */ 58 59// Forward declaration. 60class StaticInstPtr; 61 62template <class Impl> 63class BaseDynInst : public FastAlloc, public RefCounted 64{ 65 public: 66 // Typedef for the CPU. 67 typedef typename Impl::FullCPU FullCPU; 68 typedef typename FullCPU::ImplState ImplState; 69 70 // Binary machine instruction type. 71 typedef TheISA::MachInst MachInst; 72 // Extended machine instruction type 73 typedef TheISA::ExtMachInst ExtMachInst; 74 // Logical register index type. 75 typedef TheISA::RegIndex RegIndex; 76 // Integer register index type. 77 typedef TheISA::IntReg IntReg; 78 79 // The DynInstPtr type. 80 typedef typename Impl::DynInstPtr DynInstPtr; 81 82 // The list of instructions iterator type. 83 typedef typename std::list<DynInstPtr>::iterator ListIt; 84 85 enum { 86 MaxInstSrcRegs = TheISA::MaxInstSrcRegs, /// Max source regs 87 MaxInstDestRegs = TheISA::MaxInstDestRegs, /// Max dest regs 88 }; 89 90 /** The StaticInst used by this BaseDynInst. */ 91 StaticInstPtr staticInst; 92 93 //////////////////////////////////////////// 94 // 95 // INSTRUCTION EXECUTION 96 // 97 //////////////////////////////////////////// 98 /** InstRecord that tracks this instructions. */ 99 Trace::InstRecord *traceData; 100 101 /** 102 * Does a read to a given address. 103 * @param addr The address to read. 104 * @param data The read's data is written into this parameter. 105 * @param flags The request's flags. 106 * @return Returns any fault due to the read. 107 */ 108 template <class T> 109 Fault read(Addr addr, T &data, unsigned flags); 110 111 /** 112 * Does a write to a given address. 113 * @param data The data to be written. 114 * @param addr The address to write to. 115 * @param flags The request's flags. 116 * @param res The result of the write (for load locked/store conditionals). 117 * @return Returns any fault due to the write. 118 */ 119 template <class T> 120 Fault write(T data, Addr addr, unsigned flags, 121 uint64_t *res); 122 123 void prefetch(Addr addr, unsigned flags); 124 void writeHint(Addr addr, int size, unsigned flags); 125 Fault copySrcTranslate(Addr src); 126 Fault copy(Addr dest); 127 128 /** @todo: Consider making this private. */ 129 public: 130 /** The sequence number of the instruction. */ 131 InstSeqNum seqNum; 132 133 /** Is the instruction in the IQ */ 134 bool iqEntry; 135 136 /** Is the instruction in the ROB */ 137 bool robEntry; 138 139 /** Is the instruction in the LSQ */ 140 bool lsqEntry; 141 142 /** Is the instruction completed. */ 143 bool completed; 144 145 /** Is the instruction's result ready. */ 146 bool resultReady; 147 148 /** Can this instruction issue. */ 149 bool canIssue; 150 151 /** Has this instruction issued. */ 152 bool issued; 153 154 /** Has this instruction executed (or made it through execute) yet. */ 155 bool executed; 156 157 /** Can this instruction commit. */ 158 bool canCommit; 159 160 /** Is this instruction committed. */ 161 bool committed; 162 163 /** Is this instruction squashed. */ 164 bool squashed; 165 166 /** Is this instruction squashed in the instruction queue. */ 167 bool squashedInIQ; 168 169 /** Is this instruction squashed in the instruction queue. */ 170 bool squashedInLSQ; 171 172 /** Is this instruction squashed in the instruction queue. */ 173 bool squashedInROB; 174 175 /** Is this a recover instruction. */ 176 bool recoverInst; 177 178 /** Is this a thread blocking instruction. */ 179 bool blockingInst; /* this inst has called thread_block() */ 180 181 /** Is this a thread syncrhonization instruction. */ 182 bool threadsyncWait; 183 184 /** The thread this instruction is from. */ 185 short threadNumber; 186 187 /** data address space ID, for loads & stores. */ 188 short asid; 189 190 /** How many source registers are ready. */ 191 unsigned readyRegs; 192 193 /** Pointer to the FullCPU object. */ 194 FullCPU *cpu; 195 196 /** Pointer to the exec context. */ 197 ImplState *thread; 198 199 /** The kind of fault this instruction has generated. */ 200 Fault fault; 201 202 /** The memory request. */ 203// MemReqPtr req; 204 Request *req; 205// Packet pkt; 206 207 uint8_t *memData; 208 209 /** The effective virtual address (lds & stores only). */ 210 Addr effAddr; 211 212 /** The effective physical address. */ 213 Addr physEffAddr; 214 215 /** Effective virtual address for a copy source. */ 216 Addr copySrcEffAddr; 217 218 /** Effective physical address for a copy source. */ 219 Addr copySrcPhysEffAddr; 220 221 /** The memory request flags (from translation). */ 222 unsigned memReqFlags; 223 224 /** The size of the data to be stored. */ 225 int storeSize; 226 227 /** The data to be stored. */ 228 IntReg storeData; 229 230 union Result { 231 uint64_t integer; 232 float fp; 233 double dbl; 234 }; 235 236 /** The result of the instruction; assumes for now that there's only one 237 * destination register. 238 */ 239 Result instResult; 240 241 /** PC of this instruction. */ 242 Addr PC; 243 244 /** Next non-speculative PC. It is not filled in at fetch, but rather 245 * once the target of the branch is truly known (either decode or 246 * execute). 247 */ 248 Addr nextPC; 249 250 /** Predicted next PC. */ 251 Addr predPC; 252 253 /** Count of total number of dynamic instructions. */ 254 static int instcount; 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 public: 266 /** BaseDynInst constructor given a binary instruction. 267 * @param inst The binary instruction. 268 * @param PC The PC of the instruction. 269 * @param pred_PC The predicted next PC. 270 * @param seq_num The sequence number of the instruction. 271 * @param cpu Pointer to the instruction's CPU. 272 */ 273 BaseDynInst(ExtMachInst inst, Addr PC, Addr pred_PC, InstSeqNum seq_num, 274 FullCPU *cpu); 275 276 /** BaseDynInst constructor given a StaticInst pointer. 277 * @param _staticInst The StaticInst for this BaseDynInst. 278 */ 279 BaseDynInst(StaticInstPtr &_staticInst); 280 281 /** BaseDynInst destructor. */ 282 ~BaseDynInst(); 283 284 private: 285 /** Function to initialize variables in the constructors. */ 286 void initVars(); 287 288 public: 289 /** 290 * @todo: Make this function work; currently it is a dummy function. 291 * @param fault Last fault. 292 * @param cmd Last command. 293 * @param addr Virtual address of access. 294 * @param p Memory accessed. 295 * @param nbytes Access size. 296 */ 297// void 298// trace_mem(Fault fault, 299// MemCmd cmd, 300// Addr addr, 301// void *p, 302// int nbytes); 303 304 /** Dumps out contents of this BaseDynInst. */ 305 void dump(); 306 307 /** Dumps out contents of this BaseDynInst into given string. */ 308 void dump(std::string &outstring); 309 310 /** Returns the fault type. */ 311 Fault getFault() { return fault; } 312 313 /** Checks whether or not this instruction has had its branch target 314 * calculated yet. For now it is not utilized and is hacked to be 315 * always false. 316 * @todo: Actually use this instruction. 317 */ 318 bool doneTargCalc() { return false; } 319 320 /** Returns the next PC. This could be the speculative next PC if it is 321 * called prior to the actual branch target being calculated. 322 */ 323 Addr readNextPC() { return nextPC; } 324 325 /** Set the predicted target of this current instruction. */ 326 void setPredTarg(Addr predicted_PC) { predPC = predicted_PC; } 327 328 /** Returns the predicted target of the branch. */ 329 Addr readPredTarg() { return predPC; } 330 331 /** Returns whether the instruction was predicted taken or not. */ 332 bool predTaken() { return predPC != (PC + sizeof(MachInst)); } 333 334 /** Returns whether the instruction mispredicted. */ 335 bool mispredicted() { return predPC != nextPC; } 336 337 // 338 // Instruction types. Forward checks to StaticInst object. 339 // 340 bool isNop() const { return staticInst->isNop(); } 341 bool isMemRef() const { return staticInst->isMemRef(); } 342 bool isLoad() const { return staticInst->isLoad(); } 343 bool isStore() const { return staticInst->isStore(); } 344 bool isStoreConditional() const 345 { return staticInst->isStoreConditional(); } 346 bool isInstPrefetch() const { return staticInst->isInstPrefetch(); } 347 bool isDataPrefetch() const { return staticInst->isDataPrefetch(); } 348 bool isCopy() const { return staticInst->isCopy(); } 349 bool isInteger() const { return staticInst->isInteger(); } 350 bool isFloating() const { return staticInst->isFloating(); } 351 bool isControl() const { return staticInst->isControl(); } 352 bool isCall() const { return staticInst->isCall(); } 353 bool isReturn() const { return staticInst->isReturn(); } 354 bool isDirectCtrl() const { return staticInst->isDirectCtrl(); } 355 bool isIndirectCtrl() const { return staticInst->isIndirectCtrl(); } 356 bool isCondCtrl() const { return staticInst->isCondCtrl(); } 357 bool isUncondCtrl() const { return staticInst->isUncondCtrl(); } 358 bool isThreadSync() const { return staticInst->isThreadSync(); } 359 bool isSerializing() const { return staticInst->isSerializing(); } 360 bool isSerializeBefore() const 361 { return staticInst->isSerializeBefore() || serializeBefore; } 362 bool isSerializeAfter() const 363 { return staticInst->isSerializeAfter() || serializeAfter; } 364 bool isMemBarrier() const { return staticInst->isMemBarrier(); } 365 bool isWriteBarrier() const { return staticInst->isWriteBarrier(); } 366 bool isNonSpeculative() const { return staticInst->isNonSpeculative(); } 367 bool isQuiesce() const { return staticInst->isQuiesce(); } 368 bool isIprAccess() const { return staticInst->isIprAccess(); } 369 bool isUnverifiable() const { return staticInst->isUnverifiable(); } 370 371 /** Temporarily sets this instruction as a serialize before instruction. */ 372 void setSerializeBefore() { serializeBefore = true; } 373 374 /** Clears the serializeBefore part of this instruction. */ 375 void clearSerializeBefore() { serializeBefore = false; } 376 377 /** Checks if this serializeBefore is only temporarily set. */ 378 bool isTempSerializeBefore() { return serializeBefore; } 379 380 /** Tracks if instruction has been externally set as serializeBefore. */ 381 bool serializeBefore; 382 383 /** Temporarily sets this instruction as a serialize after instruction. */ 384 void setSerializeAfter() { serializeAfter = true; } 385 386 /** Clears the serializeAfter part of this instruction.*/ 387 void clearSerializeAfter() { serializeAfter = false; } 388 389 /** Checks if this serializeAfter is only temporarily set. */ 390 bool isTempSerializeAfter() { return serializeAfter; } 391 392 /** Tracks if instruction has been externally set as serializeAfter. */ 393 bool serializeAfter; 394 395 /** Checks if the serialization part of this instruction has been 396 * handled. This does not apply to the temporary serializing 397 * state; it only applies to this instruction's own permanent 398 * serializing state. 399 */ 400 bool isSerializeHandled() { return serializeHandled; } 401 402 /** Sets the serialization part of this instruction as handled. */ 403 void setSerializeHandled() { serializeHandled = true; } 404 405 /** Whether or not the serialization of this instruction has been handled. */ 406 bool serializeHandled; 407 408 /** Returns the opclass of this instruction. */ 409 OpClass opClass() const { return staticInst->opClass(); } 410 411 /** Returns the branch target address. */ 412 Addr branchTarget() const { return staticInst->branchTarget(PC); } 413 414 /** Returns the number of source registers. */ 415 int8_t numSrcRegs() const { return staticInst->numSrcRegs(); } 416 417 /** Returns the number of destination registers. */ 418 int8_t numDestRegs() const { return staticInst->numDestRegs(); } 419 420 // the following are used to track physical register usage 421 // for machines with separate int & FP reg files 422 int8_t numFPDestRegs() const { return staticInst->numFPDestRegs(); } 423 int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); } 424 425 /** Returns the logical register index of the i'th destination register. */ 426 RegIndex destRegIdx(int i) const { return staticInst->destRegIdx(i); } 427 428 /** Returns the logical register index of the i'th source register. */ 429 RegIndex srcRegIdx(int i) const { return staticInst->srcRegIdx(i); } 430 431 /** Returns the result of an integer instruction. */ 432 uint64_t readIntResult() { return instResult.integer; } 433 434 /** Returns the result of a floating point instruction. */ 435 float readFloatResult() { return instResult.fp; } 436 437 /** Returns the result of a floating point (double) instruction. */ 438 double readDoubleResult() { return instResult.dbl; } 439 440 void setIntReg(const StaticInst *si, int idx, uint64_t val) 441 { 442 instResult.integer = val; 443 } 444 445 void setFloatRegSingle(const StaticInst *si, int idx, float val) 446 { 447 instResult.fp = val; 448 } 449 450 void setFloatRegDouble(const StaticInst *si, int idx, double val) 451 { 452 instResult.dbl = val; 453 } 454 455 void setFloatRegInt(const StaticInst *si, int idx, uint64_t val) 456 { 457 instResult.integer = val; 458 } 459 460 /** Records that one of the source registers is ready. */ 461 void markSrcRegReady(); 462 463 /** Marks a specific register as ready. */ 464 void markSrcRegReady(RegIndex src_idx); 465 466 /** Returns if a source register is ready. */ 467 bool isReadySrcRegIdx(int idx) const 468 { 469 return this->_readySrcRegIdx[idx]; 470 } 471 472 /** Sets this instruction as completed. */ 473 void setCompleted() { completed = true; } 474 475 /** Returns whether or not this instruction is completed. */ 476 bool isCompleted() const { return completed; } 477 478 void setResultReady() { resultReady = true; } 479 480 bool isResultReady() const { return resultReady; } 481 482 /** Sets this instruction as ready to issue. */ 483 void setCanIssue() { canIssue = true; } 484 485 /** Returns whether or not this instruction is ready to issue. */ 486 bool readyToIssue() const { return canIssue; } 487 488 /** Sets this instruction as issued from the IQ. */ 489 void setIssued() { issued = true; } 490 491 /** Returns whether or not this instruction has issued. */ 492 bool isIssued() const { return issued; } 493 494 /** Sets this instruction as executed. */ 495 void setExecuted() { executed = true; } 496 497 /** Returns whether or not this instruction has executed. */ 498 bool isExecuted() const { return executed; } 499 500 /** Sets this instruction as ready to commit. */ 501 void setCanCommit() { canCommit = true; } 502 503 /** Clears this instruction as being ready to commit. */ 504 void clearCanCommit() { canCommit = false; } 505 506 /** Returns whether or not this instruction is ready to commit. */ 507 bool readyToCommit() const { return canCommit; } 508 509 /** Sets this instruction as committed. */ 510 void setCommitted() { committed = true; } 511 512 /** Returns whether or not this instruction is committed. */ 513 bool isCommitted() const { return committed; } 514 515 /** Sets this instruction as squashed. */ 516 void setSquashed() { squashed = true; } 517 518 /** Returns whether or not this instruction is squashed. */ 519 bool isSquashed() const { return squashed; } 520 521 //Instruction Queue Entry 522 //----------------------- 523 /** Sets this instruction as a entry the IQ. */ 524 void setInIQ() { iqEntry = true; } 525 526 /** Sets this instruction as a entry the IQ. */ 527 void removeInIQ() { iqEntry = false; } 528 529 /** Sets this instruction as squashed in the IQ. */ 530 void setSquashedInIQ() { squashedInIQ = true; squashed = true;} 531 532 /** Returns whether or not this instruction is squashed in the IQ. */ 533 bool isSquashedInIQ() const { return squashedInIQ; } 534 535 /** Returns whether or not this instruction has issued. */ 536 bool isInIQ() const { return iqEntry; } 537 538 539 //Load / Store Queue Functions 540 //----------------------- 541 /** Sets this instruction as a entry the LSQ. */ 542 void setInLSQ() { lsqEntry = true; } 543 544 /** Sets this instruction as a entry the LSQ. */ 545 void removeInLSQ() { lsqEntry = false; } 546 547 /** Sets this instruction as squashed in the LSQ. */ 548 void setSquashedInLSQ() { squashedInLSQ = true;} 549 550 /** Returns whether or not this instruction is squashed in the LSQ. */ 551 bool isSquashedInLSQ() const { return squashedInLSQ; } 552 553 /** Returns whether or not this instruction is in the LSQ. */ 554 bool isInLSQ() const { return lsqEntry; } 555 556 557 //Reorder Buffer Functions 558 //----------------------- 559 /** Sets this instruction as a entry the ROB. */ 560 void setInROB() { robEntry = true; } 561 562 /** Sets this instruction as a entry the ROB. */ 563 void removeInROB() { robEntry = false; } 564 565 /** Sets this instruction as squashed in the ROB. */ 566 void setSquashedInROB() { squashedInROB = true; } 567 568 /** Returns whether or not this instruction is squashed in the ROB. */ 569 bool isSquashedInROB() const { return squashedInROB; } 570 571 /** Returns whether or not this instruction is in the ROB. */ 572 bool isInROB() const { return robEntry; } 573 574 /** Read the PC of this instruction. */ 575 const Addr readPC() const { return PC; } 576 577 /** Set the next PC of this instruction (its actual target). */ 578 void setNextPC(uint64_t val) 579 { 580 nextPC = val; 581// instResult.integer = val; 582 } 583 584 void setASID(short addr_space_id) { asid = addr_space_id; } 585 586 void setThread(unsigned tid) { threadNumber = tid; } 587 588 void setState(ImplState *state) { thread = state; } 589 590 /** Returns the exec context. 591 * @todo: Remove this once the ExecContext is no longer used. 592 */ 593 ExecContext *xcBase() { return thread->getXCProxy(); } 594 595 private: 596 /** Instruction effective address. 597 * @todo: Consider if this is necessary or not. 598 */ 599 Addr instEffAddr; 600 601 /** Whether or not the effective address calculation is completed. 602 * @todo: Consider if this is necessary or not. 603 */ 604 bool eaCalcDone; 605 606 public: 607 /** Sets the effective address. */ 608 void setEA(Addr &ea) { instEffAddr = ea; eaCalcDone = true; } 609 610 /** Returns the effective address. */ 611 const Addr &getEA() const { return instEffAddr; } 612 613 /** Returns whether or not the eff. addr. calculation has been completed. */ 614 bool doneEACalc() { return eaCalcDone; } 615 616 /** Returns whether or not the eff. addr. source registers are ready. */ 617 bool eaSrcsReady(); 618 619 /** Whether or not the memory operation is done. */ 620 bool memOpDone; 621 622 public: 623 /** Load queue index. */ 624 int16_t lqIdx; 625 626 /** Store queue index. */ 627 int16_t sqIdx; 628 629 bool reachedCommit; 630 631 /** Iterator pointing to this BaseDynInst in the list of all insts. */ 632 ListIt instListIt; 633 634 /** Returns iterator to this instruction in the list of all insts. */ 635 ListIt &getInstListIt() { return instListIt; } 636 637 /** Sets iterator for this instruction in the list of all insts. */ 638 void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; } 639}; 640 641template<class Impl> 642template<class T> 643inline Fault 644BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags) 645{ 646 if (executed) { 647 panic("Not supposed to re-execute with split mem ops!"); 648 fault = cpu->read(req, data, lqIdx); 649 return fault; 650 } 651 652 req = new Request(); 653 req->setVirt(asid, addr, sizeof(T), flags, this->PC); 654 req->setThreadContext(thread->cpuId, threadNumber); 655 656 if ((req->getVaddr() & (TheISA::VMPageSize - 1)) + req->getSize() > 657 TheISA::VMPageSize) { 658 return TheISA::genAlignmentFault(); 659 } 660 661 fault = cpu->translateDataReadReq(req); 662 663 if (fault == NoFault) { 664 effAddr = req->getVaddr(); 665 physEffAddr = req->getPaddr(); 666 memReqFlags = req->getFlags(); 667 668#if FULL_SYSTEM 669 if (cpu->system->memctrl->badaddr(physEffAddr)) { 670 fault = TheISA::genMachineCheckFault(); 671 data = (T)-1; 672 this->setExecuted(); 673 } else { 674 fault = cpu->read(req, data, lqIdx); 675 } 676#else 677 fault = cpu->read(req, data, lqIdx); 678#endif 679 } else { 680 // Return a fixed value to keep simulation deterministic even 681 // along misspeculated paths. 682 data = (T)-1; 683 684 // Commit will have to clean up whatever happened. Set this 685 // instruction as executed. 686 this->setExecuted(); 687 } 688 689 if (traceData) { 690 traceData->setAddr(addr); 691 traceData->setData(data); 692 } 693 694 return fault; 695} 696 697template<class Impl> 698template<class T> 699inline Fault 700BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res) 701{ 702 if (traceData) { 703 traceData->setAddr(addr); 704 traceData->setData(data); 705 } 706 707 req = new Request(); 708 req->setVirt(asid, addr, sizeof(T), flags, this->PC); 709 req->setThreadContext(thread->cpuId, threadNumber); 710 711 if ((req->getVaddr() & (TheISA::VMPageSize - 1)) + req->getSize() > 712 TheISA::VMPageSize) { 713 return TheISA::genAlignmentFault(); 714 } 715 716 fault = cpu->translateDataWriteReq(req); 717 718 if (fault == NoFault) { 719 effAddr = req->getVaddr(); 720 physEffAddr = req->getPaddr(); 721 memReqFlags = req->getFlags(); 722#if FULL_SYSTEM 723 if (cpu->system->memctrl->badaddr(physEffAddr)) { 724 fault = TheISA::genMachineCheckFault(); 725 } else { 726 fault = cpu->write(req, data, sqIdx); 727 } 728#else 729 fault = cpu->write(req, data, sqIdx); 730#endif 731 } 732 733 if (res) { 734 // always return some result to keep misspeculated paths 735 // (which will ignore faults) deterministic 736 *res = (fault == NoFault) ? req->getScResult() : 0; 737 } 738 739 return fault; 740} 741 742#endif // __CPU_BASE_DYN_INST_HH__ 743