cpu.cc revision 2107
12650Ssaidi@eecs.umich.edu/* 22650Ssaidi@eecs.umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan 32650Ssaidi@eecs.umich.edu * All rights reserved. 42650Ssaidi@eecs.umich.edu * 52650Ssaidi@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 62650Ssaidi@eecs.umich.edu * modification, are permitted provided that the following conditions are 72650Ssaidi@eecs.umich.edu * met: redistributions of source code must retain the above copyright 82650Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 92650Ssaidi@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 102650Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 112650Ssaidi@eecs.umich.edu * documentation and/or other materials provided with the distribution; 122650Ssaidi@eecs.umich.edu * neither the name of the copyright holders nor the names of its 132650Ssaidi@eecs.umich.edu * contributors may be used to endorse or promote products derived from 142650Ssaidi@eecs.umich.edu * this software without specific prior written permission. 152650Ssaidi@eecs.umich.edu * 162650Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172650Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182650Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192650Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202650Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212650Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222650Ssaidi@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232650Ssaidi@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242650Ssaidi@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252650Ssaidi@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262650Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272650Ssaidi@eecs.umich.edu */ 282650Ssaidi@eecs.umich.edu 293817Ssaidi@eecs.umich.edu#include "config/full_system.hh" 303817Ssaidi@eecs.umich.edu 313817Ssaidi@eecs.umich.edu#if FULL_SYSTEM 323817Ssaidi@eecs.umich.edu#include "sim/system.hh" 333817Ssaidi@eecs.umich.edu#else 342650Ssaidi@eecs.umich.edu#include "sim/process.hh" 353817Ssaidi@eecs.umich.edu#endif 363817Ssaidi@eecs.umich.edu#include "sim/root.hh" 373817Ssaidi@eecs.umich.edu 383817Ssaidi@eecs.umich.edu#include "cpu/o3/alpha_dyn_inst.hh" 393894Shsul@eecs.umich.edu#include "cpu/o3/alpha_impl.hh" 402650Ssaidi@eecs.umich.edu#include "cpu/o3/cpu.hh" 412650Ssaidi@eecs.umich.edu#include "cpu/exec_context.hh" 422650Ssaidi@eecs.umich.edu 432982Sstever@eecs.umich.eduusing namespace std; 443894Shsul@eecs.umich.edu 453894Shsul@eecs.umich.eduBaseFullCPU::BaseFullCPU(Params ¶ms) 463894Shsul@eecs.umich.edu : BaseCPU(¶ms), cpu_id(0) 473894Shsul@eecs.umich.edu{ 483894Shsul@eecs.umich.edu} 493894Shsul@eecs.umich.edu 502650Ssaidi@eecs.umich.edutemplate <class Impl> 513894Shsul@eecs.umich.eduFullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c) 523894Shsul@eecs.umich.edu : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c) 533894Shsul@eecs.umich.edu{ 543894Shsul@eecs.umich.edu} 552650Ssaidi@eecs.umich.edu 563894Shsul@eecs.umich.edutemplate <class Impl> 573894Shsul@eecs.umich.eduvoid 583894Shsul@eecs.umich.eduFullO3CPU<Impl>::TickEvent::process() 593894Shsul@eecs.umich.edu{ 603894Shsul@eecs.umich.edu cpu->tick(); 613894Shsul@eecs.umich.edu} 623894Shsul@eecs.umich.edu 633894Shsul@eecs.umich.edutemplate <class Impl> 643894Shsul@eecs.umich.educonst char * 653894Shsul@eecs.umich.eduFullO3CPU<Impl>::TickEvent::description() 663894Shsul@eecs.umich.edu{ 672650Ssaidi@eecs.umich.edu return "FullO3CPU tick event"; 683894Shsul@eecs.umich.edu} 693894Shsul@eecs.umich.edu 703894Shsul@eecs.umich.edu//Call constructor to all the pipeline stages here 713894Shsul@eecs.umich.edutemplate <class Impl> 723894Shsul@eecs.umich.eduFullO3CPU<Impl>::FullO3CPU(Params ¶ms) 733894Shsul@eecs.umich.edu#if FULL_SYSTEM 743894Shsul@eecs.umich.edu : BaseFullCPU(params), 753894Shsul@eecs.umich.edu#else 763894Shsul@eecs.umich.edu : BaseFullCPU(params), 773894Shsul@eecs.umich.edu#endif // FULL_SYSTEM 783894Shsul@eecs.umich.edu tickEvent(this), 793894Shsul@eecs.umich.edu fetch(params), 802650Ssaidi@eecs.umich.edu decode(params), 813894Shsul@eecs.umich.edu rename(params), 823897Shsul@eecs.umich.edu iew(params), 833894Shsul@eecs.umich.edu commit(params), 843894Shsul@eecs.umich.edu 853894Shsul@eecs.umich.edu regFile(params.numPhysIntRegs, params.numPhysFloatRegs), 863827Shsul@eecs.umich.edu 873894Shsul@eecs.umich.edu freeList(TheISA::NumIntRegs, params.numPhysIntRegs, 883894Shsul@eecs.umich.edu TheISA::NumFloatRegs, params.numPhysFloatRegs), 893894Shsul@eecs.umich.edu 903894Shsul@eecs.umich.edu renameMap(TheISA::NumIntRegs, params.numPhysIntRegs, 913894Shsul@eecs.umich.edu TheISA::NumFloatRegs, params.numPhysFloatRegs, 923894Shsul@eecs.umich.edu TheISA::NumMiscRegs, 932650Ssaidi@eecs.umich.edu TheISA::ZeroReg, 943894Shsul@eecs.umich.edu TheISA::ZeroReg + TheISA::NumIntRegs), 953894Shsul@eecs.umich.edu 962650Ssaidi@eecs.umich.edu rob(params.numROBEntries, params.squashWidth), 973894Shsul@eecs.umich.edu 983894Shsul@eecs.umich.edu // What to pass to these time buffers? 993894Shsul@eecs.umich.edu // For now just have these time buffers be pretty big. 1003894Shsul@eecs.umich.edu timeBuffer(5, 5), 1012650Ssaidi@eecs.umich.edu fetchQueue(5, 5), 1023894Shsul@eecs.umich.edu decodeQueue(5, 5), 1033894Shsul@eecs.umich.edu renameQueue(5, 5), 1043894Shsul@eecs.umich.edu iewQueue(5, 5), 1053894Shsul@eecs.umich.edu 1063894Shsul@eecs.umich.edu xc(NULL), 1073894Shsul@eecs.umich.edu 1083894Shsul@eecs.umich.edu globalSeqNum(1), 1093894Shsul@eecs.umich.edu 1103894Shsul@eecs.umich.edu#if FULL_SYSTEM 1113894Shsul@eecs.umich.edu system(params.system), 1123894Shsul@eecs.umich.edu memCtrl(system->memctrl), 1133828Shsul@eecs.umich.edu physmem(system->physmem), 1143894Shsul@eecs.umich.edu itb(params.itb), 1153894Shsul@eecs.umich.edu dtb(params.dtb), 1163894Shsul@eecs.umich.edu mem(params.mem), 1173894Shsul@eecs.umich.edu#else 1183894Shsul@eecs.umich.edu // Hardcoded for a single thread!! 1193894Shsul@eecs.umich.edu mem(params.workload[0]->getMemory()), 1203894Shsul@eecs.umich.edu#endif // FULL_SYSTEM 1213894Shsul@eecs.umich.edu 1223894Shsul@eecs.umich.edu icacheInterface(params.icacheInterface), 1233894Shsul@eecs.umich.edu dcacheInterface(params.dcacheInterface), 1243894Shsul@eecs.umich.edu deferRegistration(params.defReg), 1253894Shsul@eecs.umich.edu numInsts(0), 1263817Ssaidi@eecs.umich.edu funcExeInst(0) 1273894Shsul@eecs.umich.edu{ 1283894Shsul@eecs.umich.edu _status = Idle; 1293897Shsul@eecs.umich.edu 1303894Shsul@eecs.umich.edu#if !FULL_SYSTEM 1313894Shsul@eecs.umich.edu thread.resize(this->number_of_threads); 1323894Shsul@eecs.umich.edu#endif 1333894Shsul@eecs.umich.edu 1343894Shsul@eecs.umich.edu for (int i = 0; i < this->number_of_threads; ++i) { 1353817Ssaidi@eecs.umich.edu#if FULL_SYSTEM 1363894Shsul@eecs.umich.edu assert(i == 0); 1373894Shsul@eecs.umich.edu system->execContexts[i] = 1382650Ssaidi@eecs.umich.edu new ExecContext(this, i, system, itb, dtb, mem); 1392650Ssaidi@eecs.umich.edu 1402650Ssaidi@eecs.umich.edu // initialize CPU, including PC 1412650Ssaidi@eecs.umich.edu TheISA::initCPU(&system->execContexts[i]->regs); 1423817Ssaidi@eecs.umich.edu execContexts.push_back(system->execContexts[i]); 1432650Ssaidi@eecs.umich.edu#else 1442650Ssaidi@eecs.umich.edu if (i < params.workload.size()) { 1453894Shsul@eecs.umich.edu DPRINTF(FullCPU, "FullCPU: Workload[%i]'s starting PC is %#x, " 1463825Ssaidi@eecs.umich.edu "process is %#x", 1473825Ssaidi@eecs.umich.edu i, params.workload[i]->prog_entry, thread[i]); 1483825Ssaidi@eecs.umich.edu thread[i] = new ExecContext(this, i, params.workload[i], i); 1493825Ssaidi@eecs.umich.edu } 1503825Ssaidi@eecs.umich.edu assert(params.workload[i]->getMemory() != NULL); 1513825Ssaidi@eecs.umich.edu assert(mem != NULL); 1523825Ssaidi@eecs.umich.edu execContexts.push_back(thread[i]); 1533825Ssaidi@eecs.umich.edu#endif // !FULL_SYSTEM 1543825Ssaidi@eecs.umich.edu } 1553825Ssaidi@eecs.umich.edu 1563825Ssaidi@eecs.umich.edu // Note that this is a hack so that my code which still uses xc-> will 1573825Ssaidi@eecs.umich.edu // still work. I should remove this eventually 1583825Ssaidi@eecs.umich.edu#if FULL_SYSTEM 1593825Ssaidi@eecs.umich.edu xc = system->execContexts[0]; 1603825Ssaidi@eecs.umich.edu#else 1613825Ssaidi@eecs.umich.edu xc = thread[0]; 1623825Ssaidi@eecs.umich.edu#endif 1633825Ssaidi@eecs.umich.edu 1642650Ssaidi@eecs.umich.edu // The stages also need their CPU pointer setup. However this must be 1653825Ssaidi@eecs.umich.edu // done at the upper level CPU because they have pointers to the upper 1663825Ssaidi@eecs.umich.edu // level CPU, and not this FullO3CPU. 1673825Ssaidi@eecs.umich.edu 1683825Ssaidi@eecs.umich.edu // Give each of the stages the time buffer they will use. 1692650Ssaidi@eecs.umich.edu fetch.setTimeBuffer(&timeBuffer); 1703825Ssaidi@eecs.umich.edu decode.setTimeBuffer(&timeBuffer); 1713825Ssaidi@eecs.umich.edu rename.setTimeBuffer(&timeBuffer); 1722650Ssaidi@eecs.umich.edu iew.setTimeBuffer(&timeBuffer); 1732650Ssaidi@eecs.umich.edu commit.setTimeBuffer(&timeBuffer); 1743817Ssaidi@eecs.umich.edu 1753894Shsul@eecs.umich.edu // Also setup each of the stages' queues. 1763894Shsul@eecs.umich.edu fetch.setFetchQueue(&fetchQueue); 1773894Shsul@eecs.umich.edu decode.setFetchQueue(&fetchQueue); 1783894Shsul@eecs.umich.edu decode.setDecodeQueue(&decodeQueue); 1793894Shsul@eecs.umich.edu rename.setDecodeQueue(&decodeQueue); 1803894Shsul@eecs.umich.edu rename.setRenameQueue(&renameQueue); 1813817Ssaidi@eecs.umich.edu iew.setRenameQueue(&renameQueue); 1823817Ssaidi@eecs.umich.edu iew.setIEWQueue(&iewQueue); 1833817Ssaidi@eecs.umich.edu commit.setIEWQueue(&iewQueue); 1842650Ssaidi@eecs.umich.edu commit.setRenameQueue(&renameQueue); 1852651Ssaidi@eecs.umich.edu 1862680Sktlim@umich.edu // Setup the rename map for whichever stages need it. 1872651Ssaidi@eecs.umich.edu rename.setRenameMap(&renameMap); 1882651Ssaidi@eecs.umich.edu iew.setRenameMap(&renameMap); 1892651Ssaidi@eecs.umich.edu 1902651Ssaidi@eecs.umich.edu // Setup the free list for whichever stages need it. 1912651Ssaidi@eecs.umich.edu rename.setFreeList(&freeList); 1922680Sktlim@umich.edu renameMap.setFreeList(&freeList); 1932651Ssaidi@eecs.umich.edu 1943888Ssaidi@eecs.umich.edu // Setup the ROB for whichever stages need it. 1953888Ssaidi@eecs.umich.edu commit.setROB(&rob); 1963888Ssaidi@eecs.umich.edu} 1973888Ssaidi@eecs.umich.edu 1983890Ssaidi@eecs.umich.edutemplate <class Impl> 1993894Shsul@eecs.umich.eduFullO3CPU<Impl>::~FullO3CPU() 2003888Ssaidi@eecs.umich.edu{ 2013888Ssaidi@eecs.umich.edu} 2023888Ssaidi@eecs.umich.edu 2033888Ssaidi@eecs.umich.edutemplate <class Impl> 2043888Ssaidi@eecs.umich.eduvoid 2053894Shsul@eecs.umich.eduFullO3CPU<Impl>::fullCPURegStats() 2063888Ssaidi@eecs.umich.edu{ 2073890Ssaidi@eecs.umich.edu // Register any of the FullCPU's stats here. 2083888Ssaidi@eecs.umich.edu} 2093888Ssaidi@eecs.umich.edu 2102651Ssaidi@eecs.umich.edutemplate <class Impl> 2112651Ssaidi@eecs.umich.eduvoid 2122651Ssaidi@eecs.umich.eduFullO3CPU<Impl>::tick() 2132680Sktlim@umich.edu{ 2142651Ssaidi@eecs.umich.edu DPRINTF(FullCPU, "\n\nFullCPU: Ticking main, FullO3CPU.\n"); 2153891Ssaidi@eecs.umich.edu 2163891Ssaidi@eecs.umich.edu //Tick each of the stages if they're actually running. 2173891Ssaidi@eecs.umich.edu //Will want to figure out a way to unschedule itself if they're all 2183891Ssaidi@eecs.umich.edu //going to be idle for a long time. 2193891Ssaidi@eecs.umich.edu fetch.tick(); 2203894Shsul@eecs.umich.edu 2213891Ssaidi@eecs.umich.edu decode.tick(); 2223891Ssaidi@eecs.umich.edu 2233891Ssaidi@eecs.umich.edu rename.tick(); 2243891Ssaidi@eecs.umich.edu 2253891Ssaidi@eecs.umich.edu iew.tick(); 2263894Shsul@eecs.umich.edu 2273891Ssaidi@eecs.umich.edu commit.tick(); 2283891Ssaidi@eecs.umich.edu 2293891Ssaidi@eecs.umich.edu // Now advance the time buffers, unless the stage is stalled. 2303891Ssaidi@eecs.umich.edu timeBuffer.advance(); 2312651Ssaidi@eecs.umich.edu 2322650Ssaidi@eecs.umich.edu fetchQueue.advance(); 233 decodeQueue.advance(); 234 renameQueue.advance(); 235 iewQueue.advance(); 236 237 if (_status == Running && !tickEvent.scheduled()) 238 tickEvent.schedule(curTick + 1); 239} 240 241template <class Impl> 242void 243FullO3CPU<Impl>::init() 244{ 245 if(!deferRegistration) 246 { 247 this->registerExecContexts(); 248 249 // Need to do a copy of the xc->regs into the CPU's regfile so 250 // that it can start properly. 251#if FULL_SYSTEM 252 ExecContext *src_xc = system->execContexts[0]; 253#else 254 ExecContext *src_xc = thread[0]; 255#endif 256 // First loop through the integer registers. 257 for (int i = 0; i < TheISA::NumIntRegs; ++i) 258 { 259 regFile.intRegFile[i] = src_xc->regs.intRegFile[i]; 260 } 261 262 // Then loop through the floating point registers. 263 for (int i = 0; i < TheISA::NumFloatRegs; ++i) 264 { 265 regFile.floatRegFile[i].d = src_xc->regs.floatRegFile.d[i]; 266 regFile.floatRegFile[i].q = src_xc->regs.floatRegFile.q[i]; 267 } 268 269 // Then loop through the misc registers. 270 regFile.miscRegs.fpcr = src_xc->regs.miscRegs.fpcr; 271 regFile.miscRegs.uniq = src_xc->regs.miscRegs.uniq; 272 regFile.miscRegs.lock_flag = src_xc->regs.miscRegs.lock_flag; 273 regFile.miscRegs.lock_addr = src_xc->regs.miscRegs.lock_addr; 274 275 // Then finally set the PC and the next PC. 276 regFile.pc = src_xc->regs.pc; 277 regFile.npc = src_xc->regs.npc; 278 } 279} 280 281template <class Impl> 282void 283FullO3CPU<Impl>::activateContext(int thread_num, int delay) 284{ 285 // Needs to set each stage to running as well. 286 287 scheduleTickEvent(delay); 288 289 _status = Running; 290} 291 292template <class Impl> 293void 294FullO3CPU<Impl>::suspendContext(int thread_num) 295{ 296 panic("suspendContext unimplemented!"); 297} 298 299template <class Impl> 300void 301FullO3CPU<Impl>::deallocateContext(int thread_num) 302{ 303 panic("deallocateContext unimplemented!"); 304} 305 306template <class Impl> 307void 308FullO3CPU<Impl>::haltContext(int thread_num) 309{ 310 panic("haltContext unimplemented!"); 311} 312 313template <class Impl> 314void 315FullO3CPU<Impl>::switchOut() 316{ 317 panic("FullO3CPU does not have a switch out function.\n"); 318} 319 320template <class Impl> 321void 322FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU) 323{ 324 BaseCPU::takeOverFrom(oldCPU); 325 326 assert(!tickEvent.scheduled()); 327 328 // Set all status's to active, schedule the 329 // CPU's tick event. 330 for (int i = 0; i < execContexts.size(); ++i) { 331 ExecContext *xc = execContexts[i]; 332 if (xc->status() == ExecContext::Active && _status != Running) { 333 _status = Running; 334 tickEvent.schedule(curTick); 335 } 336 } 337} 338 339template <class Impl> 340InstSeqNum 341FullO3CPU<Impl>::getAndIncrementInstSeq() 342{ 343 // Hopefully this works right. 344 return globalSeqNum++; 345} 346 347template <class Impl> 348uint64_t 349FullO3CPU<Impl>::readIntReg(int reg_idx) 350{ 351 return regFile.readIntReg(reg_idx); 352} 353 354template <class Impl> 355float 356FullO3CPU<Impl>::readFloatRegSingle(int reg_idx) 357{ 358 return regFile.readFloatRegSingle(reg_idx); 359} 360 361template <class Impl> 362double 363FullO3CPU<Impl>::readFloatRegDouble(int reg_idx) 364{ 365 return regFile.readFloatRegDouble(reg_idx); 366} 367 368template <class Impl> 369uint64_t 370FullO3CPU<Impl>::readFloatRegInt(int reg_idx) 371{ 372 return regFile.readFloatRegInt(reg_idx); 373} 374 375template <class Impl> 376void 377FullO3CPU<Impl>::setIntReg(int reg_idx, uint64_t val) 378{ 379 regFile.setIntReg(reg_idx, val); 380} 381 382template <class Impl> 383void 384FullO3CPU<Impl>::setFloatRegSingle(int reg_idx, float val) 385{ 386 regFile.setFloatRegSingle(reg_idx, val); 387} 388 389template <class Impl> 390void 391FullO3CPU<Impl>::setFloatRegDouble(int reg_idx, double val) 392{ 393 regFile.setFloatRegDouble(reg_idx, val); 394} 395 396template <class Impl> 397void 398FullO3CPU<Impl>::setFloatRegInt(int reg_idx, uint64_t val) 399{ 400 regFile.setFloatRegInt(reg_idx, val); 401} 402 403template <class Impl> 404uint64_t 405FullO3CPU<Impl>::readPC() 406{ 407 return regFile.readPC(); 408} 409 410template <class Impl> 411void 412FullO3CPU<Impl>::setNextPC(uint64_t val) 413{ 414 regFile.setNextPC(val); 415} 416 417template <class Impl> 418void 419FullO3CPU<Impl>::setPC(Addr new_PC) 420{ 421 regFile.setPC(new_PC); 422} 423 424template <class Impl> 425void 426FullO3CPU<Impl>::addInst(DynInstPtr &inst) 427{ 428 instList.push_back(inst); 429} 430 431template <class Impl> 432void 433FullO3CPU<Impl>::instDone() 434{ 435 // Keep an instruction count. 436 numInsts++; 437 438 // Check for instruction-count-based events. 439 comInstEventQueue[0]->serviceEvents(numInsts); 440} 441 442template <class Impl> 443void 444FullO3CPU<Impl>::removeBackInst(DynInstPtr &inst) 445{ 446 DynInstPtr inst_to_delete; 447 448 // Walk through the instruction list, removing any instructions 449 // that were inserted after the given instruction, inst. 450 while (instList.back() != inst) 451 { 452 assert(!instList.empty()); 453 454 // Obtain the pointer to the instruction. 455 inst_to_delete = instList.back(); 456 457 DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n", 458 inst_to_delete->seqNum, inst_to_delete->readPC()); 459 460 // Remove the instruction from the list. 461 instList.pop_back(); 462 463 // Mark it as squashed. 464 inst_to_delete->setSquashed(); 465 } 466} 467 468template <class Impl> 469void 470FullO3CPU<Impl>::removeFrontInst(DynInstPtr &inst) 471{ 472 DynInstPtr inst_to_remove; 473 474 // The front instruction should be the same one being asked to be removed. 475 assert(instList.front() == inst); 476 477 // Remove the front instruction. 478 inst_to_remove = inst; 479 instList.pop_front(); 480 481 DPRINTF(FullCPU, "FullCPU: Removing committed instruction %#x, PC %#x\n", 482 inst_to_remove, inst_to_remove->readPC()); 483} 484 485template <class Impl> 486void 487FullO3CPU<Impl>::removeInstsNotInROB() 488{ 489 DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction " 490 "list.\n"); 491 492 DynInstPtr rob_tail = rob.readTailInst(); 493 494 removeBackInst(rob_tail); 495} 496 497template <class Impl> 498void 499FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num) 500{ 501 DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction " 502 "list.\n"); 503 504 DynInstPtr inst_to_delete; 505 506 while (instList.back()->seqNum > seq_num) { 507 assert(!instList.empty()); 508 509 // Obtain the pointer to the instruction. 510 inst_to_delete = instList.back(); 511 512 DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n", 513 inst_to_delete->seqNum, inst_to_delete->readPC()); 514 515 // Remove the instruction from the list. 516 instList.back() = NULL; 517 instList.pop_back(); 518 519 // Mark it as squashed. 520 inst_to_delete->setSquashed(); 521 } 522 523} 524 525template <class Impl> 526void 527FullO3CPU<Impl>::removeAllInsts() 528{ 529 instList.clear(); 530} 531 532template <class Impl> 533void 534FullO3CPU<Impl>::dumpInsts() 535{ 536 int num = 0; 537 typename list<DynInstPtr>::iterator inst_list_it = instList.begin(); 538 539 while (inst_list_it != instList.end()) 540 { 541 cprintf("Instruction:%i\nPC:%#x\nSN:%lli\nIssued:%i\nSquashed:%i\n\n", 542 num, (*inst_list_it)->readPC(), (*inst_list_it)->seqNum, 543 (*inst_list_it)->isIssued(), (*inst_list_it)->isSquashed()); 544 inst_list_it++; 545 ++num; 546 } 547} 548 549template <class Impl> 550void 551FullO3CPU<Impl>::wakeDependents(DynInstPtr &inst) 552{ 553 iew.wakeDependents(inst); 554} 555 556// Forward declaration of FullO3CPU. 557template class FullO3CPU<AlphaSimpleImpl>; 558