@@ -81,6 +81,7 @@ MBTB::MBTB(const Params &p)
8181 numEntries (p.numEntries ),
8282 numWays (p.numWays ),
8383 tagBits (p.tagBits ),
84+ usingBasetable (p.usingMbtbBaseEiterTage ),
8485 btbStats (this , p.numWays )
8586{
8687 // MBTB doesn't support ahead-pipelined stages
@@ -356,7 +357,7 @@ MBTB::lookupSingleBlock(Addr block_pc)
356357 for (auto &way : btb_set) {
357358 if (way.valid && way.tag == current_tag) {
358359 res.push_back (way);
359- way.tick = curTick (); // Update timestamp for MRU
360+ way.tick = curTick (); // Update timestamp for MRU
360361 std::make_heap (target_mru[btb_idx].begin (), target_mru[btb_idx].end (), older ());
361362 }
362363 }
@@ -688,12 +689,44 @@ MBTB::update(const FetchStream &stream)
688689 // 1. Check prediction hit status, for stats recording
689690 checkPredictionHit (stream,
690691 std::static_pointer_cast<BTBMeta>(stream.predMetas [getComponentIdx ()]).get ());
692+ if (!usingBasetable) {
693+ // only update btb entry for control squash T-> NT or NT -> T
694+ if (stream.squashType == SQUASH_CTRL) {
695+ warn_if (stream.exeBranchInfo .pc > stream.updateEndInstPC , " exeBranchInfo.pc > updateEndInstPC" );
696+ updateBTBEntry (stream.exeBranchInfo , stream);
697+ }
698+ }else {
699+ auto entries_need_update = prepareUpdateEntries (stream);
700+ for (auto &entry : entries_need_update) {
701+ updateBTBEntry (entry, stream);
702+ }
703+ }
704+
705+ }
706+
691707
692- // only update btb entry for control squash T-> NT or NT -> T
693- if (stream.squashType == SQUASH_CTRL) {
694- warn_if (stream.exeBranchInfo .pc > stream.updateEndInstPC , " exeBranchInfo.pc > updateEndInstPC" );
695- updateBTBEntry (stream.exeBranchInfo , stream);
708+ std::vector<BTBEntry>
709+ MBTB::prepareUpdateEntries (const FetchStream &stream) {
710+ auto all_entries = stream.updateBTBEntries ;
711+
712+ // Add potential new BTB entry if it's a btb miss during prediction
713+ if (!stream.updateIsOldEntry ) {
714+ BTBEntry potential_new_entry = stream.updateNewBTBEntry ;
715+ bool new_entry_taken = stream.exeTaken && stream.getControlPC () == potential_new_entry.pc ;
716+ if (!new_entry_taken) {
717+ potential_new_entry.alwaysTaken = false ;
718+ }
719+ all_entries.push_back (potential_new_entry);
696720 }
721+
722+ // Filter: only keep conditional branches that are not always taken
723+ if (getResolvedUpdate ()) {
724+ auto remove_it = std::remove_if (all_entries.begin (), all_entries.end (),
725+ [](const BTBEntry &e) { return !e.resolved ; });
726+ all_entries.erase (remove_it, all_entries.end ());
727+ }
728+
729+ return all_entries;
697730}
698731
699732/* *
0 commit comments