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