rob_impl.hh revision 2292
11689SN/A/* 29783Sandreas.hansson@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 310239Sbinhpham@cs.rutgers.edu * All rights reserved. 47598Sminkyu.jeong@arm.com * 57598Sminkyu.jeong@arm.com * Redistribution and use in source and binary forms, with or without 67598Sminkyu.jeong@arm.com * modification, are permitted provided that the following conditions are 77598Sminkyu.jeong@arm.com * met: redistributions of source code must retain the above copyright 87598Sminkyu.jeong@arm.com * notice, this list of conditions and the following disclaimer; 97598Sminkyu.jeong@arm.com * redistributions in binary form must reproduce the above copyright 107598Sminkyu.jeong@arm.com * notice, this list of conditions and the following disclaimer in the 117598Sminkyu.jeong@arm.com * documentation and/or other materials provided with the distribution; 127598Sminkyu.jeong@arm.com * neither the name of the copyright holders nor the names of its 137598Sminkyu.jeong@arm.com * contributors may be used to endorse or promote products derived from 147598Sminkyu.jeong@arm.com * this software without specific prior written permission. 152326SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271689SN/A */ 281689SN/A 291689SN/A#include "config/full_system.hh" 301689SN/A#include "cpu/o3/rob.hh" 311689SN/A 321689SN/Ausing namespace std; 331689SN/A 341689SN/Atemplate <class Impl> 351689SN/AROB<Impl>::ROB(unsigned _numEntries, unsigned _squashWidth, 361689SN/A string _smtROBPolicy, unsigned _smtROBThreshold, 371689SN/A unsigned _numThreads) 381689SN/A : numEntries(_numEntries), 391689SN/A squashWidth(_squashWidth), 402665Ssaidi@eecs.umich.edu numInstsInROB(0), 412665Ssaidi@eecs.umich.edu squashedSeqNum(0), 421689SN/A numThreads(_numThreads) 431689SN/A{ 449944Smatt.horsnell@ARM.com for (int tid=0; tid < numThreads; tid++) { 459944Smatt.horsnell@ARM.com doneSquashing[tid] = true; 469944Smatt.horsnell@ARM.com threadEntries[tid] = 0; 471060SN/A } 481060SN/A 491689SN/A string policy = _smtROBPolicy; 501060SN/A 511060SN/A //Convert string to lowercase 521060SN/A std::transform(policy.begin(), policy.end(), policy.begin(), 538230Snate@binkert.org (int(*)(int)) tolower); 546658Snate@binkert.org 558887Sgeoffrey.blake@arm.com //Figure out rob policy 562292SN/A if (policy == "dynamic") { 571717SN/A robPolicy = Dynamic; 588229Snate@binkert.org 598232Snate@binkert.org //Set Max Entries to Total ROB Capacity 609444SAndreas.Sandberg@ARM.com for (int i = 0; i < numThreads; i++) { 618232Snate@binkert.org maxEntries[i]=numEntries; 629527SMatt.Horsnell@arm.com } 635529Snate@binkert.org 641060SN/A } else if (policy == "partitioned") { 656221Snate@binkert.org robPolicy = Partitioned; 666221Snate@binkert.org DPRINTF(Fetch, "ROB sharing policy set to Partitioned\n"); 671681SN/A 685529Snate@binkert.org //@todo:make work if part_amt doesnt divide evenly. 692873Sktlim@umich.edu int part_amt = numEntries / numThreads; 704329Sktlim@umich.edu 714329Sktlim@umich.edu //Divide ROB up evenly 724329Sktlim@umich.edu for (int i = 0; i < numThreads; i++) { 732292SN/A maxEntries[i]=part_amt; 742292SN/A } 752292SN/A 762292SN/A } else if (policy == "threshold") { 772820Sktlim@umich.edu robPolicy = Threshold; 782292SN/A DPRINTF(Fetch, "ROB sharing policy set to Threshold\n"); 792820Sktlim@umich.edu 809444SAndreas.Sandberg@ARM.com int threshold = _smtROBThreshold;; 811060SN/A 8210172Sdam.sunwoo@arm.com //Divide up by threshold amount 8310172Sdam.sunwoo@arm.com for (int i = 0; i < numThreads; i++) { 8410172Sdam.sunwoo@arm.com maxEntries[i]=threshold; 8510172Sdam.sunwoo@arm.com } 8610172Sdam.sunwoo@arm.com } else { 8710172Sdam.sunwoo@arm.com assert(0 && "Invalid ROB Sharing Policy.Options Are:{Dynamic," 8810172Sdam.sunwoo@arm.com "Partitioned, Threshold}"); 8910172Sdam.sunwoo@arm.com } 9010172Sdam.sunwoo@arm.com} 9110172Sdam.sunwoo@arm.com 9210172Sdam.sunwoo@arm.comtemplate <class Impl> 9310172Sdam.sunwoo@arm.comstd::string 9410172Sdam.sunwoo@arm.comROB<Impl>::name() const 952292SN/A{ 962292SN/A return cpu->name() + ".rob"; 972292SN/A} 981060SN/A 991060SN/Atemplate <class Impl> 1001060SN/Avoid 1011060SN/AROB<Impl>::setCPU(FullCPU *cpu_ptr) 1021060SN/A{ 1031060SN/A cpu = cpu_ptr; 1041681SN/A 1056221Snate@binkert.org // Set the per-thread iterators to the end of the instruction list. 1066221Snate@binkert.org for (int i=0; i < numThreads;i++) { 1076221Snate@binkert.org squashIt[i] = instList[i].end(); 1082292SN/A } 1092292SN/A 1102292SN/A // Initialize the "universal" ROB head & tail point to invalid 1112292SN/A // pointers 11210328Smitch.hayenga@arm.com head = instList[0].end(); 1132292SN/A tail = instList[0].end(); 1142292SN/A} 1152292SN/A 1162292SN/Atemplate <class Impl> 1172292SN/Avoid 1182292SN/AROB<Impl>::setActiveThreads(list<unsigned> *at_ptr) 1192292SN/A{ 1201060SN/A DPRINTF(ROB, "Setting active threads list pointer.\n"); 1211060SN/A activeThreads = at_ptr; 1221681SN/A} 1231062SN/A 12410023Smatt.horsnell@ARM.com 12510023Smatt.horsnell@ARM.comtemplate <class Impl> 12610023Smatt.horsnell@ARM.comvoid 12710023Smatt.horsnell@ARM.comROB<Impl>::resetEntries() 12810023Smatt.horsnell@ARM.com{ 12910023Smatt.horsnell@ARM.com if (robPolicy != Dynamic || numThreads > 1) { 13010023Smatt.horsnell@ARM.com int active_threads = (*activeThreads).size(); 13110023Smatt.horsnell@ARM.com 1322292SN/A list<unsigned>::iterator threads = (*activeThreads).begin(); 1331062SN/A list<unsigned>::iterator list_end = (*activeThreads).end(); 1342301SN/A 1352301SN/A while (threads != list_end) { 1361062SN/A if (robPolicy == Partitioned) { 1372727Sktlim@umich.edu maxEntries[*threads++] = numEntries / active_threads; 1381062SN/A } else if (robPolicy == Threshold && active_threads == 1) { 1391062SN/A maxEntries[*threads++] = numEntries; 1401062SN/A } 1411062SN/A } 1421062SN/A } 1431062SN/A} 1441062SN/A 1451062SN/Atemplate <class Impl> 1461062SN/Aint 1471062SN/AROB<Impl>::entryAmount(int num_threads) 1481062SN/A{ 1491062SN/A if (robPolicy == Partitioned) { 1501062SN/A return numEntries / num_threads; 1511062SN/A } else { 1521062SN/A return 0; 1531062SN/A } 1541062SN/A} 1551062SN/A 1561062SN/Atemplate <class Impl> 1571062SN/Aint 1581062SN/AROB<Impl>::countInsts() 1591062SN/A{ 1601062SN/A int total=0; 1611062SN/A 1621062SN/A for (int i=0;i < numThreads;i++) 1631062SN/A total += countInsts(i); 1641062SN/A 1651062SN/A return total; 1661062SN/A} 1671062SN/A 1681062SN/Atemplate <class Impl> 1691062SN/Aint 1701062SN/AROB<Impl>::countInsts(unsigned tid) 1711062SN/A{ 1721062SN/A return instList[tid].size(); 1731062SN/A} 1741062SN/A 1751062SN/Atemplate <class Impl> 1761062SN/Avoid 1771062SN/AROB<Impl>::insertInst(DynInstPtr &inst) 1781062SN/A{ 1792292SN/A // Make sure we have the right number of instructions. 1802292SN/A //assert(numInstsInROB == countInsts()); 1812292SN/A 1822292SN/A // Make sure the instruction is valid. 1831062SN/A assert(inst); 1841062SN/A 1851062SN/A DPRINTF(ROB, "Adding inst PC %#x to the ROB.\n", inst->readPC()); 1861062SN/A 1871062SN/A // If the ROB is full then exit. 1881062SN/A assert(numInstsInROB != numEntries); 1891062SN/A 1902292SN/A int tid = inst->threadNumber; 1912292SN/A 1922292SN/A // Place into ROB 1932292SN/A instList[tid].push_back(inst); 1942292SN/A 1952292SN/A //Set Up head iterator if this is the 1st instruction in the ROB 1962292SN/A if (numInstsInROB == 0) { 1972292SN/A head = instList[tid].begin(); 1982292SN/A assert((*head) == inst); 1992292SN/A } 2002301SN/A 2012727Sktlim@umich.edu //Must Decrement for iterator to actually be valid since __.end() 2022353SN/A //actually points to 1 after the last inst 2032727Sktlim@umich.edu tail = instList[tid].end(); 2042727Sktlim@umich.edu tail--; 2052727Sktlim@umich.edu 2066221Snate@binkert.org // Mark as set in ROB 2072353SN/A inst->setInROB(); 2082727Sktlim@umich.edu 2092727Sktlim@umich.edu // Increment ROB count 2102727Sktlim@umich.edu ++numInstsInROB; 2112727Sktlim@umich.edu ++threadEntries[tid]; 2122353SN/A 2132727Sktlim@umich.edu assert((*tail) == inst); 2142727Sktlim@umich.edu 2152727Sktlim@umich.edu DPRINTF(ROB, "[tid:%i] Now has %d instructions.\n", tid, threadEntries[tid]); 2166221Snate@binkert.org} 2178240Snate@binkert.org 2182301SN/A// Whatever calls this function needs to ensure that it properly frees up 2192727Sktlim@umich.edu// registers prior to this function. 2202301SN/Atemplate <class Impl> 2212727Sktlim@umich.eduvoid 2226221Snate@binkert.orgROB<Impl>::retireHead() 2238240Snate@binkert.org{ 2242301SN/A //assert(numInstsInROB == countInsts()); 2252727Sktlim@umich.edu assert(numInstsInROB > 0); 2262301SN/A 2272727Sktlim@umich.edu // Get the head ROB instruction's TID. 2286221Snate@binkert.org int tid = (*head)->threadNumber; 2298240Snate@binkert.org 2302301SN/A retireHead(tid); 2312727Sktlim@umich.edu 2322301SN/A if (numInstsInROB == 0) { 2332727Sktlim@umich.edu tail = instList[tid].end(); 2346221Snate@binkert.org } 2358240Snate@binkert.org} 2362301SN/A 2372727Sktlim@umich.edutemplate <class Impl> 2382301SN/Avoid 2392301SN/AROB<Impl>::retireHead(unsigned tid) 2408240Snate@binkert.org{ 2412301SN/A //assert(numInstsInROB == countInsts()); 2422727Sktlim@umich.edu assert(numInstsInROB > 0); 2432727Sktlim@umich.edu 2442727Sktlim@umich.edu // Get the head ROB instruction. 2452727Sktlim@umich.edu InstIt head_it = instList[tid].begin(); 2468240Snate@binkert.org 2472727Sktlim@umich.edu DynInstPtr head_inst = (*head_it); 2482727Sktlim@umich.edu 2492727Sktlim@umich.edu // Make certain this can retire. 2502727Sktlim@umich.edu assert(head_inst->readyToCommit()); 2512301SN/A 2522301SN/A DPRINTF(ROB, "[tid:%u]: Retiring head instruction, " 2536221Snate@binkert.org "instruction PC %#x,[sn:%lli]\n", tid, head_inst->readPC(), 2548240Snate@binkert.org head_inst->seqNum); 2552301SN/A 2562727Sktlim@umich.edu // Keep track of how many instructions are in the ROB. 2572301SN/A --numInstsInROB; 2582326SN/A --threadEntries[tid]; 2596221Snate@binkert.org 2608240Snate@binkert.org //Mark DynInstFlags 2612301SN/A head_inst->removeInROB(); 2622727Sktlim@umich.edu head_inst->setCommitted(); 2632301SN/A 2642326SN/A instList[tid].erase(head_it); 2656221Snate@binkert.org 2668240Snate@binkert.org //Update "Global" Head of ROB 2672301SN/A updateHead(); 2682727Sktlim@umich.edu 2692301SN/A // A special case is needed if the instruction being retired is the 2702326SN/A // only instruction in the ROB; otherwise the tail iterator will become 2716221Snate@binkert.org // invalidated. 2728240Snate@binkert.org cpu->removeFrontInst(head_inst); 2732301SN/A} 2742727Sktlim@umich.edu 2752301SN/Atemplate <class Impl> 2762326SN/Abool 2776221Snate@binkert.orgROB<Impl>::isHeadReady() 2788240Snate@binkert.org{ 2792301SN/A if (numInstsInROB != 0) { 2802727Sktlim@umich.edu return (*head)->readyToCommit(); 2812301SN/A } 2822326SN/A 2838240Snate@binkert.org return false; 2842301SN/A} 2852727Sktlim@umich.edu 2862301SN/Atemplate <class Impl> 2872326SN/Abool 2882301SN/AROB<Impl>::isHeadReady(unsigned tid) 2892326SN/A{ 2908240Snate@binkert.org if (threadEntries[tid] != 0) { 2912301SN/A return instList[tid].front()->readyToCommit(); 2922727Sktlim@umich.edu } 2932301SN/A 2942326SN/A return false; 2952301SN/A} 2962326SN/A 2978240Snate@binkert.orgtemplate <class Impl> 2982301SN/Abool 2992727Sktlim@umich.eduROB<Impl>::canCommit() 3002326SN/A{ 3011062SN/A //@todo: set ActiveThreads through ROB or CPU 3021062SN/A list<unsigned>::iterator threads = (*activeThreads).begin(); 3031681SN/A 3041060SN/A while (threads != (*activeThreads).end()) { 3059427SAndreas.Sandberg@ARM.com unsigned tid = *threads++; 3061060SN/A 3076221Snate@binkert.org if (isHeadReady(tid)) { 3082292SN/A return true; 3092292SN/A } 3102292SN/A } 3112292SN/A 3122292SN/A return false; 31310239Sbinhpham@cs.rutgers.edu} 31410239Sbinhpham@cs.rutgers.edu 3152292SN/Atemplate <class Impl> 3162292SN/Aunsigned 3178887Sgeoffrey.blake@arm.comROB<Impl>::numFreeEntries() 3188733Sgeoffrey.blake@arm.com{ 3198850Sandreas.hansson@arm.com //assert(numInstsInROB == countInsts()); 3208887Sgeoffrey.blake@arm.com 3218733Sgeoffrey.blake@arm.com return numEntries - numInstsInROB; 3222733Sktlim@umich.edu} 3231060SN/A 3241060SN/Atemplate <class Impl> 3251681SN/Aunsigned 3261060SN/AROB<Impl>::numFreeEntries(unsigned tid) 3272292SN/A{ 3281060SN/A return maxEntries[tid] - threadEntries[tid]; 3291060SN/A} 3301060SN/A 3311060SN/Atemplate <class Impl> 3321060SN/Avoid 3331060SN/AROB<Impl>::doSquash(unsigned tid) 3341060SN/A{ 3351060SN/A DPRINTF(ROB, "[tid:%u]: Squashing instructions until [sn:%i].\n", 3361060SN/A tid, squashedSeqNum); 3372292SN/A 3382292SN/A assert(squashIt[tid] != instList[tid].end()); 3391060SN/A 3401060SN/A if ((*squashIt[tid])->seqNum < squashedSeqNum) { 3411060SN/A DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n", 3421060SN/A tid); 3431681SN/A 3441060SN/A squashIt[tid] = instList[tid].end(); 3452292SN/A 3461060SN/A doneSquashing[tid] = true; 3471060SN/A return; 3481060SN/A } 3491060SN/A 3501060SN/A bool robTailUpdate = false; 3511060SN/A 3521060SN/A for (int numSquashed = 0; 3531681SN/A numSquashed < squashWidth && 3541060SN/A squashIt[tid] != instList[tid].end() && 3552292SN/A (*squashIt[tid])->seqNum > squashedSeqNum; 3561060SN/A ++numSquashed) 3571060SN/A { 3581060SN/A DPRINTF(ROB, "[tid:%u]: Squashing instruction PC %#x, seq num %i.\n", 3591060SN/A (*squashIt[tid])->threadNumber, 3601060SN/A (*squashIt[tid])->readPC(), 3611060SN/A (*squashIt[tid])->seqNum); 3621060SN/A 3631681SN/A // Mark the instruction as squashed, and ready to commit so that 3641060SN/A // it can drain out of the pipeline. 3656221Snate@binkert.org (*squashIt[tid])->setSquashed(); 3661060SN/A 3672292SN/A (*squashIt[tid])->setCanCommit(); 3682292SN/A 3692292SN/A 3702292SN/A if (squashIt[tid] == instList[tid].begin()) { 3711060SN/A DPRINTF(ROB, "Reached head of instruction list while " 3721060SN/A "squashing.\n"); 3731681SN/A 3741060SN/A squashIt[tid] = instList[tid].end(); 3752292SN/A 3761060SN/A doneSquashing[tid] = true; 3772292SN/A 3781060SN/A return; 3791060SN/A } 3802307SN/A 3812863Sktlim@umich.edu InstIt tail_thread = instList[tid].end(); 3829444SAndreas.Sandberg@ARM.com tail_thread--; 3832307SN/A 38410510Smitch.hayenga@arm.com if ((*squashIt[tid]) == (*tail_thread)) 3859444SAndreas.Sandberg@ARM.com robTailUpdate = true; 3869444SAndreas.Sandberg@ARM.com 3879444SAndreas.Sandberg@ARM.com squashIt[tid]--; 3889444SAndreas.Sandberg@ARM.com } 3899444SAndreas.Sandberg@ARM.com 3909444SAndreas.Sandberg@ARM.com 3919444SAndreas.Sandberg@ARM.com // Check if ROB is done squashing. 3929444SAndreas.Sandberg@ARM.com if ((*squashIt[tid])->seqNum <= squashedSeqNum) { 3939444SAndreas.Sandberg@ARM.com DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n", 3949444SAndreas.Sandberg@ARM.com tid); 3959444SAndreas.Sandberg@ARM.com 3969444SAndreas.Sandberg@ARM.com squashIt[tid] = instList[tid].end(); 3979783Sandreas.hansson@arm.com 3989783Sandreas.hansson@arm.com doneSquashing[tid] = true; 3999783Sandreas.hansson@arm.com } 4009783Sandreas.hansson@arm.com 4019783Sandreas.hansson@arm.com if (robTailUpdate) { 4029783Sandreas.hansson@arm.com updateTail(); 4039783Sandreas.hansson@arm.com } 4049783Sandreas.hansson@arm.com} 4059444SAndreas.Sandberg@ARM.com 4061681SN/A 4071681SN/Atemplate <class Impl> 4082316SN/Avoid 4091681SN/AROB<Impl>::updateHead() 4109444SAndreas.Sandberg@ARM.com{ 4112843Sktlim@umich.edu DynInstPtr head_inst; 4129444SAndreas.Sandberg@ARM.com InstSeqNum lowest_num = 0; 4132843Sktlim@umich.edu bool first_valid = true; 4149444SAndreas.Sandberg@ARM.com 4159444SAndreas.Sandberg@ARM.com // @todo: set ActiveThreads through ROB or CPU 4161681SN/A list<unsigned>::iterator threads = (*activeThreads).begin(); 4171681SN/A 4182307SN/A while (threads != (*activeThreads).end()) { 4191681SN/A unsigned thread_num = *threads++; 4202307SN/A 4211060SN/A if (instList[thread_num].empty()) 4222348SN/A continue; 4232307SN/A 4242307SN/A if (first_valid) { 4252307SN/A head = instList[thread_num].begin(); 4261060SN/A lowest_num = (*head)->seqNum; 4272307SN/A first_valid = false; 4282307SN/A continue; 4299444SAndreas.Sandberg@ARM.com } 4301060SN/A 4319427SAndreas.Sandberg@ARM.com InstIt head_thread = instList[thread_num].begin(); 4322307SN/A 4331060SN/A DynInstPtr head_inst = (*head_thread); 4346221Snate@binkert.org 4356221Snate@binkert.org assert(head_inst != 0); 4366221Snate@binkert.org 4372307SN/A if (head_inst->seqNum < lowest_num) { 4381060SN/A head = head_thread; 4392307SN/A lowest_num = head_inst->seqNum; 4402307SN/A } 4412873Sktlim@umich.edu } 4422307SN/A 4431060SN/A if (first_valid) { 4441060SN/A head = instList[0].end(); 4451060SN/A } 4461681SN/A 4471060SN/A} 4486221Snate@binkert.org 4492107SN/Atemplate <class Impl> 4506221Snate@binkert.orgvoid 4512107SN/AROB<Impl>::updateTail() 4522292SN/A{ 4532292SN/A tail = instList[0].end(); 4542107SN/A bool first_valid = true; 4552292SN/A 4562326SN/A list<unsigned>::iterator threads = (*activeThreads).begin(); 4572292SN/A 4582107SN/A while (threads != (*activeThreads).end()) { 4592292SN/A unsigned tid = *threads++; 4602935Sksewell@umich.edu 4614632Sgblack@eecs.umich.edu if (instList[tid].empty()) { 4622935Sksewell@umich.edu continue; 4632292SN/A } 46410239Sbinhpham@cs.rutgers.edu 46510239Sbinhpham@cs.rutgers.edu // If this is the first valid then assign w/out 46610239Sbinhpham@cs.rutgers.edu // comparison 46710239Sbinhpham@cs.rutgers.edu if (first_valid) { 46810239Sbinhpham@cs.rutgers.edu tail = instList[tid].end(); 4692292SN/A tail--; 4702107SN/A first_valid = false; 4712292SN/A continue; 4722107SN/A } 4732292SN/A 4742292SN/A // Assign new tail if this thread's tail is younger 4752107SN/A // than our current "tail high" 4762702Sktlim@umich.edu InstIt tail_thread = instList[tid].end(); 4772107SN/A tail_thread--; 4782107SN/A 4792107SN/A if ((*tail_thread)->seqNum > (*tail)->seqNum) { 4802107SN/A tail = tail_thread; 4816221Snate@binkert.org } 4822292SN/A } 4837720Sgblack@eecs.umich.edu} 4847720Sgblack@eecs.umich.edu 4852292SN/A 48610231Ssteve.reinhardt@amd.comtemplate <class Impl> 4877852SMatt.Horsnell@arm.comvoid 4887852SMatt.Horsnell@arm.comROB<Impl>::squash(InstSeqNum squash_num,unsigned tid) 4897852SMatt.Horsnell@arm.com{ 4907852SMatt.Horsnell@arm.com if (isEmpty()) { 4912935Sksewell@umich.edu DPRINTF(ROB, "Does not need to squash due to being empty " 4927852SMatt.Horsnell@arm.com "[sn:%i]\n", 4937852SMatt.Horsnell@arm.com squash_num); 4942292SN/A 4957852SMatt.Horsnell@arm.com return; 4967852SMatt.Horsnell@arm.com } 4977852SMatt.Horsnell@arm.com 4982292SN/A DPRINTF(ROB, "Starting to squash within the ROB.\n"); 4997852SMatt.Horsnell@arm.com 5007852SMatt.Horsnell@arm.com robStatus[tid] = ROBSquashing; 5017852SMatt.Horsnell@arm.com 5022292SN/A doneSquashing[tid] = false; 5032292SN/A 5042292SN/A squashedSeqNum = squash_num; 5052292SN/A 5066221Snate@binkert.org if (!instList[tid].empty()) { 5072292SN/A InstIt tail_thread = instList[tid].end(); 5088513SGiacomo.Gabrielli@arm.com tail_thread--; 5098513SGiacomo.Gabrielli@arm.com 5108513SGiacomo.Gabrielli@arm.com squashIt[tid] = tail_thread; 5118513SGiacomo.Gabrielli@arm.com 5128513SGiacomo.Gabrielli@arm.com doSquash(tid); 5138513SGiacomo.Gabrielli@arm.com } 5148513SGiacomo.Gabrielli@arm.com} 5158513SGiacomo.Gabrielli@arm.com 51610231Ssteve.reinhardt@amd.comtemplate <class Impl> 5178513SGiacomo.Gabrielli@arm.comtypename Impl::DynInstPtr 5188513SGiacomo.Gabrielli@arm.comROB<Impl>::readHeadInst() 5192292SN/A{ 5207852SMatt.Horsnell@arm.com if (numInstsInROB != 0) { 5218513SGiacomo.Gabrielli@arm.com assert((*head)->isInROB()==true); 5228137SAli.Saidi@ARM.com return *head; 5232292SN/A } else { 5248513SGiacomo.Gabrielli@arm.com return dummyInst; 5258513SGiacomo.Gabrielli@arm.com } 5262292SN/A} 5277852SMatt.Horsnell@arm.com 5287852SMatt.Horsnell@arm.comtemplate <class Impl> 5292292SN/Atypename Impl::DynInstPtr 5302292SN/AROB<Impl>::readHeadInst(unsigned tid) 5312292SN/A{ 5322292SN/A if (threadEntries[tid] != 0) { 5336221Snate@binkert.org InstIt head_thread = instList[tid].begin(); 5342292SN/A 5352292SN/A assert((*head_thread)->isInROB()==true); 5362292SN/A 5372292SN/A return *head_thread; 5382292SN/A } else { 5392292SN/A return dummyInst; 5402292SN/A } 5412292SN/A} 5422292SN/A 5432292SN/Atemplate <class Impl> 5442292SN/Auint64_t 5452292SN/AROB<Impl>::readHeadPC() 5462292SN/A{ 5472292SN/A //assert(numInstsInROB == countInsts()); 5482292SN/A 5492292SN/A DynInstPtr head_inst = *head; 5502292SN/A 5512292SN/A return head_inst->readPC(); 5526221Snate@binkert.org} 5532292SN/A 5542292SN/Atemplate <class Impl> 5552292SN/Auint64_t 5562292SN/AROB<Impl>::readHeadPC(unsigned tid) 5572292SN/A{ 5582292SN/A //assert(numInstsInROB == countInsts()); 5592292SN/A InstIt head_thread = instList[tid].begin(); 5602292SN/A 5612292SN/A return (*head_thread)->readPC(); 5622292SN/A} 5632292SN/A 5642292SN/A 5652292SN/Atemplate <class Impl> 5662292SN/Auint64_t 5672292SN/AROB<Impl>::readHeadNextPC() 5682292SN/A{ 5692292SN/A //assert(numInstsInROB == countInsts()); 5701060SN/A 5711681SN/A DynInstPtr head_inst = *head; 5721060SN/A 5731060SN/A return head_inst->readNextPC(); 5742292SN/A} 5752292SN/A 5762292SN/Atemplate <class Impl> 5772292SN/Auint64_t 5782292SN/AROB<Impl>::readHeadNextPC(unsigned tid) 5792292SN/A{ 5801681SN/A //assert(numInstsInROB == countInsts()); 5811681SN/A InstIt head_thread = instList[tid].begin(); 5821060SN/A 5832292SN/A return (*head_thread)->readNextPC(); 5841060SN/A} 5852292SN/A 5862292SN/A 5871060SN/Atemplate <class Impl> 5882292SN/AInstSeqNum 5892292SN/AROB<Impl>::readHeadSeqNum() 59010333Smitch.hayenga@arm.com{ 59110333Smitch.hayenga@arm.com //assert(numInstsInROB == countInsts()); 59210333Smitch.hayenga@arm.com DynInstPtr head_inst = *head; 59310333Smitch.hayenga@arm.com 59410333Smitch.hayenga@arm.com return head_inst->seqNum; 59510333Smitch.hayenga@arm.com} 59610333Smitch.hayenga@arm.com 59710333Smitch.hayenga@arm.comtemplate <class Impl> 59810333Smitch.hayenga@arm.comInstSeqNum 59910333Smitch.hayenga@arm.comROB<Impl>::readHeadSeqNum(unsigned tid) 60010333Smitch.hayenga@arm.com{ 60110333Smitch.hayenga@arm.com InstIt head_thread = instList[tid].begin(); 60210333Smitch.hayenga@arm.com 60310333Smitch.hayenga@arm.com return ((*head_thread)->seqNum); 6042292SN/A} 6052292SN/A 6063221Sktlim@umich.edutemplate <class Impl> 6073221Sktlim@umich.edutypename Impl::DynInstPtr 6083221Sktlim@umich.eduROB<Impl>::readTailInst() 6093221Sktlim@umich.edu{ 6103221Sktlim@umich.edu //assert(numInstsInROB == countInsts()); 6112292SN/A //assert(tail != instList[0].end()); 6122292SN/A 6132292SN/A return (*tail); 6142292SN/A} 6152326SN/A 6162292SN/Atemplate <class Impl> 6172292SN/Atypename Impl::DynInstPtr 6182820Sktlim@umich.eduROB<Impl>::readTailInst(unsigned tid) 6192292SN/A{ 6202292SN/A //assert(tail_thread[tid] != instList[tid].end()); 6212292SN/A 6222292SN/A InstIt tail_thread = instList[tid].end(); 6232292SN/A tail_thread--; 6242353SN/A 6252353SN/A return *tail_thread; 6262292SN/A} 6272292SN/A 6282292SN/A 6292292SN/Atemplate <class Impl> 6302292SN/Auint64_t 6312292SN/AROB<Impl>::readTailPC() 6322292SN/A{ 6332292SN/A //assert(numInstsInROB == countInsts()); 6342292SN/A 6352292SN/A //assert(tail != instList[0].end()); 6362292SN/A 6372292SN/A return (*tail)->readPC(); 6382731Sktlim@umich.edu} 6392292SN/A 6402292SN/Atemplate <class Impl> 6412292SN/Auint64_t 6422292SN/AROB<Impl>::readTailPC(unsigned tid) 6432292SN/A{ 6442292SN/A //assert(tail_thread[tid] != instList[tid].end()); 6452292SN/A 6462292SN/A InstIt tail_thread = instList[tid].end(); 6476221Snate@binkert.org tail_thread--; 6482292SN/A 6492292SN/A return (*tail_thread)->readPC(); 6502292SN/A} 6512292SN/A 6522292SN/Atemplate <class Impl> 6532292SN/AInstSeqNum 6542292SN/AROB<Impl>::readTailSeqNum() 6552292SN/A{ 6569937SFaissal.Sleiman@arm.com // Return the last sequence number that has not been squashed. Other 6572292SN/A // stages can use it to squash any instructions younger than the current 6587720Sgblack@eecs.umich.edu // tail. 6592292SN/A return (*tail)->seqNum; 6602292SN/A} 6612292SN/A 6622292SN/Atemplate <class Impl> 6632292SN/AInstSeqNum 6642292SN/AROB<Impl>::readTailSeqNum(unsigned tid) 6652292SN/A{ 6662292SN/A // Return the last sequence number that has not been squashed. Other 6672292SN/A // stages can use it to squash any instructions younger than the current 6682292SN/A // tail. 6692292SN/A // assert(tail_thread[tid] != instList[tid].end()); 6702292SN/A 6712292SN/A InstIt tail_thread = instList[tid].end(); 6722292SN/A tail_thread--; 6736221Snate@binkert.org 6746221Snate@binkert.org return (*tail_thread)->seqNum; 6752292SN/A} 6763867Sbinkertn@umich.edu 6776221Snate@binkert.org