rob_impl.hh revision 2307
11689SN/A/* 29444SAndreas.Sandberg@ARM.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 37598Sminkyu.jeong@arm.com * 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 142326SN/A * this software without specific prior written permission. 151689SN/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), 392665Ssaidi@eecs.umich.edu squashWidth(_squashWidth), 402665Ssaidi@eecs.umich.edu numInstsInROB(0), 411689SN/A squashedSeqNum(0), 421689SN/A numThreads(_numThreads) 431060SN/A{ 441060SN/A for (int tid=0; tid < numThreads; tid++) { 451689SN/A doneSquashing[tid] = true; 461060SN/A threadEntries[tid] = 0; 471060SN/A } 481060SN/A 498230Snate@binkert.org string policy = _smtROBPolicy; 506658Snate@binkert.org 518887Sgeoffrey.blake@arm.com //Convert string to lowercase 522292SN/A std::transform(policy.begin(), policy.end(), policy.begin(), 531717SN/A (int(*)(int)) tolower); 548229Snate@binkert.org 558232Snate@binkert.org //Figure out rob policy 568232Snate@binkert.org if (policy == "dynamic") { 579444SAndreas.Sandberg@ARM.com robPolicy = Dynamic; 588232Snate@binkert.org 595529Snate@binkert.org //Set Max Entries to Total ROB Capacity 601060SN/A for (int i = 0; i < numThreads; i++) { 616221Snate@binkert.org maxEntries[i]=numEntries; 626221Snate@binkert.org } 631681SN/A 645529Snate@binkert.org } else if (policy == "partitioned") { 652873Sktlim@umich.edu robPolicy = Partitioned; 664329Sktlim@umich.edu DPRINTF(Fetch, "ROB sharing policy set to Partitioned\n"); 674329Sktlim@umich.edu 684329Sktlim@umich.edu //@todo:make work if part_amt doesnt divide evenly. 692292SN/A int part_amt = numEntries / numThreads; 702292SN/A 712292SN/A //Divide ROB up evenly 722292SN/A for (int i = 0; i < numThreads; i++) { 732820Sktlim@umich.edu maxEntries[i]=part_amt; 742292SN/A } 752820Sktlim@umich.edu 762820Sktlim@umich.edu } else if (policy == "threshold") { 779444SAndreas.Sandberg@ARM.com robPolicy = Threshold; 781060SN/A DPRINTF(Fetch, "ROB sharing policy set to Threshold\n"); 792292SN/A 802292SN/A int threshold = _smtROBThreshold;; 812292SN/A 821060SN/A //Divide up by threshold amount 831060SN/A for (int i = 0; i < numThreads; i++) { 841060SN/A maxEntries[i]=threshold; 851060SN/A } 861060SN/A } else { 871060SN/A assert(0 && "Invalid ROB Sharing Policy.Options Are:{Dynamic," 881681SN/A "Partitioned, Threshold}"); 896221Snate@binkert.org } 906221Snate@binkert.org} 916221Snate@binkert.org 926221Snate@binkert.orgtemplate <class Impl> 932292SN/Astd::string 942292SN/AROB<Impl>::name() const 952820Sktlim@umich.edu{ 962820Sktlim@umich.edu return cpu->name() + ".rob"; 972292SN/A} 982292SN/A 992820Sktlim@umich.edutemplate <class Impl> 1002820Sktlim@umich.eduvoid 1012292SN/AROB<Impl>::setCPU(FullCPU *cpu_ptr) 1022292SN/A{ 1032292SN/A cpu = cpu_ptr; 1042292SN/A 1052292SN/A // Set the per-thread iterators to the end of the instruction list. 1062292SN/A for (int i=0; i < numThreads;i++) { 1072292SN/A squashIt[i] = instList[i].end(); 1082292SN/A } 1091060SN/A 1101060SN/A // Initialize the "universal" ROB head & tail point to invalid 1111681SN/A // pointers 1121062SN/A head = instList[0].end(); 1132292SN/A tail = instList[0].end(); 1141062SN/A} 1152301SN/A 1162301SN/Atemplate <class Impl> 1171062SN/Avoid 1182727Sktlim@umich.eduROB<Impl>::setActiveThreads(list<unsigned> *at_ptr) 1191062SN/A{ 1201062SN/A DPRINTF(ROB, "Setting active threads list pointer.\n"); 1211062SN/A activeThreads = at_ptr; 1221062SN/A} 1231062SN/A 1241062SN/Atemplate <class Impl> 1251062SN/Avoid 1261062SN/AROB<Impl>::switchOut() 1271062SN/A{ 1281062SN/A for (int tid = 0; tid < numThreads; tid++) { 1291062SN/A instList[tid].clear(); 1301062SN/A } 1311062SN/A} 1321062SN/A 1331062SN/Atemplate <class Impl> 1341062SN/Avoid 1351062SN/AROB<Impl>::takeOverFrom() 1361062SN/A{ 1371062SN/A for (int tid=0; tid < numThreads; tid++) { 1381062SN/A doneSquashing[tid] = true; 1391062SN/A threadEntries[tid] = 0; 1401062SN/A squashIt[tid] = instList[tid].end(); 1411062SN/A } 1421062SN/A numInstsInROB = 0; 1431062SN/A 1441062SN/A // Initialize the "universal" ROB head & tail point to invalid 1451062SN/A // pointers 1461062SN/A head = instList[0].end(); 1471062SN/A tail = instList[0].end(); 1481062SN/A} 1491062SN/A 1501062SN/Atemplate <class Impl> 1511062SN/Avoid 1521062SN/AROB<Impl>::resetEntries() 1531062SN/A{ 1541062SN/A if (robPolicy != Dynamic || numThreads > 1) { 1551062SN/A int active_threads = (*activeThreads).size(); 1561062SN/A 1571062SN/A list<unsigned>::iterator threads = (*activeThreads).begin(); 1581062SN/A list<unsigned>::iterator list_end = (*activeThreads).end(); 1591062SN/A 1602292SN/A while (threads != list_end) { 1612292SN/A if (robPolicy == Partitioned) { 1622292SN/A maxEntries[*threads++] = numEntries / active_threads; 1632292SN/A } else if (robPolicy == Threshold && active_threads == 1) { 1641062SN/A maxEntries[*threads++] = numEntries; 1651062SN/A } 1661062SN/A } 1671062SN/A } 1681062SN/A} 1691062SN/A 1701062SN/Atemplate <class Impl> 1712292SN/Aint 1722292SN/AROB<Impl>::entryAmount(int num_threads) 1732292SN/A{ 1742292SN/A if (robPolicy == Partitioned) { 1752292SN/A return numEntries / num_threads; 1762292SN/A } else { 1772292SN/A return 0; 1782292SN/A } 1792292SN/A} 1802292SN/A 1812301SN/Atemplate <class Impl> 1822727Sktlim@umich.eduint 1832353SN/AROB<Impl>::countInsts() 1842727Sktlim@umich.edu{ 1852727Sktlim@umich.edu int total=0; 1862727Sktlim@umich.edu 1876221Snate@binkert.org for (int i=0;i < numThreads;i++) 1882353SN/A total += countInsts(i); 1892727Sktlim@umich.edu 1902727Sktlim@umich.edu return total; 1912727Sktlim@umich.edu} 1922727Sktlim@umich.edu 1932353SN/Atemplate <class Impl> 1942727Sktlim@umich.eduint 1952727Sktlim@umich.eduROB<Impl>::countInsts(unsigned tid) 1962727Sktlim@umich.edu{ 1976221Snate@binkert.org return instList[tid].size(); 1988240Snate@binkert.org} 1992301SN/A 2002727Sktlim@umich.edutemplate <class Impl> 2012301SN/Avoid 2022727Sktlim@umich.eduROB<Impl>::insertInst(DynInstPtr &inst) 2036221Snate@binkert.org{ 2048240Snate@binkert.org // Make sure we have the right number of instructions. 2052301SN/A //assert(numInstsInROB == countInsts()); 2062727Sktlim@umich.edu 2072301SN/A // Make sure the instruction is valid. 2082727Sktlim@umich.edu assert(inst); 2096221Snate@binkert.org 2108240Snate@binkert.org DPRINTF(ROB, "Adding inst PC %#x to the ROB.\n", inst->readPC()); 2112301SN/A 2122727Sktlim@umich.edu // If the ROB is full then exit. 2132301SN/A assert(numInstsInROB != numEntries); 2142727Sktlim@umich.edu 2156221Snate@binkert.org int tid = inst->threadNumber; 2168240Snate@binkert.org 2172301SN/A // Place into ROB 2182727Sktlim@umich.edu instList[tid].push_back(inst); 2192301SN/A 2202301SN/A //Set Up head iterator if this is the 1st instruction in the ROB 2218240Snate@binkert.org if (numInstsInROB == 0) { 2222301SN/A head = instList[tid].begin(); 2232727Sktlim@umich.edu assert((*head) == inst); 2242727Sktlim@umich.edu } 2252727Sktlim@umich.edu 2262727Sktlim@umich.edu //Must Decrement for iterator to actually be valid since __.end() 2278240Snate@binkert.org //actually points to 1 after the last inst 2282727Sktlim@umich.edu tail = instList[tid].end(); 2292727Sktlim@umich.edu tail--; 2302727Sktlim@umich.edu 2312727Sktlim@umich.edu // Mark as set in ROB 2322301SN/A inst->setInROB(); 2332301SN/A 2346221Snate@binkert.org // Increment ROB count 2358240Snate@binkert.org ++numInstsInROB; 2362301SN/A ++threadEntries[tid]; 2372727Sktlim@umich.edu 2382301SN/A assert((*tail) == inst); 2392326SN/A 2406221Snate@binkert.org DPRINTF(ROB, "[tid:%i] Now has %d instructions.\n", tid, threadEntries[tid]); 2418240Snate@binkert.org} 2422301SN/A 2432727Sktlim@umich.edu// Whatever calls this function needs to ensure that it properly frees up 2442301SN/A// registers prior to this function. 2452326SN/Atemplate <class Impl> 2466221Snate@binkert.orgvoid 2478240Snate@binkert.orgROB<Impl>::retireHead() 2482301SN/A{ 2492727Sktlim@umich.edu //assert(numInstsInROB == countInsts()); 2502301SN/A assert(numInstsInROB > 0); 2512326SN/A 2526221Snate@binkert.org // Get the head ROB instruction's TID. 2538240Snate@binkert.org int tid = (*head)->threadNumber; 2542301SN/A 2552727Sktlim@umich.edu retireHead(tid); 2562301SN/A 2572326SN/A if (numInstsInROB == 0) { 2586221Snate@binkert.org tail = instList[tid].end(); 2598240Snate@binkert.org } 2602301SN/A} 2612727Sktlim@umich.edu 2622301SN/Atemplate <class Impl> 2632326SN/Avoid 2648240Snate@binkert.orgROB<Impl>::retireHead(unsigned tid) 2652301SN/A{ 2662727Sktlim@umich.edu //assert(numInstsInROB == countInsts()); 2672301SN/A assert(numInstsInROB > 0); 2682326SN/A 2692301SN/A // Get the head ROB instruction. 2702326SN/A InstIt head_it = instList[tid].begin(); 2718240Snate@binkert.org 2722301SN/A DynInstPtr head_inst = (*head_it); 2732727Sktlim@umich.edu 2742301SN/A // Make certain this can retire. 2752326SN/A assert(head_inst->readyToCommit()); 2762301SN/A 2772326SN/A DPRINTF(ROB, "[tid:%u]: Retiring head instruction, " 2788240Snate@binkert.org "instruction PC %#x,[sn:%lli]\n", tid, head_inst->readPC(), 2792301SN/A head_inst->seqNum); 2802727Sktlim@umich.edu 2812326SN/A // Keep track of how many instructions are in the ROB. 2821062SN/A --numInstsInROB; 2831062SN/A --threadEntries[tid]; 2841681SN/A 2851060SN/A //Mark DynInstFlags 2869427SAndreas.Sandberg@ARM.com head_inst->removeInROB(); 2871060SN/A head_inst->setCommitted(); 2886221Snate@binkert.org 2892292SN/A instList[tid].erase(head_it); 2902292SN/A 2912292SN/A //Update "Global" Head of ROB 2922292SN/A updateHead(); 2932292SN/A 2942292SN/A // A special case is needed if the instruction being retired is the 2952292SN/A // only instruction in the ROB; otherwise the tail iterator will become 2962292SN/A // invalidated. 2972292SN/A cpu->removeFrontInst(head_inst); 2988887Sgeoffrey.blake@arm.com} 2998733Sgeoffrey.blake@arm.com 3008850Sandreas.hansson@arm.comtemplate <class Impl> 3018887Sgeoffrey.blake@arm.combool 3028733Sgeoffrey.blake@arm.comROB<Impl>::isHeadReady() 3032733Sktlim@umich.edu{ 3041060SN/A if (numInstsInROB != 0) { 3051060SN/A return (*head)->readyToCommit(); 3061681SN/A } 3071060SN/A 3082292SN/A return false; 3091060SN/A} 3101060SN/A 3111060SN/Atemplate <class Impl> 3121060SN/Abool 3131060SN/AROB<Impl>::isHeadReady(unsigned tid) 3141060SN/A{ 3151060SN/A if (threadEntries[tid] != 0) { 3161060SN/A return instList[tid].front()->readyToCommit(); 3171060SN/A } 3182292SN/A 3192292SN/A return false; 3201060SN/A} 3211060SN/A 3221060SN/Atemplate <class Impl> 3231060SN/Abool 3241681SN/AROB<Impl>::canCommit() 3251060SN/A{ 3262292SN/A //@todo: set ActiveThreads through ROB or CPU 3271060SN/A list<unsigned>::iterator threads = (*activeThreads).begin(); 3281060SN/A 3291060SN/A while (threads != (*activeThreads).end()) { 3301060SN/A unsigned tid = *threads++; 3311060SN/A 3321060SN/A if (isHeadReady(tid)) { 3331060SN/A return true; 3341681SN/A } 3351060SN/A } 3362292SN/A 3371060SN/A return false; 3381060SN/A} 3391060SN/A 3401060SN/Atemplate <class Impl> 3411060SN/Aunsigned 3421060SN/AROB<Impl>::numFreeEntries() 3431060SN/A{ 3441681SN/A //assert(numInstsInROB == countInsts()); 3451060SN/A 3466221Snate@binkert.org return numEntries - numInstsInROB; 3471060SN/A} 3482292SN/A 3492292SN/Atemplate <class Impl> 3502292SN/Aunsigned 3512292SN/AROB<Impl>::numFreeEntries(unsigned tid) 3521060SN/A{ 3531060SN/A return maxEntries[tid] - threadEntries[tid]; 3541681SN/A} 3551060SN/A 3562292SN/Atemplate <class Impl> 3571060SN/Avoid 3582292SN/AROB<Impl>::doSquash(unsigned tid) 3591060SN/A{ 3601060SN/A DPRINTF(ROB, "[tid:%u]: Squashing instructions until [sn:%i].\n", 3612307SN/A tid, squashedSeqNum); 3622863Sktlim@umich.edu 3639444SAndreas.Sandberg@ARM.com assert(squashIt[tid] != instList[tid].end()); 3642307SN/A 3659444SAndreas.Sandberg@ARM.com if ((*squashIt[tid])->seqNum < squashedSeqNum) { 3669444SAndreas.Sandberg@ARM.com DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n", 3679444SAndreas.Sandberg@ARM.com tid); 3689444SAndreas.Sandberg@ARM.com 3699444SAndreas.Sandberg@ARM.com squashIt[tid] = instList[tid].end(); 3709444SAndreas.Sandberg@ARM.com 3719444SAndreas.Sandberg@ARM.com doneSquashing[tid] = true; 3729444SAndreas.Sandberg@ARM.com return; 3739444SAndreas.Sandberg@ARM.com } 3749444SAndreas.Sandberg@ARM.com 3759444SAndreas.Sandberg@ARM.com bool robTailUpdate = false; 3769444SAndreas.Sandberg@ARM.com 3779444SAndreas.Sandberg@ARM.com for (int numSquashed = 0; 3789444SAndreas.Sandberg@ARM.com numSquashed < squashWidth && 3791681SN/A squashIt[tid] != instList[tid].end() && 3801681SN/A (*squashIt[tid])->seqNum > squashedSeqNum; 3812316SN/A ++numSquashed) 3821681SN/A { 3839444SAndreas.Sandberg@ARM.com DPRINTF(ROB, "[tid:%u]: Squashing instruction PC %#x, seq num %i.\n", 3842843Sktlim@umich.edu (*squashIt[tid])->threadNumber, 3859444SAndreas.Sandberg@ARM.com (*squashIt[tid])->readPC(), 3862843Sktlim@umich.edu (*squashIt[tid])->seqNum); 3879444SAndreas.Sandberg@ARM.com 3889444SAndreas.Sandberg@ARM.com // Mark the instruction as squashed, and ready to commit so that 3899444SAndreas.Sandberg@ARM.com // it can drain out of the pipeline. 3901681SN/A (*squashIt[tid])->setSquashed(); 3911681SN/A 3922307SN/A (*squashIt[tid])->setCanCommit(); 3931681SN/A 3942307SN/A 3951060SN/A if (squashIt[tid] == instList[tid].begin()) { 3962348SN/A DPRINTF(ROB, "Reached head of instruction list while " 3972307SN/A "squashing.\n"); 3982307SN/A 3992307SN/A squashIt[tid] = instList[tid].end(); 4001060SN/A 4012307SN/A doneSquashing[tid] = true; 4022307SN/A 4039444SAndreas.Sandberg@ARM.com return; 4041060SN/A } 4059427SAndreas.Sandberg@ARM.com 4062307SN/A InstIt tail_thread = instList[tid].end(); 4071060SN/A tail_thread--; 4086221Snate@binkert.org 4096221Snate@binkert.org if ((*squashIt[tid]) == (*tail_thread)) 4106221Snate@binkert.org robTailUpdate = true; 4116221Snate@binkert.org 4122307SN/A squashIt[tid]--; 4131060SN/A } 4142307SN/A 4152307SN/A 4162873Sktlim@umich.edu // Check if ROB is done squashing. 4172307SN/A if ((*squashIt[tid])->seqNum <= squashedSeqNum) { 4181060SN/A DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n", 4191060SN/A tid); 4201060SN/A 4211681SN/A squashIt[tid] = instList[tid].end(); 4221060SN/A 4236221Snate@binkert.org doneSquashing[tid] = true; 4242107SN/A } 4256221Snate@binkert.org 4262107SN/A if (robTailUpdate) { 4272292SN/A updateTail(); 4282292SN/A } 4292107SN/A} 4302292SN/A 4312326SN/A 4322292SN/Atemplate <class Impl> 4332107SN/Avoid 4342292SN/AROB<Impl>::updateHead() 4352935Sksewell@umich.edu{ 4364632Sgblack@eecs.umich.edu DynInstPtr head_inst; 4372935Sksewell@umich.edu InstSeqNum lowest_num = 0; 4382292SN/A bool first_valid = true; 4392292SN/A 4402292SN/A // @todo: set ActiveThreads through ROB or CPU 4412292SN/A list<unsigned>::iterator threads = (*activeThreads).begin(); 4422292SN/A 4432107SN/A while (threads != (*activeThreads).end()) { 4442292SN/A unsigned thread_num = *threads++; 4452107SN/A 4462292SN/A if (instList[thread_num].empty()) 4472292SN/A continue; 4482107SN/A 4492702Sktlim@umich.edu if (first_valid) { 4502107SN/A head = instList[thread_num].begin(); 4512107SN/A lowest_num = (*head)->seqNum; 4522107SN/A first_valid = false; 4532107SN/A continue; 4546221Snate@binkert.org } 4552292SN/A 4567720Sgblack@eecs.umich.edu InstIt head_thread = instList[thread_num].begin(); 4577720Sgblack@eecs.umich.edu 4582292SN/A DynInstPtr head_inst = (*head_thread); 4597852SMatt.Horsnell@arm.com 4607852SMatt.Horsnell@arm.com assert(head_inst != 0); 4617852SMatt.Horsnell@arm.com 4627852SMatt.Horsnell@arm.com if (head_inst->seqNum < lowest_num) { 4637852SMatt.Horsnell@arm.com head = head_thread; 4642935Sksewell@umich.edu lowest_num = head_inst->seqNum; 4657852SMatt.Horsnell@arm.com } 4667852SMatt.Horsnell@arm.com } 4672292SN/A 4687852SMatt.Horsnell@arm.com if (first_valid) { 4697852SMatt.Horsnell@arm.com head = instList[0].end(); 4707852SMatt.Horsnell@arm.com } 4712292SN/A 4727852SMatt.Horsnell@arm.com} 4737852SMatt.Horsnell@arm.com 4747852SMatt.Horsnell@arm.comtemplate <class Impl> 4752292SN/Avoid 4762292SN/AROB<Impl>::updateTail() 4772292SN/A{ 4782292SN/A tail = instList[0].end(); 4796221Snate@binkert.org bool first_valid = true; 4802292SN/A 4818513SGiacomo.Gabrielli@arm.com list<unsigned>::iterator threads = (*activeThreads).begin(); 4828513SGiacomo.Gabrielli@arm.com 4838513SGiacomo.Gabrielli@arm.com while (threads != (*activeThreads).end()) { 4848513SGiacomo.Gabrielli@arm.com unsigned tid = *threads++; 4858513SGiacomo.Gabrielli@arm.com 4868513SGiacomo.Gabrielli@arm.com if (instList[tid].empty()) { 4878513SGiacomo.Gabrielli@arm.com continue; 4888513SGiacomo.Gabrielli@arm.com } 4898513SGiacomo.Gabrielli@arm.com 4908513SGiacomo.Gabrielli@arm.com // If this is the first valid then assign w/out 4918513SGiacomo.Gabrielli@arm.com // comparison 4922292SN/A if (first_valid) { 4937852SMatt.Horsnell@arm.com tail = instList[tid].end(); 4948513SGiacomo.Gabrielli@arm.com tail--; 4958137SAli.Saidi@ARM.com first_valid = false; 4962292SN/A continue; 4978513SGiacomo.Gabrielli@arm.com } 4988513SGiacomo.Gabrielli@arm.com 4992292SN/A // Assign new tail if this thread's tail is younger 5007852SMatt.Horsnell@arm.com // than our current "tail high" 5017852SMatt.Horsnell@arm.com InstIt tail_thread = instList[tid].end(); 5022292SN/A tail_thread--; 5032292SN/A 5042292SN/A if ((*tail_thread)->seqNum > (*tail)->seqNum) { 5052292SN/A tail = tail_thread; 5066221Snate@binkert.org } 5072292SN/A } 5082292SN/A} 5097720Sgblack@eecs.umich.edu 5107852SMatt.Horsnell@arm.com 5117852SMatt.Horsnell@arm.comtemplate <class Impl> 5127852SMatt.Horsnell@arm.comvoid 5132292SN/AROB<Impl>::squash(InstSeqNum squash_num,unsigned tid) 5147852SMatt.Horsnell@arm.com{ 5157852SMatt.Horsnell@arm.com if (isEmpty()) { 5168137SAli.Saidi@ARM.com DPRINTF(ROB, "Does not need to squash due to being empty " 5172292SN/A "[sn:%i]\n", 5187852SMatt.Horsnell@arm.com squash_num); 5197852SMatt.Horsnell@arm.com 5202292SN/A return; 5217852SMatt.Horsnell@arm.com } 5222292SN/A 5237852SMatt.Horsnell@arm.com DPRINTF(ROB, "Starting to squash within the ROB.\n"); 5247852SMatt.Horsnell@arm.com 5252292SN/A robStatus[tid] = ROBSquashing; 5262292SN/A 5272292SN/A doneSquashing[tid] = false; 5282292SN/A 5296221Snate@binkert.org squashedSeqNum = squash_num; 5302292SN/A 5312292SN/A if (!instList[tid].empty()) { 5322292SN/A InstIt tail_thread = instList[tid].end(); 5332292SN/A tail_thread--; 5342292SN/A 5352292SN/A squashIt[tid] = tail_thread; 5362292SN/A 5372292SN/A doSquash(tid); 5382292SN/A } 5392292SN/A} 5402292SN/A 5412292SN/Atemplate <class Impl> 5422292SN/Atypename Impl::DynInstPtr 5432292SN/AROB<Impl>::readHeadInst() 5442292SN/A{ 5452292SN/A if (numInstsInROB != 0) { 5462292SN/A assert((*head)->isInROB()==true); 5472292SN/A return *head; 5486221Snate@binkert.org } else { 5492292SN/A return dummyInst; 5502292SN/A } 5512292SN/A} 5522292SN/A 5532292SN/Atemplate <class Impl> 5542292SN/Atypename Impl::DynInstPtr 5552292SN/AROB<Impl>::readHeadInst(unsigned tid) 5562292SN/A{ 5572292SN/A if (threadEntries[tid] != 0) { 5582292SN/A InstIt head_thread = instList[tid].begin(); 5592292SN/A 5602292SN/A assert((*head_thread)->isInROB()==true); 5612292SN/A 5622292SN/A return *head_thread; 5632292SN/A } else { 5642292SN/A return dummyInst; 5652292SN/A } 5661060SN/A} 5671681SN/A 5681060SN/Atemplate <class Impl> 5691060SN/Auint64_t 5702292SN/AROB<Impl>::readHeadPC() 5712292SN/A{ 5722292SN/A //assert(numInstsInROB == countInsts()); 5732292SN/A 5742292SN/A DynInstPtr head_inst = *head; 5752292SN/A 5761681SN/A return head_inst->readPC(); 5771681SN/A} 5781060SN/A 5792292SN/Atemplate <class Impl> 5801060SN/Auint64_t 5812292SN/AROB<Impl>::readHeadPC(unsigned tid) 5822292SN/A{ 5831060SN/A //assert(numInstsInROB == countInsts()); 5842292SN/A InstIt head_thread = instList[tid].begin(); 5852292SN/A 5862292SN/A return (*head_thread)->readPC(); 5872292SN/A} 5883221Sktlim@umich.edu 5893221Sktlim@umich.edu 5903221Sktlim@umich.edutemplate <class Impl> 5913221Sktlim@umich.eduuint64_t 5923221Sktlim@umich.eduROB<Impl>::readHeadNextPC() 5932292SN/A{ 5942292SN/A //assert(numInstsInROB == countInsts()); 5952292SN/A 5962292SN/A DynInstPtr head_inst = *head; 5972326SN/A 5982292SN/A return head_inst->readNextPC(); 5992292SN/A} 6002820Sktlim@umich.edu 6012292SN/Atemplate <class Impl> 6022292SN/Auint64_t 6032292SN/AROB<Impl>::readHeadNextPC(unsigned tid) 6042292SN/A{ 6052353SN/A //assert(numInstsInROB == countInsts()); 6062292SN/A InstIt head_thread = instList[tid].begin(); 6072292SN/A 6082353SN/A return (*head_thread)->readNextPC(); 6092353SN/A} 6102292SN/A 6112292SN/A 6122292SN/Atemplate <class Impl> 6132292SN/AInstSeqNum 6142292SN/AROB<Impl>::readHeadSeqNum() 6152292SN/A{ 6162292SN/A //assert(numInstsInROB == countInsts()); 6172292SN/A DynInstPtr head_inst = *head; 6182292SN/A 6192292SN/A return head_inst->seqNum; 6202292SN/A} 6212292SN/A 6222731Sktlim@umich.edutemplate <class Impl> 6232292SN/AInstSeqNum 6242292SN/AROB<Impl>::readHeadSeqNum(unsigned tid) 6252292SN/A{ 6262292SN/A InstIt head_thread = instList[tid].begin(); 6272292SN/A 6282292SN/A return ((*head_thread)->seqNum); 6292292SN/A} 6302292SN/A 6316221Snate@binkert.orgtemplate <class Impl> 6322292SN/Atypename Impl::DynInstPtr 6332292SN/AROB<Impl>::readTailInst() 6342292SN/A{ 6352292SN/A //assert(numInstsInROB == countInsts()); 6362292SN/A //assert(tail != instList[0].end()); 6372292SN/A 6382292SN/A return (*tail); 6392292SN/A} 6407720Sgblack@eecs.umich.edu 6412292SN/Atemplate <class Impl> 6427720Sgblack@eecs.umich.edutypename Impl::DynInstPtr 6432292SN/AROB<Impl>::readTailInst(unsigned tid) 6442292SN/A{ 6452292SN/A //assert(tail_thread[tid] != instList[tid].end()); 6462292SN/A 6472292SN/A InstIt tail_thread = instList[tid].end(); 6482292SN/A tail_thread--; 6492292SN/A 6502292SN/A return *tail_thread; 6512292SN/A} 6522292SN/A 6532292SN/A 6542292SN/Atemplate <class Impl> 6552292SN/Auint64_t 6562292SN/AROB<Impl>::readTailPC() 6576221Snate@binkert.org{ 6586221Snate@binkert.org //assert(numInstsInROB == countInsts()); 6592292SN/A 6603867Sbinkertn@umich.edu //assert(tail != instList[0].end()); 6616221Snate@binkert.org 6623867Sbinkertn@umich.edu return (*tail)->readPC(); 6632292SN/A} 6642292SN/A 6652292SN/Atemplate <class Impl> 6662292SN/Auint64_t 6672292SN/AROB<Impl>::readTailPC(unsigned tid) 6682292SN/A{ 6692292SN/A //assert(tail_thread[tid] != instList[tid].end()); 6702292SN/A 6712292SN/A InstIt tail_thread = instList[tid].end(); 6722292SN/A tail_thread--; 6732292SN/A 6746221Snate@binkert.org return (*tail_thread)->readPC(); 6756221Snate@binkert.org} 6762292SN/A 6773867Sbinkertn@umich.edutemplate <class Impl> 6786221Snate@binkert.orgInstSeqNum 6793867Sbinkertn@umich.eduROB<Impl>::readTailSeqNum() 6803867Sbinkertn@umich.edu{ 6812292SN/A // Return the last sequence number that has not been squashed. Other 6822292SN/A // stages can use it to squash any instructions younger than the current 6832292SN/A // tail. 6842292SN/A return (*tail)->seqNum; 6851062SN/A} 6861062SN/A 6871681SN/Atemplate <class Impl> 6881062SN/AInstSeqNum 6892292SN/AROB<Impl>::readTailSeqNum(unsigned tid) 6901062SN/A{ 6912292SN/A // Return the last sequence number that has not been squashed. Other 6921062SN/A // stages can use it to squash any instructions younger than the current 6936221Snate@binkert.org // tail. 6946221Snate@binkert.org // assert(tail_thread[tid] != instList[tid].end()); 6951062SN/A 6963867Sbinkertn@umich.edu InstIt tail_thread = instList[tid].end(); 6976221Snate@binkert.org tail_thread--; 6981062SN/A 6992292SN/A return (*tail_thread)->seqNum; 7002292SN/A} 7012292SN/A 7022292SN/A