rename_impl.hh revision 1060
16019Shines@cs.fsu.edu#include <list> 26019Shines@cs.fsu.edu 37101Sgblack@eecs.umich.edu#include "cpu/beta_cpu/rename.hh" 47101Sgblack@eecs.umich.edu 57101Sgblack@eecs.umich.edutemplate<class Impl> 67101Sgblack@eecs.umich.eduSimpleRename<Impl>::SimpleRename(Params ¶ms) 77101Sgblack@eecs.umich.edu : iewToRenameDelay(params.iewToRenameDelay), 87101Sgblack@eecs.umich.edu decodeToRenameDelay(params.decodeToRenameDelay), 97101Sgblack@eecs.umich.edu commitToRenameDelay(params.commitToRenameDelay), 107101Sgblack@eecs.umich.edu renameWidth(params.renameWidth), 117101Sgblack@eecs.umich.edu commitWidth(params.commitWidth) 127101Sgblack@eecs.umich.edu{ 137101Sgblack@eecs.umich.edu _status = Idle; 147101Sgblack@eecs.umich.edu} 156019Shines@cs.fsu.edu 166019Shines@cs.fsu.edutemplate<class Impl> 176019Shines@cs.fsu.eduvoid 186019Shines@cs.fsu.eduSimpleRename<Impl>::setCPU(FullCPU *cpu_ptr) 196019Shines@cs.fsu.edu{ 206019Shines@cs.fsu.edu DPRINTF(Rename, "Rename: Setting CPU pointer.\n"); 216019Shines@cs.fsu.edu cpu = cpu_ptr; 226019Shines@cs.fsu.edu} 236019Shines@cs.fsu.edu 246019Shines@cs.fsu.edutemplate<class Impl> 256019Shines@cs.fsu.eduvoid 266019Shines@cs.fsu.eduSimpleRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 276019Shines@cs.fsu.edu{ 286019Shines@cs.fsu.edu DPRINTF(Rename, "Rename: Setting time buffer pointer.\n"); 296019Shines@cs.fsu.edu timeBuffer = tb_ptr; 306019Shines@cs.fsu.edu 316019Shines@cs.fsu.edu // Setup wire to read information from time buffer, from IEW stage. 326019Shines@cs.fsu.edu fromIEW = timeBuffer->getWire(-iewToRenameDelay); 336019Shines@cs.fsu.edu 346019Shines@cs.fsu.edu // Setup wire to read infromation from time buffer, from commit stage. 356019Shines@cs.fsu.edu fromCommit = timeBuffer->getWire(-commitToRenameDelay); 366019Shines@cs.fsu.edu 376019Shines@cs.fsu.edu // Setup wire to write information to previous stages. 386019Shines@cs.fsu.edu toDecode = timeBuffer->getWire(0); 396019Shines@cs.fsu.edu} 406019Shines@cs.fsu.edu 416019Shines@cs.fsu.edutemplate<class Impl> 426019Shines@cs.fsu.eduvoid 436019Shines@cs.fsu.eduSimpleRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) 446019Shines@cs.fsu.edu{ 456019Shines@cs.fsu.edu DPRINTF(Rename, "Rename: Setting rename queue pointer.\n"); 466019Shines@cs.fsu.edu renameQueue = rq_ptr; 476019Shines@cs.fsu.edu 486019Shines@cs.fsu.edu // Setup wire to write information to future stages. 496268Sgblack@eecs.umich.edu toIEW = renameQueue->getWire(0); 506251Sgblack@eecs.umich.edu} 516269Sgblack@eecs.umich.edu 526269Sgblack@eecs.umich.edutemplate<class Impl> 536749Sgblack@eecs.umich.eduvoid 547105Sgblack@eecs.umich.eduSimpleRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr) 556251Sgblack@eecs.umich.edu{ 566251Sgblack@eecs.umich.edu DPRINTF(Rename, "Rename: Setting decode queue pointer.\n"); 576251Sgblack@eecs.umich.edu decodeQueue = dq_ptr; 587105Sgblack@eecs.umich.edu 597105Sgblack@eecs.umich.edu // Setup wire to get information from decode. 607105Sgblack@eecs.umich.edu fromDecode = decodeQueue->getWire(-decodeToRenameDelay); 617105Sgblack@eecs.umich.edu 626251Sgblack@eecs.umich.edu} 637105Sgblack@eecs.umich.edu 646268Sgblack@eecs.umich.edutemplate<class Impl> 656759SAli.Saidi@ARM.comvoid 666251Sgblack@eecs.umich.eduSimpleRename<Impl>::setRenameMap(RenameMap *rm_ptr) 677105Sgblack@eecs.umich.edu{ 686251Sgblack@eecs.umich.edu DPRINTF(Rename, "Rename: Setting rename map pointer.\n"); 696019Shines@cs.fsu.edu renameMap = rm_ptr; 706267Sgblack@eecs.umich.edu} 716267Sgblack@eecs.umich.edu 726267Sgblack@eecs.umich.edutemplate<class Impl> 737101Sgblack@eecs.umich.eduvoid 747101Sgblack@eecs.umich.eduSimpleRename<Impl>::setFreeList(FreeList *fl_ptr) 757101Sgblack@eecs.umich.edu{ 766019Shines@cs.fsu.edu DPRINTF(Rename, "Rename: Setting free list pointer.\n"); 776251Sgblack@eecs.umich.edu freeList = fl_ptr; 786251Sgblack@eecs.umich.edu} 796251Sgblack@eecs.umich.edu 806251Sgblack@eecs.umich.edutemplate<class Impl> 817121Sgblack@eecs.umich.eduvoid 826251Sgblack@eecs.umich.eduSimpleRename<Impl>::dumpHistory() 836251Sgblack@eecs.umich.edu{ 846251Sgblack@eecs.umich.edu typename list<RenameHistory>::iterator buf_it = historyBuffer.begin(); 856019Shines@cs.fsu.edu 866251Sgblack@eecs.umich.edu while (buf_it != historyBuffer.end()) 876019Shines@cs.fsu.edu { 886275Sgblack@eecs.umich.edu cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys " 896275Sgblack@eecs.umich.edu "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg, 906275Sgblack@eecs.umich.edu (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg); 916275Sgblack@eecs.umich.edu 926275Sgblack@eecs.umich.edu buf_it++; 936251Sgblack@eecs.umich.edu } 946019Shines@cs.fsu.edu} 956275Sgblack@eecs.umich.edu 966019Shines@cs.fsu.edutemplate<class Impl> 976275Sgblack@eecs.umich.eduvoid 986019Shines@cs.fsu.eduSimpleRename<Impl>::block() 996251Sgblack@eecs.umich.edu{ 1007121Sgblack@eecs.umich.edu DPRINTF(Rename, "Rename: Blocking.\n"); 1016019Shines@cs.fsu.edu // Set status to Blocked. 1026251Sgblack@eecs.umich.edu _status = Blocked; 1036251Sgblack@eecs.umich.edu 1046019Shines@cs.fsu.edu // Add the current inputs onto the skid buffer, so they can be 1056251Sgblack@eecs.umich.edu // reprocessed when this stage unblocks. 1066019Shines@cs.fsu.edu skidBuffer.push(*fromDecode); 1077105Sgblack@eecs.umich.edu 1086019Shines@cs.fsu.edu // Note that this stage only signals previous stages to stall when 1097105Sgblack@eecs.umich.edu // it is the cause of the stall originates at this stage. Otherwise 1107105Sgblack@eecs.umich.edu // the previous stages are expected to check all possible stall signals. 1117105Sgblack@eecs.umich.edu} 1126019Shines@cs.fsu.edu 1136019Shines@cs.fsu.edutemplate<class Impl> 1147105Sgblack@eecs.umich.eduinline void 1157105Sgblack@eecs.umich.eduSimpleRename<Impl>::unblock() 1167105Sgblack@eecs.umich.edu{ 1176019Shines@cs.fsu.edu DPRINTF(Rename, "Rename: Reading instructions out of skid " 1186019Shines@cs.fsu.edu "buffer.\n"); 1196251Sgblack@eecs.umich.edu // Remove the now processed instructions from the skid buffer. 1206019Shines@cs.fsu.edu skidBuffer.pop(); 1217106Sgblack@eecs.umich.edu 1227103Sgblack@eecs.umich.edu // If there's still information in the skid buffer, then 1237103Sgblack@eecs.umich.edu // continue to tell previous stages to stall. They will be 1247103Sgblack@eecs.umich.edu // able to restart once the skid buffer is empty. 1257103Sgblack@eecs.umich.edu if (!skidBuffer.empty()) { 1267103Sgblack@eecs.umich.edu toDecode->renameInfo.stall = true; 1277103Sgblack@eecs.umich.edu } else { 1287103Sgblack@eecs.umich.edu DPRINTF(Rename, "Rename: Done unblocking.\n"); 1297103Sgblack@eecs.umich.edu _status = Running; 1307103Sgblack@eecs.umich.edu } 1317103Sgblack@eecs.umich.edu} 1327103Sgblack@eecs.umich.edu 1337103Sgblack@eecs.umich.edutemplate<class Impl> 1347103Sgblack@eecs.umich.eduvoid 1357103Sgblack@eecs.umich.eduSimpleRename<Impl>::doSquash() 1367106Sgblack@eecs.umich.edu{ 1377106Sgblack@eecs.umich.edu typename list<RenameHistory>::iterator hb_it = historyBuffer.begin(); 1387106Sgblack@eecs.umich.edu typename list<RenameHistory>::iterator delete_it; 1397106Sgblack@eecs.umich.edu 1407106Sgblack@eecs.umich.edu InstSeqNum squashed_seq_num = fromCommit->commitInfo.doneSeqNum; 1417106Sgblack@eecs.umich.edu 1427106Sgblack@eecs.umich.edu#ifdef FULL_SYSTEM 1437106Sgblack@eecs.umich.edu assert(!historyBuffer.empty()); 1447106Sgblack@eecs.umich.edu#else 1457106Sgblack@eecs.umich.edu // After a syscall squashes everything, the history buffer may be empty 1467106Sgblack@eecs.umich.edu // but the ROB may still be squashing instructions. 1477106Sgblack@eecs.umich.edu if (historyBuffer.empty()) { 1487113Sgblack@eecs.umich.edu return; 1497116Sgblack@eecs.umich.edu } 1507106Sgblack@eecs.umich.edu#endif // FULL_SYSTEM 1517106Sgblack@eecs.umich.edu 1527106Sgblack@eecs.umich.edu // Go through the most recent instructions, undoing the mappings 1537106Sgblack@eecs.umich.edu // they did and freeing up the registers. 1547106Sgblack@eecs.umich.edu while ((*hb_it).instSeqNum > squashed_seq_num) 1557106Sgblack@eecs.umich.edu { 1567106Sgblack@eecs.umich.edu DPRINTF(Rename, "Rename: Removing history entry with sequence " 1577106Sgblack@eecs.umich.edu "number %i.\n", (*hb_it).instSeqNum); 1587113Sgblack@eecs.umich.edu 1597113Sgblack@eecs.umich.edu // If it's not simply a place holder, then add the registers. 1607106Sgblack@eecs.umich.edu if (!(*hb_it).placeHolder) { 1617106Sgblack@eecs.umich.edu // Tell the rename map to set the architected register to the 1627106Sgblack@eecs.umich.edu // previous physical register that it was renamed to. 1637106Sgblack@eecs.umich.edu renameMap->setEntry(hb_it->archReg, hb_it->prevPhysReg); 1647106Sgblack@eecs.umich.edu 165 // Put the renamed physical register back on the free list. 166 freeList->addReg(hb_it->newPhysReg); 167 } 168 169 delete_it = hb_it; 170 171 hb_it++; 172 173 historyBuffer.erase(delete_it); 174 } 175} 176 177template<class Impl> 178void 179SimpleRename<Impl>::squash() 180{ 181 DPRINTF(Rename, "Rename: Squashing instructions.\n"); 182 // Set the status to Squashing. 183 _status = Squashing; 184 185 // Clear the skid buffer in case it has any data in it. 186 while (!skidBuffer.empty()) 187 { 188 skidBuffer.pop(); 189 } 190 191 doSquash(); 192} 193 194// In the future, when a SmartPtr is used for DynInst, then this function 195// itself can handle returning the instruction's physical registers to 196// the free list. 197template<class Impl> 198void 199SimpleRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num) 200{ 201 DPRINTF(Rename, "Rename: Removing a committed instruction from the " 202 "history buffer, sequence number %lli.\n", inst_seq_num); 203 typename list<RenameHistory>::iterator hb_it = historyBuffer.end(); 204 205 hb_it--; 206 207 if (hb_it->instSeqNum > inst_seq_num) { 208 DPRINTF(Rename, "Rename: Old sequence number encountered. Ensure " 209 "that a syscall happened recently.\n"); 210 return; 211 } 212 213 for ( ; hb_it->instSeqNum != inst_seq_num; hb_it--) 214 { 215 // Make sure we haven't gone off the end of the list. 216 assert(hb_it != historyBuffer.end()); 217 218 // In theory instructions at the end of the history buffer 219 // should be older than the instruction being removed, which 220 // means they will have a lower sequence number. Also the 221 // instruction being removed from the history really should 222 // be the last instruction in the list, as it is the instruction 223 // that was just committed that is being removed. 224 assert(hb_it->instSeqNum < inst_seq_num); 225 DPRINTF(Rename, "Rename: Committed instruction is not the last " 226 "entry in the history buffer.\n"); 227 } 228 229 if (!(*hb_it).placeHolder) { 230 freeList->addReg(hb_it->prevPhysReg); 231 } 232 233 historyBuffer.erase(hb_it); 234 235} 236 237template<class Impl> 238void 239SimpleRename<Impl>::tick() 240{ 241 // Rename will need to try to rename as many instructions as it 242 // has bandwidth, unless it is blocked. 243 244 // Check if _status is BarrierStall. If so, then check if the number 245 // of free ROB entries is equal to the number of total ROB entries. 246 // Once equal then wake this stage up. Set status to unblocking maybe. 247 248 if (_status != Blocked && _status != Squashing) { 249 DPRINTF(Rename, "Rename: Status is not blocked, will attempt to " 250 "run stage.\n"); 251 // Make sure that the skid buffer has something in it if the 252 // status is unblocking. 253 assert(_status == Unblocking ? !skidBuffer.empty() : 1); 254 255 rename(); 256 257 // If the status was unblocking, then instructions from the skid 258 // buffer were used. Remove those instructions and handle 259 // the rest of unblocking. 260 if (_status == Unblocking) { 261 unblock(); 262 } 263 } else if (_status == Blocked) { 264 // If stage is blocked and still receiving valid instructions, 265 // make sure to store them in the skid buffer. 266 if (fromDecode->insts[0] != NULL) { 267 268 block(); 269 270 // Continue to tell previous stage to stall. 271 toDecode->renameInfo.stall = true; 272 } 273 274 if (!fromIEW->iewInfo.stall && 275 !fromCommit->commitInfo.stall && 276 fromCommit->commitInfo.freeROBEntries != 0 && 277 fromIEW->iewInfo.freeIQEntries != 0) { 278 279 // Need to be sure to check all blocking conditions above. 280 // If they have cleared, then start unblocking. 281 DPRINTF(Rename, "Rename: Stall signals cleared, going to " 282 "unblock.\n"); 283 _status = Unblocking; 284 285 // Continue to tell previous stage to block until this stage 286 // is done unblocking. 287 toDecode->renameInfo.stall = true; 288 } else { 289 // Otherwise no conditions have changed. Tell previous 290 // stage to continue blocking. 291 toDecode->renameInfo.stall = true; 292 } 293 294 if (fromCommit->commitInfo.squash || 295 fromCommit->commitInfo.robSquashing) { 296 squash(); 297 return; 298 } 299 } else if (_status == Squashing) { 300 if (fromCommit->commitInfo.squash) { 301 squash(); 302 } else if (!fromCommit->commitInfo.squash && 303 !fromCommit->commitInfo.robSquashing) { 304 305 DPRINTF(Rename, "Rename: Done squashing, going to running.\n"); 306 _status = Running; 307 } else { 308 doSquash(); 309 } 310 } 311 312 // Ugly code, revamp all of the tick() functions eventually. 313 if (fromCommit->commitInfo.doneSeqNum != 0 && _status != Squashing) { 314 removeFromHistory(fromCommit->commitInfo.doneSeqNum); 315 } 316 317 // Perhaps put this outside of this function, since this will 318 // happen regardless of whether or not the stage is blocked or 319 // squashing. 320 // Read from the time buffer any necessary data. 321 // Read registers that are freed, and add them to the freelist. 322 // This is unnecessary due to the history buffer (assuming the history 323 // buffer works properly). 324/* 325 while(!fromCommit->commitInfo.freeRegs.empty()) 326 { 327 PhysRegIndex freed_reg = fromCommit->commitInfo.freeRegs.back(); 328 DPRINTF(Rename, "Rename: Adding freed register %i to freelist.\n", 329 (int)freed_reg); 330 freeList->addReg(freed_reg); 331 332 fromCommit->commitInfo.freeRegs.pop_back(); 333 } 334*/ 335 336} 337 338template<class Impl> 339void 340SimpleRename<Impl>::rename() 341{ 342 // Check if any of the stages ahead of rename are telling rename 343 // to squash. The squash() function will also take care of fixing up 344 // the rename map and the free list. 345 if (fromCommit->commitInfo.squash || 346 fromCommit->commitInfo.robSquashing) { 347 squash(); 348 return; 349 } 350 351 // Check if time buffer is telling this stage to stall. 352 if (fromIEW->iewInfo.stall || 353 fromCommit->commitInfo.stall) { 354 DPRINTF(Rename, "Rename: Receiving signal from IEW/Commit to " 355 "stall.\n"); 356 block(); 357 return; 358 } 359 360 // Check if the current status is squashing. If so, set its status 361 // to running and resume execution the next cycle. 362 if (_status == Squashing) { 363 DPRINTF(Rename, "Rename: Done squashing.\n"); 364 _status = Running; 365 return; 366 } 367 368 // Check the decode queue to see if instructions are available. 369 // If there are no available instructions to rename, then do nothing. 370 // Or, if the stage is currently unblocking, then go ahead and run it. 371 if (fromDecode->insts[0] == NULL && _status != Unblocking) { 372 DPRINTF(Rename, "Rename: Nothing to do, breaking out early.\n"); 373 // Should I change status to idle? 374 return; 375 } 376 377 DynInst *inst; 378 unsigned num_inst = 0; 379 380 bool insts_available = _status == Unblocking ? 381 skidBuffer.front().insts[num_inst] != NULL : 382 fromDecode->insts[num_inst] != NULL; 383 384 typename SimpleRenameMap::RenameInfo rename_result; 385 386 unsigned num_src_regs; 387 unsigned num_dest_regs; 388 389 // Will have to do a different calculation for the number of free 390 // entries. Number of free entries recorded on this cycle - 391 // renameWidth * renameToDecodeDelay 392 // Can I avoid a multiply? 393 unsigned free_rob_entries = 394 fromCommit->commitInfo.freeROBEntries - iewToRenameDelay; 395 DPRINTF(Rename, "Rename: ROB has %d free entries.\n", 396 free_rob_entries); 397 unsigned free_iq_entries = 398 fromIEW->iewInfo.freeIQEntries - iewToRenameDelay; 399 400 // Check if there's any space left. 401 if (free_rob_entries == 0 || free_iq_entries == 0) { 402 DPRINTF(Rename, "Rename: Blocking due to no free ROB or IQ " 403 "entries.\n" 404 "Rename: ROB has %d free entries.\n" 405 "Rename: IQ has %d free entries.\n", 406 free_rob_entries, 407 free_iq_entries); 408 block(); 409 // Tell previous stage to stall. 410 toDecode->renameInfo.stall = true; 411 412 return; 413 } 414 415 unsigned min_iq_rob = min(free_rob_entries, free_iq_entries); 416 unsigned num_insts_to_rename = min(min_iq_rob, renameWidth); 417 418 while (insts_available && 419 num_inst < num_insts_to_rename) { 420 DPRINTF(Rename, "Rename: Sending instructions to iew.\n"); 421 422 // Get the next instruction either from the skid buffer or the 423 // decode queue. 424 inst = _status == Unblocking ? skidBuffer.front().insts[num_inst] : 425 fromDecode->insts[num_inst]; 426 427 DPRINTF(Rename, "Rename: Processing instruction %i with PC %#x.\n", 428 inst, inst->readPC()); 429 430 // If it's a trap instruction, then it needs to wait here within 431 // rename until the ROB is empty. Needs a way to detect that the 432 // ROB is empty. Maybe an event? 433 // Would be nice if it could be avoided putting this into a 434 // specific stage and instead just put it into the AlphaFullCPU. 435 // Might not really be feasible though... 436 // (EXCB, TRAPB) 437 if (inst->isSerializing()) { 438 panic("Rename: Serializing instruction encountered.\n"); 439 DPRINTF(Rename, "Rename: Serializing instruction " 440 "encountered.\n"); 441 block(); 442 443 // Change status over to BarrierStall so that other stages know 444 // what this is blocked on. 445 _status = BarrierStall; 446 447 // Tell the previous stage to stall. 448 toDecode->renameInfo.stall = true; 449 450 break; 451 } 452 453 // Make sure there's enough room in the ROB and the IQ. 454 // This doesn't really need to be done dynamically; consider 455 // moving outside of this function. 456 if (free_rob_entries == 0 || free_iq_entries == 0) { 457 DPRINTF(Rename, "Rename: Blocking due to lack of ROB or IQ " 458 "entries.\n"); 459 // Call some sort of function to handle all the setup of being 460 // blocked. 461 block(); 462 463 // Not really sure how to schedule an event properly, but an 464 // event must be scheduled such that upon freeing a ROB entry, 465 // this stage will restart up. Perhaps add in a ptr to an Event 466 // within the ROB that will be able to execute that Event 467 // if a free register is added to the freelist. 468 469 // Tell the previous stage to stall. 470 toDecode->renameInfo.stall = true; 471 472 break; 473 } 474 475 // Temporary variables to hold number of source and destination regs. 476 num_src_regs = inst->numSrcRegs(); 477 num_dest_regs = inst->numDestRegs(); 478 479 // Check here to make sure there are enough destination registers 480 // to rename to. Otherwise block. 481 if (renameMap->numFreeEntries() < num_dest_regs) 482 { 483 DPRINTF(Rename, "Rename: Blocking due to lack of free " 484 "physical registers to rename to.\n"); 485 // Call function to handle blocking. 486 block(); 487 488 // Need some sort of event based on a register being freed. 489 490 // Tell the previous stage to stall. 491 toDecode->renameInfo.stall = true; 492 493 // Break out of rename loop. 494 break; 495 } 496 497 // Get the architectual register numbers from the source and 498 // destination operands, and redirect them to the right register. 499 // Will need to mark dependencies though. 500 for (int src_idx = 0; src_idx < num_src_regs; src_idx++) 501 { 502 RegIndex src_reg = inst->srcRegIdx(src_idx); 503 504 // Look up the source registers to get the phys. register they've 505 // been renamed to, and set the sources to those registers. 506 RegIndex renamed_reg = renameMap->lookup(src_reg); 507 508 DPRINTF(Rename, "Rename: Looking up arch reg %i, got " 509 "physical reg %i.\n", (int)src_reg, (int)renamed_reg); 510 511 inst->renameSrcReg(src_idx, renamed_reg); 512 513 // Either incorporate it into the info passed back, 514 // or make another function call to see if that register is 515 // ready or not. 516 if (renameMap->isReady(renamed_reg)) { 517 DPRINTF(Rename, "Rename: Register is ready.\n"); 518 519 inst->markSrcRegReady(src_idx); 520 } 521 } 522 523 // Rename the destination registers. 524 for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) 525 { 526 RegIndex dest_reg = inst->destRegIdx(dest_idx); 527 528 // Get the physical register that the destination will be 529 // renamed to. 530 rename_result = renameMap->rename(dest_reg); 531 532 DPRINTF(Rename, "Rename: Renaming arch reg %i to physical " 533 "register %i.\n", (int)dest_reg, 534 (int)rename_result.first); 535 536 // Record the rename information so that a history can be kept. 537 RenameHistory hb_entry(inst->seqNum, dest_reg, 538 rename_result.first, 539 rename_result.second); 540 541 historyBuffer.push_front(hb_entry); 542 543 DPRINTF(Rename, "Rename: Adding instruction to history buffer, " 544 "sequence number %lli.\n", inst->seqNum); 545 546 // Tell the instruction to rename the appropriate destination 547 // register (dest_idx) to the new physical register 548 // (rename_result.first), and record the previous physical 549 // register that the same logical register was renamed to 550 // (rename_result.second). 551 inst->renameDestReg(dest_idx, 552 rename_result.first, 553 rename_result.second); 554 } 555 556 // If it's an instruction with no destination registers, then put 557 // a placeholder within the history buffer. It might be better 558 // to not put it in the history buffer at all (other than branches, 559 // which always need at least a place holder), and differentiate 560 // between instructions with and without destination registers 561 // when getting from commit the instructions that committed. 562 if (num_dest_regs == 0) { 563 RenameHistory hb_entry(inst->seqNum); 564 565 historyBuffer.push_front(hb_entry); 566 567 DPRINTF(Rename, "Rename: Adding placeholder instruction to " 568 "history buffer, sequence number %lli.\n", 569 inst->seqNum); 570 } 571 572 // Put instruction in rename queue. 573 toIEW->insts[num_inst] = inst; 574 575 // Decrease the number of free ROB and IQ entries. 576 --free_rob_entries; 577 --free_iq_entries; 578 579 // Increment which instruction we're on. 580 ++num_inst; 581 582 // Check whether or not there are instructions available. 583 // Either need to check within the skid buffer, or the decode 584 // queue, depending if this stage is unblocking or not. 585 // Hmm, dangerous check. Can touch memory not allocated. Might 586 // be better to just do check at beginning of loop. Or better 587 // yet actually pass the number of instructions issued. 588 insts_available = _status == Unblocking ? 589 skidBuffer.front().insts[num_inst] != NULL : 590 fromDecode->insts[num_inst] != NULL; 591 } 592 593} 594