rob_impl.hh revision 13831
11689SN/A/* 213590Srekai.gonzalezalberquilla@arm.com * Copyright (c) 2012 ARM Limited 39920Syasuko.eckert@amd.com * All rights reserved 47944SGiacomo.Gabrielli@arm.com * 57944SGiacomo.Gabrielli@arm.com * The license below extends only to copyright in the software and shall 67944SGiacomo.Gabrielli@arm.com * not be construed as granting a license to any other intellectual 77944SGiacomo.Gabrielli@arm.com * property including but not limited to intellectual property relating 87944SGiacomo.Gabrielli@arm.com * to a hardware implementation of the functionality of the software 97944SGiacomo.Gabrielli@arm.com * licensed hereunder. You may use the software subject to the license 107944SGiacomo.Gabrielli@arm.com * terms below provided that you ensure that this notice is replicated 117944SGiacomo.Gabrielli@arm.com * unmodified and in its entirety in all distributions of the software, 127944SGiacomo.Gabrielli@arm.com * modified or unmodified, in source code or in binary form. 137944SGiacomo.Gabrielli@arm.com * 147944SGiacomo.Gabrielli@arm.com * Copyright (c) 2004-2006 The Regents of The University of Michigan 152326SN/A * All rights reserved. 161689SN/A * 171689SN/A * Redistribution and use in source and binary forms, with or without 181689SN/A * modification, are permitted provided that the following conditions are 191689SN/A * met: redistributions of source code must retain the above copyright 201689SN/A * notice, this list of conditions and the following disclaimer; 211689SN/A * redistributions in binary form must reproduce the above copyright 221689SN/A * notice, this list of conditions and the following disclaimer in the 231689SN/A * documentation and/or other materials provided with the distribution; 241689SN/A * neither the name of the copyright holders nor the names of its 251689SN/A * contributors may be used to endorse or promote products derived from 261689SN/A * this software without specific prior written permission. 271689SN/A * 281689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 291689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 301689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 311689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 321689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 331689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 341689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 351689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 361689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 371689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 381689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 391689SN/A * 402665Ssaidi@eecs.umich.edu * Authors: Kevin Lim 412665Ssaidi@eecs.umich.edu * Korey Sewell 422831Sksewell@umich.edu */ 431689SN/A 441689SN/A#ifndef __CPU_O3_ROB_IMPL_HH__ 459944Smatt.horsnell@ARM.com#define __CPU_O3_ROB_IMPL_HH__ 469944Smatt.horsnell@ARM.com 479944Smatt.horsnell@ARM.com#include <list> 482064SN/A 491060SN/A#include "base/logging.hh" 501060SN/A#include "cpu/o3/rob.hh" 5113449Sgabeblack@google.com#include "debug/Fetch.hh" 522292SN/A#include "debug/ROB.hh" 531717SN/A#include "params/DerivO3CPU.hh" 548232Snate@binkert.org 554762Snate@binkert.orgusing namespace std; 566221Snate@binkert.org 574762Snate@binkert.orgtemplate <class Impl> 581060SN/AROB<Impl>::ROB(O3CPU *_cpu, DerivO3CPUParams *params) 598737Skoansin.tan@gmail.com : robPolicy(params->smtROBPolicy), 608737Skoansin.tan@gmail.com cpu(_cpu), 618737Skoansin.tan@gmail.com numEntries(params->numROBEntries), 625529Snate@binkert.org squashWidth(params->squashWidth), 631061SN/A numInstsInROB(0), 6413429Srekai.gonzalezalberquilla@arm.com numThreads(params->numThreads) 655606Snate@binkert.org{ 668581Ssteve.reinhardt@amd.com //Figure out rob policy 678581Ssteve.reinhardt@amd.com if (robPolicy == SMTQueuePolicy::Dynamic) { 681060SN/A //Set Max Entries to Total ROB Capacity 692292SN/A for (ThreadID tid = 0; tid < numThreads; tid++) { 702292SN/A maxEntries[tid] = numEntries; 712292SN/A } 722292SN/A 732292SN/A } else if (robPolicy == SMTQueuePolicy::Partitioned) { 742292SN/A DPRINTF(Fetch, "ROB sharing policy set to Partitioned\n"); 752326SN/A 762292SN/A //@todo:make work if part_amt doesnt divide evenly. 772292SN/A int part_amt = numEntries / numThreads; 782292SN/A 792292SN/A //Divide ROB up evenly 802292SN/A for (ThreadID tid = 0; tid < numThreads; tid++) { 812292SN/A maxEntries[tid] = part_amt; 825336Shines@cs.fsu.edu } 832292SN/A 844873Sstever@eecs.umich.edu } else if (robPolicy == SMTQueuePolicy::Threshold) { 852292SN/A DPRINTF(Fetch, "ROB sharing policy set to Threshold\n"); 862292SN/A 872292SN/A int threshold = params->smtROBThreshold;; 884329Sktlim@umich.edu 895529Snate@binkert.org //Divide up by threshold amount 904329Sktlim@umich.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 914329Sktlim@umich.edu maxEntries[tid] = threshold; 924329Sktlim@umich.edu } 9313561Snikos.nikoleris@arm.com } 942292SN/A 952292SN/A for (ThreadID tid = numThreads; tid < Impl::MaxThreads; tid++) { 962292SN/A maxEntries[tid] = 0; 972292SN/A } 982292SN/A 992292SN/A resetState(); 1005529Snate@binkert.org} 1011060SN/A 1029920Syasuko.eckert@amd.comtemplate <class Impl> 10312109SRekai.GonzalezAlberquilla@arm.comvoid 1049920Syasuko.eckert@amd.comROB<Impl>::resetState() 10512109SRekai.GonzalezAlberquilla@arm.com{ 10612109SRekai.GonzalezAlberquilla@arm.com for (ThreadID tid = 0; tid < Impl::MaxThreads; tid++) { 10713610Sgiacomo.gabrielli@arm.com threadEntries[tid] = 0; 10812109SRekai.GonzalezAlberquilla@arm.com squashIt[tid] = instList[tid].end(); 1091060SN/A squashedSeqNum[tid] = 0; 1101060SN/A doneSquashing[tid] = true; 1111060SN/A } 1122326SN/A numInstsInROB = 0; 1131060SN/A 1141060SN/A // Initialize the "universal" ROB head & tail point to invalid 1151060SN/A // pointers 1161060SN/A head = instList[0].end(); 1172292SN/A tail = instList[0].end(); 11813453Srekai.gonzalezalberquilla@arm.com} 1196221Snate@binkert.org 1206221Snate@binkert.orgtemplate <class Impl> 1211060SN/Astd::string 1221060SN/AROB<Impl>::name() const 1232307SN/A{ 1242292SN/A return cpu->name() + ".rob"; 1252292SN/A} 12613561Snikos.nikoleris@arm.com 1272292SN/Atemplate <class Impl> 1286221Snate@binkert.orgvoid 1296221Snate@binkert.orgROB<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 1302292SN/A{ 1312292SN/A DPRINTF(ROB, "Setting active threads list pointer.\n"); 13213561Snikos.nikoleris@arm.com activeThreads = at_ptr; 1332292SN/A} 1342292SN/A 1352292SN/Atemplate <class Impl> 1362292SN/Avoid 1376221Snate@binkert.orgROB<Impl>::drainSanityCheck() const 1386221Snate@binkert.org{ 1392292SN/A for (ThreadID tid = 0; tid < numThreads; tid++) 1402292SN/A assert(instList[tid].empty()); 1412831Sksewell@umich.edu assert(isEmpty()); 1422292SN/A} 14313561Snikos.nikoleris@arm.com 1442292SN/Atemplate <class Impl> 1452292SN/Avoid 1462292SN/AROB<Impl>::takeOverFrom() 1472292SN/A{ 1482292SN/A resetState(); 1496221Snate@binkert.org} 1506221Snate@binkert.org 1512292SN/Atemplate <class Impl> 1522292SN/Avoid 1532831Sksewell@umich.eduROB<Impl>::resetEntries() 1542292SN/A{ 1552292SN/A if (robPolicy != SMTQueuePolicy::Dynamic || numThreads > 1) { 15613453Srekai.gonzalezalberquilla@arm.com int active_threads = activeThreads->size(); 15713453Srekai.gonzalezalberquilla@arm.com 15813453Srekai.gonzalezalberquilla@arm.com list<ThreadID>::iterator threads = activeThreads->begin(); 1592292SN/A list<ThreadID>::iterator end = activeThreads->end(); 1602292SN/A 1612292SN/A while (threads != end) { 1622292SN/A ThreadID tid = *threads++; 1632292SN/A 1642326SN/A if (robPolicy == SMTQueuePolicy::Partitioned) { 1652348SN/A maxEntries[tid] = numEntries / active_threads; 1662326SN/A } else if (robPolicy == SMTQueuePolicy::Threshold && 1672326SN/A active_threads == 1) { 1682348SN/A maxEntries[tid] = numEntries; 1692292SN/A } 1702292SN/A } 1712292SN/A } 1722292SN/A} 1732292SN/A 1742292SN/Atemplate <class Impl> 1752292SN/Aint 1761060SN/AROB<Impl>::entryAmount(ThreadID num_threads) 1771060SN/A{ 1781061SN/A if (robPolicy == SMTQueuePolicy::Partitioned) { 1791060SN/A return numEntries / num_threads; 1801062SN/A } else { 1811062SN/A return 0; 1822301SN/A } 1831062SN/A} 1841062SN/A 1851062SN/Atemplate <class Impl> 1861062SN/Aint 1871062SN/AROB<Impl>::countInsts() 1881062SN/A{ 1891062SN/A int total = 0; 1901062SN/A 1911062SN/A for (ThreadID tid = 0; tid < numThreads; tid++) 1921062SN/A total += countInsts(tid); 1932301SN/A 1942301SN/A return total; 1952301SN/A} 1962301SN/A 1971062SN/Atemplate <class Impl> 1981062SN/Aint 1991062SN/AROB<Impl>::countInsts(ThreadID tid) 2001062SN/A{ 2011062SN/A return instList[tid].size(); 2021062SN/A} 2031062SN/A 2041062SN/Atemplate <class Impl> 2051062SN/Avoid 2061062SN/AROB<Impl>::insertInst(const DynInstPtr &inst) 2071062SN/A{ 2081062SN/A assert(inst); 2091062SN/A 2101062SN/A robWrites++; 2111062SN/A 2121062SN/A DPRINTF(ROB, "Adding inst PC %s to the ROB.\n", inst->pcState()); 2131062SN/A 2141062SN/A assert(numInstsInROB != numEntries); 2151062SN/A 2161062SN/A ThreadID tid = inst->threadNumber; 2171062SN/A 2181062SN/A instList[tid].push_back(inst); 2191062SN/A 2201062SN/A //Set Up head iterator if this is the 1st instruction in the ROB 2211062SN/A if (numInstsInROB == 0) { 2221062SN/A head = instList[tid].begin(); 2231062SN/A assert((*head) == inst); 2241062SN/A } 2251062SN/A 2261062SN/A //Must Decrement for iterator to actually be valid since __.end() 2271062SN/A //actually points to 1 after the last inst 2281062SN/A tail = instList[tid].end(); 2291062SN/A tail--; 2301062SN/A 2311062SN/A inst->setInROB(); 2321062SN/A 2331062SN/A ++numInstsInROB; 2341062SN/A ++threadEntries[tid]; 2351062SN/A 2361062SN/A assert((*tail) == inst); 2371062SN/A 2381062SN/A DPRINTF(ROB, "[tid:%i] Now has %d instructions.\n", tid, threadEntries[tid]); 2391062SN/A} 2401062SN/A 2411062SN/Atemplate <class Impl> 2421062SN/Avoid 2431062SN/AROB<Impl>::retireHead(ThreadID tid) 2442361SN/A{ 2452326SN/A robWrites++; 2462301SN/A 2472301SN/A assert(numInstsInROB > 0); 2482301SN/A 2492301SN/A // Get the head ROB instruction by copying it and remove it from the list 2502301SN/A InstIt head_it = instList[tid].begin(); 2512301SN/A 2522326SN/A DynInstPtr head_inst = std::move(*head_it); 2532301SN/A instList[tid].erase(head_it); 2542361SN/A 2552326SN/A assert(head_inst->readyToCommit()); 2562307SN/A 2578240Snate@binkert.org DPRINTF(ROB, "[tid:%i] Retiring head instruction, " 2582301SN/A "instruction PC %s, [sn:%llu]\n", tid, head_inst->pcState(), 2592307SN/A head_inst->seqNum); 2602301SN/A 2612301SN/A --numInstsInROB; 2622301SN/A --threadEntries[tid]; 2632301SN/A 2648240Snate@binkert.org head_inst->clearInROB(); 2652301SN/A head_inst->setCommitted(); 2662301SN/A 2672301SN/A //Update "Global" Head of ROB 2682301SN/A updateHead(); 2692301SN/A 2702301SN/A // @todo: A special case is needed if the instruction being 2712301SN/A // retired is the only instruction in the ROB; otherwise the tail 2722326SN/A // iterator will become invalidated. 2734762Snate@binkert.org cpu->removeFrontInst(head_inst); 2748240Snate@binkert.org} 2752301SN/A 2762301SN/Atemplate <class Impl> 2772301SN/Abool 2784762Snate@binkert.orgROB<Impl>::isHeadReady(ThreadID tid) 2792301SN/A{ 2802301SN/A robReads++; 2812301SN/A if (threadEntries[tid] != 0) { 2822301SN/A return instList[tid].front()->readyToCommit(); 2832361SN/A } 2842326SN/A 2852301SN/A return false; 2868240Snate@binkert.org} 2872301SN/A 2882301SN/Atemplate <class Impl> 2892301SN/Abool 2902301SN/AROB<Impl>::canCommit() 2912301SN/A{ 2922980Sgblack@eecs.umich.edu //@todo: set ActiveThreads through ROB or CPU 2932301SN/A list<ThreadID>::iterator threads = activeThreads->begin(); 2942326SN/A list<ThreadID>::iterator end = activeThreads->end(); 2952301SN/A 2962361SN/A while (threads != end) { 2972326SN/A ThreadID tid = *threads++; 2988240Snate@binkert.org 2992301SN/A if (isHeadReady(tid)) { 3002301SN/A return true; 3012301SN/A } 3022326SN/A } 3032727Sktlim@umich.edu 3042326SN/A return false; 3052301SN/A} 3068240Snate@binkert.org 3072301SN/Atemplate <class Impl> 3082301SN/Aunsigned 3092301SN/AROB<Impl>::numFreeEntries() 3102301SN/A{ 3114762Snate@binkert.org return numEntries - numInstsInROB; 3122301SN/A} 3132301SN/A 3142326SN/Atemplate <class Impl> 3152301SN/Aunsigned 3168240Snate@binkert.orgROB<Impl>::numFreeEntries(ThreadID tid) 3172301SN/A{ 3182301SN/A return maxEntries[tid] - threadEntries[tid]; 3192301SN/A} 3202301SN/A 3212326SN/Atemplate <class Impl> 3228240Snate@binkert.orgvoid 3232301SN/AROB<Impl>::doSquash(ThreadID tid) 3242301SN/A{ 3252301SN/A robWrites++; 3262326SN/A DPRINTF(ROB, "[tid:%i] Squashing instructions until [sn:%llu].\n", 3272301SN/A tid, squashedSeqNum[tid]); 3286221Snate@binkert.org 3292292SN/A assert(squashIt[tid] != instList[tid].end()); 3306221Snate@binkert.org 3312292SN/A if ((*squashIt[tid])->seqNum < squashedSeqNum[tid]) { 3327897Shestness@cs.utexas.edu DPRINTF(ROB, "[tid:%i] Done squashing instructions.\n", 3337897Shestness@cs.utexas.edu tid); 3347897Shestness@cs.utexas.edu 3357897Shestness@cs.utexas.edu squashIt[tid] = instList[tid].end(); 3367897Shestness@cs.utexas.edu 3377897Shestness@cs.utexas.edu doneSquashing[tid] = true; 3387897Shestness@cs.utexas.edu return; 3397897Shestness@cs.utexas.edu } 3407897Shestness@cs.utexas.edu 3417897Shestness@cs.utexas.edu bool robTailUpdate = false; 3427897Shestness@cs.utexas.edu 3437897Shestness@cs.utexas.edu for (int numSquashed = 0; 3447897Shestness@cs.utexas.edu numSquashed < squashWidth && 3457897Shestness@cs.utexas.edu squashIt[tid] != instList[tid].end() && 3467897Shestness@cs.utexas.edu (*squashIt[tid])->seqNum > squashedSeqNum[tid]; 3477897Shestness@cs.utexas.edu ++numSquashed) 3487897Shestness@cs.utexas.edu { 3497897Shestness@cs.utexas.edu DPRINTF(ROB, "[tid:%i] Squashing instruction PC %s, seq num %i.\n", 3507897Shestness@cs.utexas.edu (*squashIt[tid])->threadNumber, 3517897Shestness@cs.utexas.edu (*squashIt[tid])->pcState(), 3527897Shestness@cs.utexas.edu (*squashIt[tid])->seqNum); 3537897Shestness@cs.utexas.edu 3547897Shestness@cs.utexas.edu // Mark the instruction as squashed, and ready to commit so that 3557897Shestness@cs.utexas.edu // it can drain out of the pipeline. 3567897Shestness@cs.utexas.edu (*squashIt[tid])->setSquashed(); 3577897Shestness@cs.utexas.edu 35812110SRekai.GonzalezAlberquilla@arm.com (*squashIt[tid])->setCanCommit(); 3597897Shestness@cs.utexas.edu 3607897Shestness@cs.utexas.edu 3617897Shestness@cs.utexas.edu if (squashIt[tid] == instList[tid].begin()) { 3627897Shestness@cs.utexas.edu DPRINTF(ROB, "Reached head of instruction list while " 36312319Sandreas.sandberg@arm.com "squashing.\n"); 36412319Sandreas.sandberg@arm.com 36512319Sandreas.sandberg@arm.com squashIt[tid] = instList[tid].end(); 36612319Sandreas.sandberg@arm.com 36712319Sandreas.sandberg@arm.com doneSquashing[tid] = true; 36812319Sandreas.sandberg@arm.com 36912319Sandreas.sandberg@arm.com return; 37012319Sandreas.sandberg@arm.com } 37112319Sandreas.sandberg@arm.com 37212319Sandreas.sandberg@arm.com InstIt tail_thread = instList[tid].end(); 37312319Sandreas.sandberg@arm.com tail_thread--; 37412319Sandreas.sandberg@arm.com 37512319Sandreas.sandberg@arm.com if ((*squashIt[tid]) == (*tail_thread)) 37612319Sandreas.sandberg@arm.com robTailUpdate = true; 37712319Sandreas.sandberg@arm.com 3787897Shestness@cs.utexas.edu squashIt[tid]--; 3797897Shestness@cs.utexas.edu } 3807897Shestness@cs.utexas.edu 3817897Shestness@cs.utexas.edu 3827897Shestness@cs.utexas.edu // Check if ROB is done squashing. 3837897Shestness@cs.utexas.edu if ((*squashIt[tid])->seqNum <= squashedSeqNum[tid]) { 3847897Shestness@cs.utexas.edu DPRINTF(ROB, "[tid:%i] Done squashing instructions.\n", 3857897Shestness@cs.utexas.edu tid); 3867897Shestness@cs.utexas.edu 3877897Shestness@cs.utexas.edu squashIt[tid] = instList[tid].end(); 38812319Sandreas.sandberg@arm.com 38912319Sandreas.sandberg@arm.com doneSquashing[tid] = true; 39012319Sandreas.sandberg@arm.com } 39112319Sandreas.sandberg@arm.com 39212319Sandreas.sandberg@arm.com if (robTailUpdate) { 3931062SN/A updateTail(); 3941062SN/A } 3951062SN/A} 3961062SN/A 3972307SN/A 3981060SN/Atemplate <class Impl> 3992307SN/Avoid 40013453Srekai.gonzalezalberquilla@arm.comROB<Impl>::updateHead() 4016221Snate@binkert.org{ 4026221Snate@binkert.org InstSeqNum lowest_num = 0; 4032307SN/A bool first_valid = true; 4041060SN/A 4052307SN/A // @todo: set ActiveThreads through ROB or CPU 4062307SN/A list<ThreadID>::iterator threads = activeThreads->begin(); 4072307SN/A list<ThreadID>::iterator end = activeThreads->end(); 4082307SN/A 4092307SN/A while (threads != end) { 4102307SN/A ThreadID tid = *threads++; 4112307SN/A 4122307SN/A if (instList[tid].empty()) 4132307SN/A continue; 4142307SN/A 4152307SN/A if (first_valid) { 4162307SN/A head = instList[tid].begin(); 41713453Srekai.gonzalezalberquilla@arm.com lowest_num = (*head)->seqNum; 4186221Snate@binkert.org first_valid = false; 4192307SN/A continue; 4202307SN/A } 4212307SN/A 4222307SN/A InstIt head_thread = instList[tid].begin(); 4232307SN/A 4242307SN/A DynInstPtr head_inst = (*head_thread); 4252307SN/A 4262307SN/A assert(head_inst != 0); 4272307SN/A 4282307SN/A if (head_inst->seqNum < lowest_num) { 4297944SGiacomo.Gabrielli@arm.com head = head_thread; 43010333Smitch.hayenga@arm.com lowest_num = head_inst->seqNum; 43110333Smitch.hayenga@arm.com } 43210511Smitch.hayenga@arm.com } 4331060SN/A 4341060SN/A if (first_valid) { 4351061SN/A head = instList[0].end(); 4361060SN/A } 4376221Snate@binkert.org 4381060SN/A} 4392292SN/A 4402064SN/Atemplate <class Impl> 4412064SN/Avoid 4422064SN/AROB<Impl>::updateTail() 4432064SN/A{ 4442292SN/A tail = instList[0].end(); 4452064SN/A bool first_valid = true; 4464318Sktlim@umich.edu 4471060SN/A list<ThreadID>::iterator threads = activeThreads->begin(); 4481060SN/A list<ThreadID>::iterator end = activeThreads->end(); 4491061SN/A 4501060SN/A while (threads != end) { 4511060SN/A ThreadID tid = *threads++; 4521060SN/A 4531060SN/A if (instList[tid].empty()) { 4541060SN/A continue; 4551060SN/A } 4561060SN/A 4571060SN/A // If this is the first valid then assign w/out 4581684SN/A // comparison 45910510Smitch.hayenga@arm.com if (first_valid) { 46010510Smitch.hayenga@arm.com tail = instList[tid].end(); 46110510Smitch.hayenga@arm.com tail--; 46210511Smitch.hayenga@arm.com first_valid = false; 46310511Smitch.hayenga@arm.com continue; 46410511Smitch.hayenga@arm.com } 46510510Smitch.hayenga@arm.com 46610510Smitch.hayenga@arm.com // Assign new tail if this thread's tail is younger 46710510Smitch.hayenga@arm.com // than our current "tail high" 46810510Smitch.hayenga@arm.com InstIt tail_thread = instList[tid].end(); 46910510Smitch.hayenga@arm.com tail_thread--; 47010510Smitch.hayenga@arm.com 47110510Smitch.hayenga@arm.com if ((*tail_thread)->seqNum > (*tail)->seqNum) { 4722307SN/A tail = tail_thread; 4739444SAndreas.Sandberg@ARM.com } 4742307SN/A } 4759444SAndreas.Sandberg@ARM.com} 4769444SAndreas.Sandberg@ARM.com 4779444SAndreas.Sandberg@ARM.com 4789444SAndreas.Sandberg@ARM.comtemplate <class Impl> 4792307SN/Avoid 4802307SN/AROB<Impl>::squash(InstSeqNum squash_num, ThreadID tid) 4812307SN/A{ 4822307SN/A if (isEmpty(tid)) { 4832307SN/A DPRINTF(ROB, "Does not need to squash due to being empty " 4842307SN/A "[sn:%llu]\n", 4859444SAndreas.Sandberg@ARM.com squash_num); 4862307SN/A 4872307SN/A return; 4882307SN/A } 4892292SN/A 4906221Snate@binkert.org DPRINTF(ROB, "Starting to squash within the ROB.\n"); 4912292SN/A 49213561Snikos.nikoleris@arm.com robStatus[tid] = ROBSquashing; 4932292SN/A 4942292SN/A doneSquashing[tid] = false; 4952292SN/A 4962292SN/A squashedSeqNum[tid] = squash_num; 4972292SN/A 4982292SN/A if (!instList[tid].empty()) { 4992292SN/A InstIt tail_thread = instList[tid].end(); 5002292SN/A tail_thread--; 5012292SN/A 5022292SN/A squashIt[tid] = tail_thread; 5032292SN/A 50413561Snikos.nikoleris@arm.com doSquash(tid); 5053867Sbinkertn@umich.edu } 5062292SN/A} 5076221Snate@binkert.org 5086221Snate@binkert.orgtemplate <class Impl> 5092292SN/Aconst typename Impl::DynInstPtr& 5103867Sbinkertn@umich.eduROB<Impl>::readHeadInst(ThreadID tid) 5116221Snate@binkert.org{ 5123867Sbinkertn@umich.edu if (threadEntries[tid] != 0) { 51313561Snikos.nikoleris@arm.com InstIt head_thread = instList[tid].begin(); 5143867Sbinkertn@umich.edu 51513561Snikos.nikoleris@arm.com assert((*head_thread)->isInROB()); 51613561Snikos.nikoleris@arm.com 5173867Sbinkertn@umich.edu return *head_thread; 5182292SN/A } else { 5192292SN/A return dummyInst; 5202292SN/A } 5212292SN/A} 5222292SN/A 5232292SN/Atemplate <class Impl> 5241684SN/Atypename Impl::DynInstPtr 5251684SN/AROB<Impl>::readTailInst(ThreadID tid) 5261684SN/A{ 5271684SN/A InstIt tail_thread = instList[tid].end(); 5281684SN/A tail_thread--; 5291684SN/A 5302292SN/A return *tail_thread; 5312292SN/A} 5326221Snate@binkert.org 5332292SN/Atemplate <class Impl> 5342292SN/Avoid 5352292SN/AROB<Impl>::regStats() 5362292SN/A{ 5371060SN/A using namespace Stats; 5381060SN/A robReads 5391061SN/A .name(name() + ".rob_reads") 5401060SN/A .desc("The number of ROB reads"); 5411060SN/A 5421060SN/A robWrites 5431060SN/A .name(name() + ".rob_writes") 5441060SN/A .desc("The number of ROB writes"); 5451060SN/A} 5461060SN/A 5471060SN/Atemplate <class Impl> 5481060SN/Atypename Impl::DynInstPtr 5491060SN/AROB<Impl>::findInst(ThreadID tid, InstSeqNum squash_inst) 5501061SN/A{ 5512292SN/A for (InstIt it = instList[tid].begin(); it != instList[tid].end(); it++) { 5526221Snate@binkert.org if ((*it)->seqNum == squash_inst) { 5532292SN/A return *it; 5542292SN/A } 5552292SN/A } 5562292SN/A return NULL; 5572292SN/A} 5582292SN/A 5592292SN/A#endif//__CPU_O3_ROB_IMPL_HH__ 5602292SN/A