base_dyn_inst.hh revision 2356
13993Sgblack@eecs.umich.edu/* 22632Sstever@eecs.umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan 32632Sstever@eecs.umich.edu * All rights reserved. 42632Sstever@eecs.umich.edu * 52632Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 62632Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are 72632Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright 82632Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 92632Sstever@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 102632Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 112632Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution; 122632Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its 132632Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from 142632Sstever@eecs.umich.edu * this software without specific prior written permission. 152632Sstever@eecs.umich.edu * 162632Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172632Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182632Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192632Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202632Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212632Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222632Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232632Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242632Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252632Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262632Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272632Sstever@eecs.umich.edu */ 282632Sstever@eecs.umich.edu 292632Sstever@eecs.umich.edu#ifndef __CPU_BASE_DYN_INST_HH__ 302632Sstever@eecs.umich.edu#define __CPU_BASE_DYN_INST_HH__ 312023SN/A 322023SN/A#include <list> 332023SN/A#include <string> 342023SN/A 352023SN/A#include "base/fast_alloc.hh" 362023SN/A#include "base/trace.hh" 372023SN/A#include "config/full_system.hh" 382023SN/A#include "cpu/exetrace.hh" 392023SN/A#include "cpu/inst_seq.hh" 404040Ssaidi@eecs.umich.edu#include "cpu/static_inst.hh" 412023SN/A#include "encumbered/cpu/full/op_class.hh" 422023SN/A#include "mem/functional/memory_control.hh" 432023SN/A#include "sim/system.hh" 442023SN/A/* 452023SN/A#include "encumbered/cpu/full/bpred_update.hh" 463279Sgblack@eecs.umich.edu#include "encumbered/cpu/full/spec_memory.hh" 473279Sgblack@eecs.umich.edu#include "encumbered/cpu/full/spec_state.hh" 483279Sgblack@eecs.umich.edu#include "encumbered/mem/functional/main.hh" 493279Sgblack@eecs.umich.edu*/ 503279Sgblack@eecs.umich.edu 513279Sgblack@eecs.umich.edu/** 523381Sgblack@eecs.umich.edu * @file 533279Sgblack@eecs.umich.edu * Defines a dynamic instruction context. 543279Sgblack@eecs.umich.edu */ 553279Sgblack@eecs.umich.edu 562023SN/A// Forward declaration. 572023SN/Aclass StaticInstPtr; 582023SN/A 592023SN/Atemplate <class Impl> 603761Sgblack@eecs.umich.educlass BaseDynInst : public FastAlloc, public RefCounted 612501SN/A{ 623761Sgblack@eecs.umich.edu public: 633761Sgblack@eecs.umich.edu // Typedef for the CPU. 643761Sgblack@eecs.umich.edu typedef typename Impl::FullCPU FullCPU; 653761Sgblack@eecs.umich.edu typedef typename FullCPU::ImplState ImplState; 663835Sgblack@eecs.umich.edu 673952Sgblack@eecs.umich.edu // Binary machine instruction type. 683835Sgblack@eecs.umich.edu typedef TheISA::MachInst MachInst; 693761Sgblack@eecs.umich.edu // Extended machine instruction type 703761Sgblack@eecs.umich.edu typedef TheISA::ExtMachInst ExtMachInst; 713761Sgblack@eecs.umich.edu // Logical register index type. 723761Sgblack@eecs.umich.edu typedef TheISA::RegIndex RegIndex; 733761Sgblack@eecs.umich.edu // Integer register index type. 743761Sgblack@eecs.umich.edu typedef TheISA::IntReg IntReg; 753761Sgblack@eecs.umich.edu 763761Sgblack@eecs.umich.edu // The DynInstPtr type. 773761Sgblack@eecs.umich.edu typedef typename Impl::DynInstPtr DynInstPtr; 783761Sgblack@eecs.umich.edu 793761Sgblack@eecs.umich.edu // The list of instructions iterator type. 803279Sgblack@eecs.umich.edu typedef typename std::list<DynInstPtr>::iterator ListIt; 813279Sgblack@eecs.umich.edu 823279Sgblack@eecs.umich.edu enum { 833279Sgblack@eecs.umich.edu MaxInstSrcRegs = TheISA::MaxInstSrcRegs, /// Max source regs 843279Sgblack@eecs.umich.edu MaxInstDestRegs = TheISA::MaxInstDestRegs, /// Max dest regs 853279Sgblack@eecs.umich.edu }; 863279Sgblack@eecs.umich.edu 873279Sgblack@eecs.umich.edu /** The StaticInst used by this BaseDynInst. */ 883279Sgblack@eecs.umich.edu StaticInstPtr staticInst; 893279Sgblack@eecs.umich.edu 903279Sgblack@eecs.umich.edu //////////////////////////////////////////// 913279Sgblack@eecs.umich.edu // 923993Sgblack@eecs.umich.edu // INSTRUCTION EXECUTION 933279Sgblack@eecs.umich.edu // 943993Sgblack@eecs.umich.edu //////////////////////////////////////////// 953279Sgblack@eecs.umich.edu /** InstRecord that tracks this instructions. */ 962954Sgblack@eecs.umich.edu Trace::InstRecord *traceData; 972954Sgblack@eecs.umich.edu 983761Sgblack@eecs.umich.edu /** 992516SN/A * Does a read to a given address. 1002561SN/A * @param addr The address to read. 1012561SN/A * @param data The read's data is written into this parameter. 1022561SN/A * @param flags The request's flags. 1032646Ssaidi@eecs.umich.edu * @return Returns any fault due to the read. 1042469SN/A */ 1053761Sgblack@eecs.umich.edu template <class T> 1063761Sgblack@eecs.umich.edu Fault read(Addr addr, T &data, unsigned flags); 1073761Sgblack@eecs.umich.edu 1083761Sgblack@eecs.umich.edu /** 1092954Sgblack@eecs.umich.edu * Does a write to a given address. 1103587Sgblack@eecs.umich.edu * @param data The data to be written. 1113587Sgblack@eecs.umich.edu * @param addr The address to write to. 1123587Sgblack@eecs.umich.edu * @param flags The request's flags. 1133587Sgblack@eecs.umich.edu * @param res The result of the write (for load locked/store conditionals). 1143587Sgblack@eecs.umich.edu * @return Returns any fault due to the write. 1153587Sgblack@eecs.umich.edu */ 1163587Sgblack@eecs.umich.edu template <class T> 1173587Sgblack@eecs.umich.edu Fault write(T data, Addr addr, unsigned flags, 1183587Sgblack@eecs.umich.edu uint64_t *res); 1193587Sgblack@eecs.umich.edu 1202646Ssaidi@eecs.umich.edu void prefetch(Addr addr, unsigned flags); 1213587Sgblack@eecs.umich.edu void writeHint(Addr addr, int size, unsigned flags); 1223587Sgblack@eecs.umich.edu Fault copySrcTranslate(Addr src); 1233587Sgblack@eecs.umich.edu Fault copy(Addr dest); 1243587Sgblack@eecs.umich.edu 1253587Sgblack@eecs.umich.edu /** @todo: Consider making this private. */ 1263587Sgblack@eecs.umich.edu public: 1273587Sgblack@eecs.umich.edu /** The sequence number of the instruction. */ 1283587Sgblack@eecs.umich.edu InstSeqNum seqNum; 1293587Sgblack@eecs.umich.edu 1303793Sgblack@eecs.umich.edu enum Status { 1313761Sgblack@eecs.umich.edu IqEntry, /// Instruction is in the IQ 1323761Sgblack@eecs.umich.edu RobEntry, /// Instruction is in the ROB 1333761Sgblack@eecs.umich.edu LsqEntry, /// Instruction is in the LSQ 1343761Sgblack@eecs.umich.edu Completed, /// Instruction has completed 1353761Sgblack@eecs.umich.edu ResultReady, /// Instruction has its result 1363761Sgblack@eecs.umich.edu CanIssue, /// Instruction can issue and execute 1373761Sgblack@eecs.umich.edu Issued, /// Instruction has issued 1383761Sgblack@eecs.umich.edu Executed, /// Instruction has executed 1393761Sgblack@eecs.umich.edu CanCommit, /// Instruction can commit 1403761Sgblack@eecs.umich.edu AtCommit, /// Instruction has reached commit 1413587Sgblack@eecs.umich.edu Committed, /// Instruction has committed 1422646Ssaidi@eecs.umich.edu Squashed, /// Instruction is squashed 1433587Sgblack@eecs.umich.edu SquashedInIQ, /// Instruction is squashed in the IQ 1443587Sgblack@eecs.umich.edu SquashedInLSQ, /// Instruction is squashed in the LSQ 1453587Sgblack@eecs.umich.edu SquashedInROB, /// Instruction is squashed in the ROB 1463587Sgblack@eecs.umich.edu RecoverInst, /// Is a recover instruction 1473587Sgblack@eecs.umich.edu BlockingInst, /// Is a blocking instruction 1483587Sgblack@eecs.umich.edu ThreadsyncWait, /// Is a thread synchronization instruction 1493600Sgblack@eecs.umich.edu SerializeBefore, /// Needs to serialize on 1502646Ssaidi@eecs.umich.edu /// instructions ahead of it 1513587Sgblack@eecs.umich.edu SerializeAfter, /// Needs to serialize instructions behind it 1523388Sgblack@eecs.umich.edu SerializeHandled, /// Serialization has been handled 1533388Sgblack@eecs.umich.edu NumStatus 1542646Ssaidi@eecs.umich.edu }; 1552023SN/A 156 /** The status of this BaseDynInst. Several bits can be set. */ 157 std::bitset<NumStatus> status; 158 159 /** The thread this instruction is from. */ 160 short threadNumber; 161 162 /** data address space ID, for loads & stores. */ 163 short asid; 164 165 /** How many source registers are ready. */ 166 unsigned readyRegs; 167 168 /** Pointer to the FullCPU object. */ 169 FullCPU *cpu; 170 171 /** Pointer to the exec context. */ 172 ImplState *thread; 173 174 /** The kind of fault this instruction has generated. */ 175 Fault fault; 176 177 /** The memory request. */ 178 MemReqPtr req; 179 180 /** The effective virtual address (lds & stores only). */ 181 Addr effAddr; 182 183 /** The effective physical address. */ 184 Addr physEffAddr; 185 186 /** Effective virtual address for a copy source. */ 187 Addr copySrcEffAddr; 188 189 /** Effective physical address for a copy source. */ 190 Addr copySrcPhysEffAddr; 191 192 /** The memory request flags (from translation). */ 193 unsigned memReqFlags; 194 195 /** The size of the data to be stored. */ 196 int storeSize; 197 198 /** The data to be stored. */ 199 IntReg storeData; 200 201 union Result { 202 uint64_t integer; 203// float fp; 204 double dbl; 205 }; 206 207 /** The result of the instruction; assumes for now that there's only one 208 * destination register. 209 */ 210 Result instResult; 211 212 /** PC of this instruction. */ 213 Addr PC; 214 215 /** Next non-speculative PC. It is not filled in at fetch, but rather 216 * once the target of the branch is truly known (either decode or 217 * execute). 218 */ 219 Addr nextPC; 220 221 /** Predicted next PC. */ 222 Addr predPC; 223 224 /** Count of total number of dynamic instructions. */ 225 static int instcount; 226 227#ifdef DEBUG 228 void dumpSNList(); 229#endif 230 231 /** Whether or not the source register is ready. 232 * @todo: Not sure this should be here vs the derived class. 233 */ 234 bool _readySrcRegIdx[MaxInstSrcRegs]; 235 236 public: 237 /** BaseDynInst constructor given a binary instruction. 238 * @param inst The binary instruction. 239 * @param PC The PC of the instruction. 240 * @param pred_PC The predicted next PC. 241 * @param seq_num The sequence number of the instruction. 242 * @param cpu Pointer to the instruction's CPU. 243 */ 244 BaseDynInst(ExtMachInst inst, Addr PC, Addr pred_PC, InstSeqNum seq_num, 245 FullCPU *cpu); 246 247 /** BaseDynInst constructor given a StaticInst pointer. 248 * @param _staticInst The StaticInst for this BaseDynInst. 249 */ 250 BaseDynInst(StaticInstPtr &_staticInst); 251 252 /** BaseDynInst destructor. */ 253 ~BaseDynInst(); 254 255 private: 256 /** Function to initialize variables in the constructors. */ 257 void initVars(); 258 259 public: 260 /** 261 * @todo: Make this function work; currently it is a dummy function. 262 * @param fault Last fault. 263 * @param cmd Last command. 264 * @param addr Virtual address of access. 265 * @param p Memory accessed. 266 * @param nbytes Access size. 267 */ 268 void 269 trace_mem(Fault fault, 270 MemCmd cmd, 271 Addr addr, 272 void *p, 273 int nbytes); 274 275 /** Dumps out contents of this BaseDynInst. */ 276 void dump(); 277 278 /** Dumps out contents of this BaseDynInst into given string. */ 279 void dump(std::string &outstring); 280 281 /** Returns the fault type. */ 282 Fault getFault() { return fault; } 283 284 /** Checks whether or not this instruction has had its branch target 285 * calculated yet. For now it is not utilized and is hacked to be 286 * always false. 287 * @todo: Actually use this instruction. 288 */ 289 bool doneTargCalc() { return false; } 290 291 /** Returns the next PC. This could be the speculative next PC if it is 292 * called prior to the actual branch target being calculated. 293 */ 294 Addr readNextPC() { return nextPC; } 295 296 /** Set the predicted target of this current instruction. */ 297 void setPredTarg(Addr predicted_PC) { predPC = predicted_PC; } 298 299 /** Returns the predicted target of the branch. */ 300 Addr readPredTarg() { return predPC; } 301 302 /** Returns whether the instruction was predicted taken or not. */ 303 bool predTaken() { return predPC != (PC + sizeof(MachInst)); } 304 305 /** Returns whether the instruction mispredicted. */ 306 bool mispredicted() { return predPC != nextPC; } 307 308 // 309 // Instruction types. Forward checks to StaticInst object. 310 // 311 bool isNop() const { return staticInst->isNop(); } 312 bool isMemRef() const { return staticInst->isMemRef(); } 313 bool isLoad() const { return staticInst->isLoad(); } 314 bool isStore() const { return staticInst->isStore(); } 315 bool isStoreConditional() const 316 { return staticInst->isStoreConditional(); } 317 bool isInstPrefetch() const { return staticInst->isInstPrefetch(); } 318 bool isDataPrefetch() const { return staticInst->isDataPrefetch(); } 319 bool isCopy() const { return staticInst->isCopy(); } 320 bool isInteger() const { return staticInst->isInteger(); } 321 bool isFloating() const { return staticInst->isFloating(); } 322 bool isControl() const { return staticInst->isControl(); } 323 bool isCall() const { return staticInst->isCall(); } 324 bool isReturn() const { return staticInst->isReturn(); } 325 bool isDirectCtrl() const { return staticInst->isDirectCtrl(); } 326 bool isIndirectCtrl() const { return staticInst->isIndirectCtrl(); } 327 bool isCondCtrl() const { return staticInst->isCondCtrl(); } 328 bool isUncondCtrl() const { return staticInst->isUncondCtrl(); } 329 bool isThreadSync() const { return staticInst->isThreadSync(); } 330 bool isSerializing() const { return staticInst->isSerializing(); } 331 bool isSerializeBefore() const 332 { return staticInst->isSerializeBefore() || status[SerializeBefore]; } 333 bool isSerializeAfter() const 334 { return staticInst->isSerializeAfter() || status[SerializeAfter]; } 335 bool isMemBarrier() const { return staticInst->isMemBarrier(); } 336 bool isWriteBarrier() const { return staticInst->isWriteBarrier(); } 337 bool isNonSpeculative() const { return staticInst->isNonSpeculative(); } 338 bool isQuiesce() const { return staticInst->isQuiesce(); } 339 bool isIprAccess() const { return staticInst->isIprAccess(); } 340 bool isUnverifiable() const { return staticInst->isUnverifiable(); } 341 342 /** Temporarily sets this instruction as a serialize before instruction. */ 343 void setSerializeBefore() { status.set(SerializeBefore); } 344 345 /** Clears the serializeBefore part of this instruction. */ 346 void clearSerializeBefore() { status.reset(SerializeBefore); } 347 348 /** Checks if this serializeBefore is only temporarily set. */ 349 bool isTempSerializeBefore() { return status[SerializeBefore]; } 350 351 /** Temporarily sets this instruction as a serialize after instruction. */ 352 void setSerializeAfter() { status.set(SerializeAfter); } 353 354 /** Clears the serializeAfter part of this instruction.*/ 355 void clearSerializeAfter() { status.reset(SerializeAfter); } 356 357 /** Checks if this serializeAfter is only temporarily set. */ 358 bool isTempSerializeAfter() { return status[SerializeAfter]; } 359 360 /** Sets the serialization part of this instruction as handled. */ 361 void setSerializeHandled() { status.set(SerializeHandled); } 362 363 /** Checks if the serialization part of this instruction has been 364 * handled. This does not apply to the temporary serializing 365 * state; it only applies to this instruction's own permanent 366 * serializing state. 367 */ 368 bool isSerializeHandled() { return status[SerializeHandled]; } 369 370 /** Returns the opclass of this instruction. */ 371 OpClass opClass() const { return staticInst->opClass(); } 372 373 /** Returns the branch target address. */ 374 Addr branchTarget() const { return staticInst->branchTarget(PC); } 375 376 /** Returns the number of source registers. */ 377 int8_t numSrcRegs() const { return staticInst->numSrcRegs(); } 378 379 /** Returns the number of destination registers. */ 380 int8_t numDestRegs() const { return staticInst->numDestRegs(); } 381 382 // the following are used to track physical register usage 383 // for machines with separate int & FP reg files 384 int8_t numFPDestRegs() const { return staticInst->numFPDestRegs(); } 385 int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); } 386 387 /** Returns the logical register index of the i'th destination register. */ 388 RegIndex destRegIdx(int i) const { return staticInst->destRegIdx(i); } 389 390 /** Returns the logical register index of the i'th source register. */ 391 RegIndex srcRegIdx(int i) const { return staticInst->srcRegIdx(i); } 392 393 /** Returns the result of an integer instruction. */ 394 uint64_t readIntResult() { return instResult.integer; } 395 396 /** Returns the result of a floating point instruction. */ 397 float readFloatResult() { return (float)instResult.dbl; } 398 399 /** Returns the result of a floating point (double) instruction. */ 400 double readDoubleResult() { return instResult.dbl; } 401 402 void setIntReg(const StaticInst *si, int idx, uint64_t val) 403 { 404 instResult.integer = val; 405 } 406 407 void setFloatRegSingle(const StaticInst *si, int idx, float val) 408 { 409// instResult.fp = val; 410 instResult.dbl = (double)val; 411 } 412 413 void setFloatRegDouble(const StaticInst *si, int idx, double val) 414 { 415 instResult.dbl = val; 416 } 417 418 void setFloatRegInt(const StaticInst *si, int idx, uint64_t val) 419 { 420 instResult.integer = val; 421 } 422 423 /** Records that one of the source registers is ready. */ 424 void markSrcRegReady(); 425 426 /** Marks a specific register as ready. */ 427 void markSrcRegReady(RegIndex src_idx); 428 429 /** Returns if a source register is ready. */ 430 bool isReadySrcRegIdx(int idx) const 431 { 432 return this->_readySrcRegIdx[idx]; 433 } 434 435 /** Sets this instruction as completed. */ 436 void setCompleted() { status.set(Completed); } 437 438 /** Returns whether or not this instruction is completed. */ 439 bool isCompleted() const { return status[Completed]; } 440 441 /** Marks the result as ready. */ 442 void setResultReady() { status.set(ResultReady); } 443 444 /** Returns whether or not the result is ready. */ 445 bool isResultReady() const { return status[ResultReady]; } 446 447 /** Sets this instruction as ready to issue. */ 448 void setCanIssue() { status.set(CanIssue); } 449 450 /** Returns whether or not this instruction is ready to issue. */ 451 bool readyToIssue() const { return status[CanIssue]; } 452 453 /** Sets this instruction as issued from the IQ. */ 454 void setIssued() { status.set(Issued); } 455 456 /** Returns whether or not this instruction has issued. */ 457 bool isIssued() const { return status[Issued]; } 458 459 /** Sets this instruction as executed. */ 460 void setExecuted() { status.set(Executed); } 461 462 /** Returns whether or not this instruction has executed. */ 463 bool isExecuted() const { return status[Executed]; } 464 465 /** Sets this instruction as ready to commit. */ 466 void setCanCommit() { status.set(CanCommit); } 467 468 /** Clears this instruction as being ready to commit. */ 469 void clearCanCommit() { status.reset(CanCommit); } 470 471 /** Returns whether or not this instruction is ready to commit. */ 472 bool readyToCommit() const { return status[CanCommit]; } 473 474 void setAtCommit() { status.set(AtCommit); } 475 476 bool isAtCommit() { return status[AtCommit]; } 477 478 /** Sets this instruction as committed. */ 479 void setCommitted() { status.set(Committed); } 480 481 /** Returns whether or not this instruction is committed. */ 482 bool isCommitted() const { return status[Committed]; } 483 484 /** Sets this instruction as squashed. */ 485 void setSquashed() { status.set(Squashed); } 486 487 /** Returns whether or not this instruction is squashed. */ 488 bool isSquashed() const { return status[Squashed]; } 489 490 //Instruction Queue Entry 491 //----------------------- 492 /** Sets this instruction as a entry the IQ. */ 493 void setInIQ() { status.set(IqEntry); } 494 495 /** Sets this instruction as a entry the IQ. */ 496 void clearInIQ() { status.reset(IqEntry); } 497 498 /** Returns whether or not this instruction has issued. */ 499 bool isInIQ() const { return status[IqEntry]; } 500 501 /** Sets this instruction as squashed in the IQ. */ 502 void setSquashedInIQ() { status.set(SquashedInIQ); status.set(Squashed);} 503 504 /** Returns whether or not this instruction is squashed in the IQ. */ 505 bool isSquashedInIQ() const { return status[SquashedInIQ]; } 506 507 508 //Load / Store Queue Functions 509 //----------------------- 510 /** Sets this instruction as a entry the LSQ. */ 511 void setInLSQ() { status.set(LsqEntry); } 512 513 /** Sets this instruction as a entry the LSQ. */ 514 void removeInLSQ() { status.reset(LsqEntry); } 515 516 /** Returns whether or not this instruction is in the LSQ. */ 517 bool isInLSQ() const { return status[LsqEntry]; } 518 519 /** Sets this instruction as squashed in the LSQ. */ 520 void setSquashedInLSQ() { status.set(SquashedInLSQ);} 521 522 /** Returns whether or not this instruction is squashed in the LSQ. */ 523 bool isSquashedInLSQ() const { return status[SquashedInLSQ]; } 524 525 526 //Reorder Buffer Functions 527 //----------------------- 528 /** Sets this instruction as a entry the ROB. */ 529 void setInROB() { status.set(RobEntry); } 530 531 /** Sets this instruction as a entry the ROB. */ 532 void clearInROB() { status.reset(RobEntry); } 533 534 /** Returns whether or not this instruction is in the ROB. */ 535 bool isInROB() const { return status[RobEntry]; } 536 537 /** Sets this instruction as squashed in the ROB. */ 538 void setSquashedInROB() { status.set(SquashedInROB); } 539 540 /** Returns whether or not this instruction is squashed in the ROB. */ 541 bool isSquashedInROB() const { return status[SquashedInROB]; } 542 543 /** Read the PC of this instruction. */ 544 const Addr readPC() const { return PC; } 545 546 /** Set the next PC of this instruction (its actual target). */ 547 void setNextPC(uint64_t val) 548 { 549 nextPC = val; 550// instResult.integer = val; 551 } 552 553 void setASID(short addr_space_id) { asid = addr_space_id; } 554 555 void setThread(unsigned tid) { threadNumber = tid; } 556 557 void setState(ImplState *state) { thread = state; } 558 559 /** Returns the exec context. 560 * @todo: Remove this once the ExecContext is no longer used. 561 */ 562 ExecContext *xcBase() { return thread->getXCProxy(); } 563 564 private: 565 /** Instruction effective address. 566 * @todo: Consider if this is necessary or not. 567 */ 568 Addr instEffAddr; 569 570 /** Whether or not the effective address calculation is completed. 571 * @todo: Consider if this is necessary or not. 572 */ 573 bool eaCalcDone; 574 575 public: 576 /** Sets the effective address. */ 577 void setEA(Addr &ea) { instEffAddr = ea; eaCalcDone = true; } 578 579 /** Returns the effective address. */ 580 const Addr &getEA() const { return req->vaddr; } 581 582 /** Returns whether or not the eff. addr. calculation has been completed. */ 583 bool doneEACalc() { return eaCalcDone; } 584 585 /** Returns whether or not the eff. addr. source registers are ready. */ 586 bool eaSrcsReady(); 587 588 /** Whether or not the memory operation is done. */ 589 bool memOpDone; 590 591 public: 592 /** Load queue index. */ 593 int16_t lqIdx; 594 595 /** Store queue index. */ 596 int16_t sqIdx; 597 598 /** Iterator pointing to this BaseDynInst in the list of all insts. */ 599 ListIt instListIt; 600 601 /** Returns iterator to this instruction in the list of all insts. */ 602 ListIt &getInstListIt() { return instListIt; } 603 604 /** Sets iterator for this instruction in the list of all insts. */ 605 void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; } 606}; 607 608template<class Impl> 609template<class T> 610inline Fault 611BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags) 612{ 613 if (status[Executed]) { 614 fault = cpu->read(req, data, lqIdx); 615 return fault; 616 } 617 618 req = new MemReq(addr, thread->getXCProxy(), sizeof(T), flags); 619 req->asid = asid; 620 req->thread_num = threadNumber; 621 req->pc = this->PC; 622 623 if ((req->vaddr & (TheISA::VMPageSize - 1)) + req->size > 624 TheISA::VMPageSize) { 625 return TheISA::genAlignmentFault(); 626 } 627 628 fault = cpu->translateDataReadReq(req); 629 630 effAddr = req->vaddr; 631 physEffAddr = req->paddr; 632 memReqFlags = req->flags; 633 634 if (fault == NoFault) { 635#if FULL_SYSTEM 636 if (cpu->system->memctrl->badaddr(physEffAddr)) { 637 fault = TheISA::genMachineCheckFault(); 638 data = (T)-1; 639 this->setExecuted(); 640 } else { 641 fault = cpu->read(req, data, lqIdx); 642 } 643#else 644 fault = cpu->read(req, data, lqIdx); 645#endif 646 } else { 647 // Return a fixed value to keep simulation deterministic even 648 // along misspeculated paths. 649 data = (T)-1; 650 651 // Commit will have to clean up whatever happened. Set this 652 // instruction as executed. 653 this->setExecuted(); 654 } 655 656 if (traceData) { 657 traceData->setAddr(addr); 658 traceData->setData(data); 659 } 660 661 return fault; 662} 663 664template<class Impl> 665template<class T> 666inline Fault 667BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res) 668{ 669 if (traceData) { 670 traceData->setAddr(addr); 671 traceData->setData(data); 672 } 673 674 req = new MemReq(addr, thread->getXCProxy(), sizeof(T), flags); 675 676 req->asid = asid; 677 req->thread_num = threadNumber; 678 req->pc = this->PC; 679 680 if ((req->vaddr & (TheISA::VMPageSize - 1)) + req->size > 681 TheISA::VMPageSize) { 682 return TheISA::genAlignmentFault(); 683 } 684 685 fault = cpu->translateDataWriteReq(req); 686 687 effAddr = req->vaddr; 688 physEffAddr = req->paddr; 689 memReqFlags = req->flags; 690 691 if (fault == NoFault) { 692#if FULL_SYSTEM 693 if (cpu->system->memctrl->badaddr(physEffAddr)) { 694 fault = TheISA::genMachineCheckFault(); 695 } else { 696 fault = cpu->write(req, data, sqIdx); 697 } 698#else 699 fault = cpu->write(req, data, sqIdx); 700#endif 701 } 702 703 if (res) { 704 // always return some result to keep misspeculated paths 705 // (which will ignore faults) deterministic 706 *res = (fault == NoFault) ? req->result : 0; 707 } 708 709 return fault; 710} 711 712#endif // __CPU_BASE_DYN_INST_HH__ 713