rob_impl.hh revision 2307
12623SN/A/* 22623SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 32623SN/A * All rights reserved. 42623SN/A * 52623SN/A * Redistribution and use in source and binary forms, with or without 62623SN/A * modification, are permitted provided that the following conditions are 72623SN/A * met: redistributions of source code must retain the above copyright 82623SN/A * notice, this list of conditions and the following disclaimer; 92623SN/A * redistributions in binary form must reproduce the above copyright 102623SN/A * notice, this list of conditions and the following disclaimer in the 112623SN/A * documentation and/or other materials provided with the distribution; 122623SN/A * neither the name of the copyright holders nor the names of its 132623SN/A * contributors may be used to endorse or promote products derived from 142623SN/A * this software without specific prior written permission. 152623SN/A * 162623SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172623SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182623SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192623SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202623SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212623SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222623SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232623SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242623SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252623SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262623SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292623SN/A#include "config/full_system.hh" 302623SN/A#include "cpu/o3/rob.hh" 313170Sstever@eecs.umich.edu 322623SN/Ausing namespace std; 334040Ssaidi@eecs.umich.edu 342623SN/Atemplate <class Impl> 352623SN/AROB<Impl>::ROB(unsigned _numEntries, unsigned _squashWidth, 363348Sbinkertn@umich.edu string _smtROBPolicy, unsigned _smtROBThreshold, 373348Sbinkertn@umich.edu unsigned _numThreads) 382623SN/A : numEntries(_numEntries), 392901Ssaidi@eecs.umich.edu squashWidth(_squashWidth), 402623SN/A numInstsInROB(0), 412623SN/A squashedSeqNum(0), 422623SN/A numThreads(_numThreads) 432623SN/A{ 442856Srdreslin@umich.edu for (int tid=0; tid < numThreads; tid++) { 452856Srdreslin@umich.edu doneSquashing[tid] = true; 462856Srdreslin@umich.edu threadEntries[tid] = 0; 472856Srdreslin@umich.edu } 482856Srdreslin@umich.edu 492856Srdreslin@umich.edu string policy = _smtROBPolicy; 502856Srdreslin@umich.edu 512856Srdreslin@umich.edu //Convert string to lowercase 522856Srdreslin@umich.edu std::transform(policy.begin(), policy.end(), policy.begin(), 532856Srdreslin@umich.edu (int(*)(int)) tolower); 542623SN/A 552623SN/A //Figure out rob policy 562623SN/A if (policy == "dynamic") { 572623SN/A robPolicy = Dynamic; 582623SN/A 592623SN/A //Set Max Entries to Total ROB Capacity 602680Sktlim@umich.edu for (int i = 0; i < numThreads; i++) { 612680Sktlim@umich.edu maxEntries[i]=numEntries; 622623SN/A } 632623SN/A 642680Sktlim@umich.edu } else if (policy == "partitioned") { 652623SN/A robPolicy = Partitioned; 662623SN/A DPRINTF(Fetch, "ROB sharing policy set to Partitioned\n"); 672623SN/A 682623SN/A //@todo:make work if part_amt doesnt divide evenly. 692623SN/A int part_amt = numEntries / numThreads; 703349Sbinkertn@umich.edu 712623SN/A //Divide ROB up evenly 722623SN/A for (int i = 0; i < numThreads; i++) { 732623SN/A maxEntries[i]=part_amt; 742623SN/A } 752623SN/A 762623SN/A } else if (policy == "threshold") { 773349Sbinkertn@umich.edu robPolicy = Threshold; 782623SN/A DPRINTF(Fetch, "ROB sharing policy set to Threshold\n"); 793184Srdreslin@umich.edu 803184Srdreslin@umich.edu int threshold = _smtROBThreshold;; 812623SN/A 822623SN/A //Divide up by threshold amount 832623SN/A for (int i = 0; i < numThreads; i++) { 842623SN/A maxEntries[i]=threshold; 852623SN/A } 863647Srdreslin@umich.edu } else { 873647Srdreslin@umich.edu assert(0 && "Invalid ROB Sharing Policy.Options Are:{Dynamic," 883647Srdreslin@umich.edu "Partitioned, Threshold}"); 893647Srdreslin@umich.edu } 903647Srdreslin@umich.edu} 912631SN/A 923647Srdreslin@umich.edutemplate <class Impl> 932631SN/Astd::string 942623SN/AROB<Impl>::name() const 952623SN/A{ 962623SN/A return cpu->name() + ".rob"; 972948Ssaidi@eecs.umich.edu} 982948Ssaidi@eecs.umich.edu 993349Sbinkertn@umich.edutemplate <class Impl> 1002948Ssaidi@eecs.umich.eduvoid 1012948Ssaidi@eecs.umich.eduROB<Impl>::setCPU(FullCPU *cpu_ptr) 1022948Ssaidi@eecs.umich.edu{ 1032948Ssaidi@eecs.umich.edu cpu = cpu_ptr; 1042948Ssaidi@eecs.umich.edu 1052623SN/A // Set the per-thread iterators to the end of the instruction list. 1063170Sstever@eecs.umich.edu for (int i=0; i < numThreads;i++) { 1073170Sstever@eecs.umich.edu squashIt[i] = instList[i].end(); 1082623SN/A } 1092623SN/A 1103647Srdreslin@umich.edu // Initialize the "universal" ROB head & tail point to invalid 1113647Srdreslin@umich.edu // pointers 1123647Srdreslin@umich.edu head = instList[0].end(); 1133647Srdreslin@umich.edu tail = instList[0].end(); 1142623SN/A} 1152839Sktlim@umich.edu 1162867Sktlim@umich.edutemplate <class Impl> 1173222Sktlim@umich.eduvoid 1182901Ssaidi@eecs.umich.eduROB<Impl>::setActiveThreads(list<unsigned> *at_ptr) 1192623SN/A{ 1202623SN/A DPRINTF(ROB, "Setting active threads list pointer.\n"); 1212623SN/A activeThreads = at_ptr; 1222623SN/A} 1232623SN/A 1242623SN/Atemplate <class Impl> 1252623SN/Avoid 1262623SN/AROB<Impl>::switchOut() 1272623SN/A{ 1282623SN/A for (int tid = 0; tid < numThreads; tid++) { 1292915Sktlim@umich.edu instList[tid].clear(); 1302915Sktlim@umich.edu } 1312623SN/A} 1322623SN/A 1332623SN/Atemplate <class Impl> 1342623SN/Avoid 1352623SN/AROB<Impl>::takeOverFrom() 1362623SN/A{ 1372915Sktlim@umich.edu for (int tid=0; tid < numThreads; tid++) { 1382915Sktlim@umich.edu doneSquashing[tid] = true; 1392623SN/A threadEntries[tid] = 0; 1402798Sktlim@umich.edu squashIt[tid] = instList[tid].end(); 1412798Sktlim@umich.edu } 1422901Ssaidi@eecs.umich.edu numInstsInROB = 0; 1432839Sktlim@umich.edu 1442798Sktlim@umich.edu // Initialize the "universal" ROB head & tail point to invalid 1452839Sktlim@umich.edu // pointers 1462798Sktlim@umich.edu head = instList[0].end(); 1472798Sktlim@umich.edu tail = instList[0].end(); 1482901Ssaidi@eecs.umich.edu} 1492901Ssaidi@eecs.umich.edu 1502798Sktlim@umich.edutemplate <class Impl> 1512839Sktlim@umich.eduvoid 1522839Sktlim@umich.eduROB<Impl>::resetEntries() 1532901Ssaidi@eecs.umich.edu{ 1542798Sktlim@umich.edu if (robPolicy != Dynamic || numThreads > 1) { 1552623SN/A int active_threads = (*activeThreads).size(); 1562623SN/A 1572623SN/A list<unsigned>::iterator threads = (*activeThreads).begin(); 1582798Sktlim@umich.edu list<unsigned>::iterator list_end = (*activeThreads).end(); 1592623SN/A 1602798Sktlim@umich.edu while (threads != list_end) { 1613201Shsul@eecs.umich.edu if (robPolicy == Partitioned) { 1623201Shsul@eecs.umich.edu maxEntries[*threads++] = numEntries / active_threads; 1632867Sktlim@umich.edu } else if (robPolicy == Threshold && active_threads == 1) { 1642867Sktlim@umich.edu maxEntries[*threads++] = numEntries; 1652915Sktlim@umich.edu } 1662915Sktlim@umich.edu } 1672915Sktlim@umich.edu } 1682867Sktlim@umich.edu} 1692867Sktlim@umich.edu 1702867Sktlim@umich.edutemplate <class Impl> 1714471Sstever@eecs.umich.eduint 1722623SN/AROB<Impl>::entryAmount(int num_threads) 1732798Sktlim@umich.edu{ 1742901Ssaidi@eecs.umich.edu if (robPolicy == Partitioned) { 1753222Sktlim@umich.edu return numEntries / num_threads; 1762798Sktlim@umich.edu } else { 1772798Sktlim@umich.edu return 0; 1782798Sktlim@umich.edu } 1792798Sktlim@umich.edu} 1802798Sktlim@umich.edu 1812798Sktlim@umich.edutemplate <class Impl> 1822798Sktlim@umich.eduint 1833222Sktlim@umich.eduROB<Impl>::countInsts() 1842867Sktlim@umich.edu{ 1852867Sktlim@umich.edu int total=0; 1862867Sktlim@umich.edu 1872867Sktlim@umich.edu for (int i=0;i < numThreads;i++) 1882867Sktlim@umich.edu total += countInsts(i); 1892623SN/A 1902623SN/A return total; 1912623SN/A} 1922623SN/A 1932623SN/Atemplate <class Impl> 1942623SN/Aint 1954192Sktlim@umich.eduROB<Impl>::countInsts(unsigned tid) 1962623SN/A{ 1972680Sktlim@umich.edu return instList[tid].size(); 1982623SN/A} 1992680Sktlim@umich.edu 2002680Sktlim@umich.edutemplate <class Impl> 2012680Sktlim@umich.eduvoid 2022623SN/AROB<Impl>::insertInst(DynInstPtr &inst) 2032623SN/A{ 2042623SN/A // Make sure we have the right number of instructions. 2052623SN/A //assert(numInstsInROB == countInsts()); 2063201Shsul@eecs.umich.edu 2073201Shsul@eecs.umich.edu // Make sure the instruction is valid. 2083201Shsul@eecs.umich.edu assert(inst); 2093201Shsul@eecs.umich.edu 2102623SN/A DPRINTF(ROB, "Adding inst PC %#x to the ROB.\n", inst->readPC()); 2112623SN/A 2122623SN/A // If the ROB is full then exit. 2132623SN/A assert(numInstsInROB != numEntries); 2142623SN/A 2152623SN/A int tid = inst->threadNumber; 2162623SN/A 2172683Sktlim@umich.edu // Place into ROB 2182623SN/A instList[tid].push_back(inst); 2192623SN/A 2202623SN/A //Set Up head iterator if this is the 1st instruction in the ROB 2212623SN/A if (numInstsInROB == 0) { 2222623SN/A head = instList[tid].begin(); 2233686Sktlim@umich.edu assert((*head) == inst); 2242623SN/A } 2254471Sstever@eecs.umich.edu 2262623SN/A //Must Decrement for iterator to actually be valid since __.end() 2272623SN/A //actually points to 1 after the last inst 2282623SN/A tail = instList[tid].end(); 2292623SN/A tail--; 2302623SN/A 2312623SN/A // Mark as set in ROB 2322623SN/A inst->setInROB(); 2332683Sktlim@umich.edu 2342623SN/A // Increment ROB count 2352644Sstever@eecs.umich.edu ++numInstsInROB; 2362623SN/A ++threadEntries[tid]; 2372644Sstever@eecs.umich.edu 2382644Sstever@eecs.umich.edu assert((*tail) == inst); 2392623SN/A 2402623SN/A DPRINTF(ROB, "[tid:%i] Now has %d instructions.\n", tid, threadEntries[tid]); 2412623SN/A} 2422623SN/A 2432623SN/A// Whatever calls this function needs to ensure that it properly frees up 2442623SN/A// registers prior to this function. 2452623SN/Atemplate <class Impl> 2462623SN/Avoid 2472623SN/AROB<Impl>::retireHead() 2482623SN/A{ 2493169Sstever@eecs.umich.edu //assert(numInstsInROB == countInsts()); 2503169Sstever@eecs.umich.edu assert(numInstsInROB > 0); 2513170Sstever@eecs.umich.edu 2522623SN/A // Get the head ROB instruction's TID. 2532623SN/A int tid = (*head)->threadNumber; 2543169Sstever@eecs.umich.edu 2552623SN/A retireHead(tid); 2562623SN/A 2572623SN/A if (numInstsInROB == 0) { 2583169Sstever@eecs.umich.edu tail = instList[tid].end(); 2592623SN/A } 2602623SN/A} 2612623SN/A 2623349Sbinkertn@umich.edutemplate <class Impl> 2634878Sstever@eecs.umich.eduvoid 2644878Sstever@eecs.umich.eduROB<Impl>::retireHead(unsigned tid) 2654878Sstever@eecs.umich.edu{ 2664878Sstever@eecs.umich.edu //assert(numInstsInROB == countInsts()); 2673169Sstever@eecs.umich.edu assert(numInstsInROB > 0); 2682623SN/A 2693169Sstever@eecs.umich.edu // Get the head ROB instruction. 2702623SN/A InstIt head_it = instList[tid].begin(); 2713169Sstever@eecs.umich.edu 2722623SN/A DynInstPtr head_inst = (*head_it); 2732623SN/A 2743169Sstever@eecs.umich.edu // Make certain this can retire. 2752623SN/A assert(head_inst->readyToCommit()); 2762623SN/A 2774200Ssaidi@eecs.umich.edu DPRINTF(ROB, "[tid:%u]: Retiring head instruction, " 2784200Ssaidi@eecs.umich.edu "instruction PC %#x,[sn:%lli]\n", tid, head_inst->readPC(), 2794200Ssaidi@eecs.umich.edu head_inst->seqNum); 2804200Ssaidi@eecs.umich.edu 2813658Sktlim@umich.edu // Keep track of how many instructions are in the ROB. 2823658Sktlim@umich.edu --numInstsInROB; 2832623SN/A --threadEntries[tid]; 2842623SN/A 2852623SN/A //Mark DynInstFlags 2862623SN/A head_inst->removeInROB(); 2872623SN/A head_inst->setCommitted(); 2882623SN/A 2892623SN/A instList[tid].erase(head_it); 2902623SN/A 2912623SN/A //Update "Global" Head of ROB 2924040Ssaidi@eecs.umich.edu updateHead(); 2934040Ssaidi@eecs.umich.edu 2944040Ssaidi@eecs.umich.edu // A special case is needed if the instruction being retired is the 2954040Ssaidi@eecs.umich.edu // only instruction in the ROB; otherwise the tail iterator will become 2964115Ssaidi@eecs.umich.edu // invalidated. 2974115Ssaidi@eecs.umich.edu cpu->removeFrontInst(head_inst); 2984115Ssaidi@eecs.umich.edu} 2994115Ssaidi@eecs.umich.edu 3002623SN/Atemplate <class Impl> 3012623SN/Abool 3022623SN/AROB<Impl>::isHeadReady() 3032623SN/A{ 3042623SN/A if (numInstsInROB != 0) { 3052623SN/A return (*head)->readyToCommit(); 3062623SN/A } 3072623SN/A 3082623SN/A return false; 3092623SN/A} 3102623SN/A 3112623SN/Atemplate <class Impl> 3122623SN/Abool 3132623SN/AROB<Impl>::isHeadReady(unsigned tid) 3142623SN/A{ 3152623SN/A if (threadEntries[tid] != 0) { 3162623SN/A return instList[tid].front()->readyToCommit(); 3172623SN/A } 3182623SN/A 3192623SN/A return false; 3202623SN/A} 3212623SN/A 3222623SN/Atemplate <class Impl> 3232623SN/Abool 3242623SN/AROB<Impl>::canCommit() 3252623SN/A{ 3262623SN/A //@todo: set ActiveThreads through ROB or CPU 3272623SN/A list<unsigned>::iterator threads = (*activeThreads).begin(); 3282623SN/A 3292623SN/A while (threads != (*activeThreads).end()) { 3302623SN/A unsigned tid = *threads++; 3312623SN/A 3322623SN/A if (isHeadReady(tid)) { 3332623SN/A return true; 3342623SN/A } 3352623SN/A } 3362623SN/A 3372623SN/A return false; 3382623SN/A} 3392623SN/A 3402623SN/Atemplate <class Impl> 3412623SN/Aunsigned 3422623SN/AROB<Impl>::numFreeEntries() 3433169Sstever@eecs.umich.edu{ 3443169Sstever@eecs.umich.edu //assert(numInstsInROB == countInsts()); 3453170Sstever@eecs.umich.edu 3462623SN/A return numEntries - numInstsInROB; 3474040Ssaidi@eecs.umich.edu} 3484040Ssaidi@eecs.umich.edu 3494040Ssaidi@eecs.umich.edutemplate <class Impl> 3504040Ssaidi@eecs.umich.eduunsigned 3512623SN/AROB<Impl>::numFreeEntries(unsigned tid) 3523169Sstever@eecs.umich.edu{ 3533169Sstever@eecs.umich.edu return maxEntries[tid] - threadEntries[tid]; 3542623SN/A} 3552623SN/A 3564878Sstever@eecs.umich.edutemplate <class Impl> 3573170Sstever@eecs.umich.eduvoid 3583170Sstever@eecs.umich.eduROB<Impl>::doSquash(unsigned tid) 3593170Sstever@eecs.umich.edu{ 3604878Sstever@eecs.umich.edu DPRINTF(ROB, "[tid:%u]: Squashing instructions until [sn:%i].\n", 3613170Sstever@eecs.umich.edu tid, squashedSeqNum); 3624878Sstever@eecs.umich.edu 3634878Sstever@eecs.umich.edu assert(squashIt[tid] != instList[tid].end()); 3644878Sstever@eecs.umich.edu 3654878Sstever@eecs.umich.edu if ((*squashIt[tid])->seqNum < squashedSeqNum) { 3664878Sstever@eecs.umich.edu DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n", 3674878Sstever@eecs.umich.edu tid); 3684040Ssaidi@eecs.umich.edu 3693170Sstever@eecs.umich.edu squashIt[tid] = instList[tid].end(); 3704881Sstever@eecs.umich.edu 3714881Sstever@eecs.umich.edu doneSquashing[tid] = true; 3724881Sstever@eecs.umich.edu return; 3734881Sstever@eecs.umich.edu } 3744881Sstever@eecs.umich.edu 3754881Sstever@eecs.umich.edu bool robTailUpdate = false; 3764881Sstever@eecs.umich.edu 3773170Sstever@eecs.umich.edu for (int numSquashed = 0; 3783170Sstever@eecs.umich.edu numSquashed < squashWidth && 3793170Sstever@eecs.umich.edu squashIt[tid] != instList[tid].end() && 3803170Sstever@eecs.umich.edu (*squashIt[tid])->seqNum > squashedSeqNum; 3813170Sstever@eecs.umich.edu ++numSquashed) 3823170Sstever@eecs.umich.edu { 3833170Sstever@eecs.umich.edu DPRINTF(ROB, "[tid:%u]: Squashing instruction PC %#x, seq num %i.\n", 3843170Sstever@eecs.umich.edu (*squashIt[tid])->threadNumber, 3852623SN/A (*squashIt[tid])->readPC(), 3864200Ssaidi@eecs.umich.edu (*squashIt[tid])->seqNum); 3874200Ssaidi@eecs.umich.edu 3884200Ssaidi@eecs.umich.edu // Mark the instruction as squashed, and ready to commit so that 3893658Sktlim@umich.edu // it can drain out of the pipeline. 3903658Sktlim@umich.edu (*squashIt[tid])->setSquashed(); 3912623SN/A 3922623SN/A (*squashIt[tid])->setCanCommit(); 3932623SN/A 3942623SN/A 3952623SN/A if (squashIt[tid] == instList[tid].begin()) { 3962623SN/A DPRINTF(ROB, "Reached head of instruction list while " 3972623SN/A "squashing.\n"); 3982623SN/A 3992623SN/A squashIt[tid] = instList[tid].end(); 4002623SN/A 4012623SN/A doneSquashing[tid] = true; 4022623SN/A 4034224Sgblack@eecs.umich.edu return; 4044224Sgblack@eecs.umich.edu } 4054224Sgblack@eecs.umich.edu 4064224Sgblack@eecs.umich.edu InstIt tail_thread = instList[tid].end(); 4074224Sgblack@eecs.umich.edu tail_thread--; 4084224Sgblack@eecs.umich.edu 4094224Sgblack@eecs.umich.edu if ((*squashIt[tid]) == (*tail_thread)) 4104224Sgblack@eecs.umich.edu robTailUpdate = true; 4114224Sgblack@eecs.umich.edu 4124224Sgblack@eecs.umich.edu squashIt[tid]--; 4132623SN/A } 4142623SN/A 4152623SN/A 4162623SN/A // Check if ROB is done squashing. 4172623SN/A if ((*squashIt[tid])->seqNum <= squashedSeqNum) { 4182623SN/A DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n", 4192623SN/A tid); 4202623SN/A 4212623SN/A squashIt[tid] = instList[tid].end(); 4222623SN/A 4232623SN/A doneSquashing[tid] = true; 4242623SN/A } 4252623SN/A 4262623SN/A if (robTailUpdate) { 4272623SN/A updateTail(); 4282623SN/A } 4292623SN/A} 4302623SN/A 4312623SN/A 4322623SN/Atemplate <class Impl> 4332623SN/Avoid 4342623SN/AROB<Impl>::updateHead() 4352623SN/A{ 4362623SN/A DynInstPtr head_inst; 4372623SN/A InstSeqNum lowest_num = 0; 4382623SN/A bool first_valid = true; 4392623SN/A 4402623SN/A // @todo: set ActiveThreads through ROB or CPU 4412623SN/A list<unsigned>::iterator threads = (*activeThreads).begin(); 4422623SN/A 4432623SN/A while (threads != (*activeThreads).end()) { 4442623SN/A unsigned thread_num = *threads++; 4452623SN/A 4462623SN/A if (instList[thread_num].empty()) 4472623SN/A continue; 4482623SN/A 4492623SN/A if (first_valid) { 4502623SN/A head = instList[thread_num].begin(); 4512623SN/A lowest_num = (*head)->seqNum; 4522623SN/A first_valid = false; 4532623SN/A continue; 4542623SN/A } 4552623SN/A 4562623SN/A InstIt head_thread = instList[thread_num].begin(); 4572623SN/A 4582623SN/A DynInstPtr head_inst = (*head_thread); 4593387Sgblack@eecs.umich.edu 4603387Sgblack@eecs.umich.edu assert(head_inst != 0); 4612631SN/A 4622663Sstever@eecs.umich.edu if (head_inst->seqNum < lowest_num) { 4633170Sstever@eecs.umich.edu head = head_thread; 4642662Sstever@eecs.umich.edu lowest_num = head_inst->seqNum; 4652623SN/A } 4664022Sstever@eecs.umich.edu } 4672623SN/A 4682623SN/A if (first_valid) { 4692623SN/A head = instList[0].end(); 4702630SN/A } 4712623SN/A 4722623SN/A} 4732623SN/A 4742623SN/Atemplate <class Impl> 4752623SN/Avoid 4762623SN/AROB<Impl>::updateTail() 4772623SN/A{ 4782623SN/A tail = instList[0].end(); 4792623SN/A bool first_valid = true; 4803658Sktlim@umich.edu 4813658Sktlim@umich.edu list<unsigned>::iterator threads = (*activeThreads).begin(); 4822644Sstever@eecs.umich.edu 4832644Sstever@eecs.umich.edu while (threads != (*activeThreads).end()) { 4842623SN/A unsigned tid = *threads++; 4853222Sktlim@umich.edu 4863222Sktlim@umich.edu if (instList[tid].empty()) { 4873222Sktlim@umich.edu continue; 4882623SN/A } 4892623SN/A 4902623SN/A // If this is the first valid then assign w/out 4912623SN/A // comparison 4922644Sstever@eecs.umich.edu if (first_valid) { 4932623SN/A tail = instList[tid].end(); 4942623SN/A tail--; 4952623SN/A first_valid = false; 4962631SN/A continue; 4972631SN/A } 4982631SN/A 4992631SN/A // Assign new tail if this thread's tail is younger 5002631SN/A // than our current "tail high" 5012631SN/A InstIt tail_thread = instList[tid].end(); 5022623SN/A tail_thread--; 5032623SN/A 5042623SN/A if ((*tail_thread)->seqNum > (*tail)->seqNum) { 5052623SN/A tail = tail_thread; 5063349Sbinkertn@umich.edu } 5072623SN/A } 5082623SN/A} 5092623SN/A 5104870Sstever@eecs.umich.edu 5112623SN/Atemplate <class Impl> 5122798Sktlim@umich.eduvoid 5132623SN/AROB<Impl>::squash(InstSeqNum squash_num,unsigned tid) 5142644Sstever@eecs.umich.edu{ 5153222Sktlim@umich.edu if (isEmpty()) { 5163222Sktlim@umich.edu DPRINTF(ROB, "Does not need to squash due to being empty " 5173222Sktlim@umich.edu "[sn:%i]\n", 5182839Sktlim@umich.edu squash_num); 5193658Sktlim@umich.edu 5203658Sktlim@umich.edu return; 5213658Sktlim@umich.edu } 5222839Sktlim@umich.edu 5232798Sktlim@umich.edu DPRINTF(ROB, "Starting to squash within the ROB.\n"); 5242798Sktlim@umich.edu 5252798Sktlim@umich.edu robStatus[tid] = ROBSquashing; 5262623SN/A 5272644Sstever@eecs.umich.edu doneSquashing[tid] = false; 5282623SN/A 5292623SN/A squashedSeqNum = squash_num; 5303170Sstever@eecs.umich.edu 5313170Sstever@eecs.umich.edu if (!instList[tid].empty()) { 5323170Sstever@eecs.umich.edu InstIt tail_thread = instList[tid].end(); 5333170Sstever@eecs.umich.edu tail_thread--; 5342644Sstever@eecs.umich.edu 5353170Sstever@eecs.umich.edu squashIt[tid] = tail_thread; 5363170Sstever@eecs.umich.edu 5373170Sstever@eecs.umich.edu doSquash(tid); 5383170Sstever@eecs.umich.edu } 5393170Sstever@eecs.umich.edu} 5403170Sstever@eecs.umich.edu 5413170Sstever@eecs.umich.edutemplate <class Impl> 5423170Sstever@eecs.umich.edutypename Impl::DynInstPtr 5433170Sstever@eecs.umich.eduROB<Impl>::readHeadInst() 5442644Sstever@eecs.umich.edu{ 5452644Sstever@eecs.umich.edu if (numInstsInROB != 0) { 5462644Sstever@eecs.umich.edu assert((*head)->isInROB()==true); 5472623SN/A return *head; 5482623SN/A } else { 5492623SN/A return dummyInst; 5502644Sstever@eecs.umich.edu } 5512644Sstever@eecs.umich.edu} 5522623SN/A 5533658Sktlim@umich.edutemplate <class Impl> 5543658Sktlim@umich.edutypename Impl::DynInstPtr 5553658Sktlim@umich.eduROB<Impl>::readHeadInst(unsigned tid) 5562623SN/A{ 5572623SN/A if (threadEntries[tid] != 0) { 5582948Ssaidi@eecs.umich.edu InstIt head_thread = instList[tid].begin(); 5592948Ssaidi@eecs.umich.edu 5602948Ssaidi@eecs.umich.edu assert((*head_thread)->isInROB()==true); 5612948Ssaidi@eecs.umich.edu 5622948Ssaidi@eecs.umich.edu return *head_thread; 5632623SN/A } else { 5642623SN/A return dummyInst; 5653349Sbinkertn@umich.edu } 5662623SN/A} 5673310Srdreslin@umich.edu 5683310Srdreslin@umich.edutemplate <class Impl> 5694584Ssaidi@eecs.umich.eduuint64_t 5702948Ssaidi@eecs.umich.eduROB<Impl>::readHeadPC() 5713495Sktlim@umich.edu{ 5723310Srdreslin@umich.edu //assert(numInstsInROB == countInsts()); 5733310Srdreslin@umich.edu 5743495Sktlim@umich.edu DynInstPtr head_inst = *head; 5752948Ssaidi@eecs.umich.edu 5763310Srdreslin@umich.edu return head_inst->readPC(); 5773310Srdreslin@umich.edu} 5784870Sstever@eecs.umich.edu 5794433Ssaidi@eecs.umich.edutemplate <class Impl> 5804433Ssaidi@eecs.umich.eduuint64_t 5814433Ssaidi@eecs.umich.eduROB<Impl>::readHeadPC(unsigned tid) 5824433Ssaidi@eecs.umich.edu{ 5834433Ssaidi@eecs.umich.edu //assert(numInstsInROB == countInsts()); 5844433Ssaidi@eecs.umich.edu InstIt head_thread = instList[tid].begin(); 5853310Srdreslin@umich.edu 5864433Ssaidi@eecs.umich.edu return (*head_thread)->readPC(); 5874433Ssaidi@eecs.umich.edu} 5882623SN/A 5892623SN/A 5902657Ssaidi@eecs.umich.edutemplate <class Impl> 5912623SN/Auint64_t 5922623SN/AROB<Impl>::readHeadNextPC() 5932623SN/A{ 5942623SN/A //assert(numInstsInROB == countInsts()); 5952623SN/A 5962623SN/A DynInstPtr head_inst = *head; 5973349Sbinkertn@umich.edu 5982657Ssaidi@eecs.umich.edu return head_inst->readNextPC(); 5992657Ssaidi@eecs.umich.edu} 6002657Ssaidi@eecs.umich.edu 6012657Ssaidi@eecs.umich.edutemplate <class Impl> 6022623SN/Auint64_t 6032623SN/AROB<Impl>::readHeadNextPC(unsigned tid) 6042623SN/A{ 6053349Sbinkertn@umich.edu //assert(numInstsInROB == countInsts()); 6062623SN/A InstIt head_thread = instList[tid].begin(); 6072623SN/A 6082623SN/A return (*head_thread)->readNextPC(); 6094870Sstever@eecs.umich.edu} 6102623SN/A 6112623SN/A 6122623SN/Atemplate <class Impl> 6133222Sktlim@umich.eduInstSeqNum 6143222Sktlim@umich.eduROB<Impl>::readHeadSeqNum() 6153184Srdreslin@umich.edu{ 6162623SN/A //assert(numInstsInROB == countInsts()); 6172623SN/A DynInstPtr head_inst = *head; 6184878Sstever@eecs.umich.edu 6193170Sstever@eecs.umich.edu return head_inst->seqNum; 6203170Sstever@eecs.umich.edu} 6213170Sstever@eecs.umich.edu 6222644Sstever@eecs.umich.edutemplate <class Impl> 6232644Sstever@eecs.umich.eduInstSeqNum 6242644Sstever@eecs.umich.eduROB<Impl>::readHeadSeqNum(unsigned tid) 6253184Srdreslin@umich.edu{ 6263227Sktlim@umich.edu InstIt head_thread = instList[tid].begin(); 6273201Shsul@eecs.umich.edu 6283201Shsul@eecs.umich.edu return ((*head_thread)->seqNum); 6293201Shsul@eecs.umich.edu} 6303201Shsul@eecs.umich.edu 6313201Shsul@eecs.umich.edutemplate <class Impl> 6323201Shsul@eecs.umich.edutypename Impl::DynInstPtr 6333201Shsul@eecs.umich.eduROB<Impl>::readTailInst() 6342644Sstever@eecs.umich.edu{ 6352623SN/A //assert(numInstsInROB == countInsts()); 6362623SN/A //assert(tail != instList[0].end()); 6372623SN/A 6382798Sktlim@umich.edu return (*tail); 6392839Sktlim@umich.edu} 6402798Sktlim@umich.edu 6412839Sktlim@umich.edutemplate <class Impl> 6422901Ssaidi@eecs.umich.edutypename Impl::DynInstPtr 6432839Sktlim@umich.eduROB<Impl>::readTailInst(unsigned tid) 6442798Sktlim@umich.edu{ 6452623SN/A //assert(tail_thread[tid] != instList[tid].end()); 6464192Sktlim@umich.edu 6474192Sktlim@umich.edu InstIt tail_thread = instList[tid].end(); 6484192Sktlim@umich.edu tail_thread--; 6494192Sktlim@umich.edu 6504192Sktlim@umich.edu return *tail_thread; 6514192Sktlim@umich.edu} 6524192Sktlim@umich.edu 6534192Sktlim@umich.edu 6544192Sktlim@umich.edutemplate <class Impl> 6554192Sktlim@umich.eduuint64_t 6564192Sktlim@umich.eduROB<Impl>::readTailPC() 6574192Sktlim@umich.edu{ 6582623SN/A //assert(numInstsInROB == countInsts()); 6593349Sbinkertn@umich.edu 6602623SN/A //assert(tail != instList[0].end()); 6613310Srdreslin@umich.edu 6623310Srdreslin@umich.edu return (*tail)->readPC(); 6634584Ssaidi@eecs.umich.edu} 6642948Ssaidi@eecs.umich.edu 6653495Sktlim@umich.edutemplate <class Impl> 6663310Srdreslin@umich.eduuint64_t 6673310Srdreslin@umich.eduROB<Impl>::readTailPC(unsigned tid) 6683495Sktlim@umich.edu{ 6692948Ssaidi@eecs.umich.edu //assert(tail_thread[tid] != instList[tid].end()); 6703310Srdreslin@umich.edu 6713310Srdreslin@umich.edu InstIt tail_thread = instList[tid].end(); 6724870Sstever@eecs.umich.edu tail_thread--; 6734433Ssaidi@eecs.umich.edu 6744433Ssaidi@eecs.umich.edu return (*tail_thread)->readPC(); 6754433Ssaidi@eecs.umich.edu} 6764433Ssaidi@eecs.umich.edu 6774433Ssaidi@eecs.umich.edutemplate <class Impl> 6784433Ssaidi@eecs.umich.eduInstSeqNum 6793310Srdreslin@umich.eduROB<Impl>::readTailSeqNum() 6804433Ssaidi@eecs.umich.edu{ 6814433Ssaidi@eecs.umich.edu // Return the last sequence number that has not been squashed. Other 6822948Ssaidi@eecs.umich.edu // stages can use it to squash any instructions younger than the current 6832948Ssaidi@eecs.umich.edu // tail. 6842948Ssaidi@eecs.umich.edu return (*tail)->seqNum; 6852948Ssaidi@eecs.umich.edu} 6862948Ssaidi@eecs.umich.edu 6872630SN/Atemplate <class Impl> 6882623SN/AInstSeqNum 6892623SN/AROB<Impl>::readTailSeqNum(unsigned tid) 6902657Ssaidi@eecs.umich.edu{ 6912623SN/A // Return the last sequence number that has not been squashed. Other 6922623SN/A // stages can use it to squash any instructions younger than the current 6932623SN/A // tail. 6942623SN/A // assert(tail_thread[tid] != instList[tid].end()); 6952623SN/A 6962623SN/A InstIt tail_thread = instList[tid].end(); 6973349Sbinkertn@umich.edu tail_thread--; 6982657Ssaidi@eecs.umich.edu 6992657Ssaidi@eecs.umich.edu return (*tail_thread)->seqNum; 7003170Sstever@eecs.umich.edu} 7012657Ssaidi@eecs.umich.edu 7022657Ssaidi@eecs.umich.edu