rob_impl.hh revision 6221:58a3c04e6344
16019Shines@cs.fsu.edu/* 26019Shines@cs.fsu.edu * Copyright (c) 2004-2006 The Regents of The University of Michigan 37178Sgblack@eecs.umich.edu * All rights reserved. 47178Sgblack@eecs.umich.edu * 57178Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67178Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77178Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87178Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97178Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107178Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117178Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127178Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137178Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 147178Sgblack@eecs.umich.edu * this software without specific prior written permission. 156019Shines@cs.fsu.edu * 166019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276019Shines@cs.fsu.edu * 286019Shines@cs.fsu.edu * Authors: Kevin Lim 296019Shines@cs.fsu.edu * Korey Sewell 306019Shines@cs.fsu.edu */ 316019Shines@cs.fsu.edu 326019Shines@cs.fsu.edu#include <list> 336019Shines@cs.fsu.edu 346019Shines@cs.fsu.edu#include "config/full_system.hh" 356019Shines@cs.fsu.edu#include "cpu/o3/rob.hh" 366019Shines@cs.fsu.edu 376019Shines@cs.fsu.eduusing namespace std; 386019Shines@cs.fsu.edu 396019Shines@cs.fsu.edutemplate <class Impl> 406019Shines@cs.fsu.eduROB<Impl>::ROB(O3CPU *_cpu, unsigned _numEntries, unsigned _squashWidth, 416019Shines@cs.fsu.edu std::string _smtROBPolicy, unsigned _smtROBThreshold, 426019Shines@cs.fsu.edu ThreadID _numThreads) 436019Shines@cs.fsu.edu : cpu(_cpu), 446019Shines@cs.fsu.edu numEntries(_numEntries), 456019Shines@cs.fsu.edu squashWidth(_squashWidth), 466019Shines@cs.fsu.edu numInstsInROB(0), 476019Shines@cs.fsu.edu numThreads(_numThreads) 486019Shines@cs.fsu.edu{ 496019Shines@cs.fsu.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 506019Shines@cs.fsu.edu squashedSeqNum[tid] = 0; 516019Shines@cs.fsu.edu doneSquashing[tid] = true; 526019Shines@cs.fsu.edu threadEntries[tid] = 0; 536019Shines@cs.fsu.edu } 546019Shines@cs.fsu.edu 556019Shines@cs.fsu.edu std::string policy = _smtROBPolicy; 566019Shines@cs.fsu.edu 576019Shines@cs.fsu.edu //Convert string to lowercase 586243Sgblack@eecs.umich.edu std::transform(policy.begin(), policy.end(), policy.begin(), 596243Sgblack@eecs.umich.edu (int(*)(int)) tolower); 606243Sgblack@eecs.umich.edu 616243Sgblack@eecs.umich.edu //Figure out rob policy 626243Sgblack@eecs.umich.edu if (policy == "dynamic") { 636019Shines@cs.fsu.edu robPolicy = Dynamic; 646019Shines@cs.fsu.edu 656019Shines@cs.fsu.edu //Set Max Entries to Total ROB Capacity 666019Shines@cs.fsu.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 676019Shines@cs.fsu.edu maxEntries[tid] = numEntries; 686019Shines@cs.fsu.edu } 696019Shines@cs.fsu.edu 706019Shines@cs.fsu.edu } else if (policy == "partitioned") { 716019Shines@cs.fsu.edu robPolicy = Partitioned; 726019Shines@cs.fsu.edu DPRINTF(Fetch, "ROB sharing policy set to Partitioned\n"); 736019Shines@cs.fsu.edu 746019Shines@cs.fsu.edu //@todo:make work if part_amt doesnt divide evenly. 756019Shines@cs.fsu.edu int part_amt = numEntries / numThreads; 766019Shines@cs.fsu.edu 776019Shines@cs.fsu.edu //Divide ROB up evenly 786019Shines@cs.fsu.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 796019Shines@cs.fsu.edu maxEntries[tid] = part_amt; 806019Shines@cs.fsu.edu } 816019Shines@cs.fsu.edu 826019Shines@cs.fsu.edu } else if (policy == "threshold") { 836019Shines@cs.fsu.edu robPolicy = Threshold; 846019Shines@cs.fsu.edu DPRINTF(Fetch, "ROB sharing policy set to Threshold\n"); 856019Shines@cs.fsu.edu 866019Shines@cs.fsu.edu int threshold = _smtROBThreshold;; 876019Shines@cs.fsu.edu 886019Shines@cs.fsu.edu //Divide up by threshold amount 896019Shines@cs.fsu.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 906019Shines@cs.fsu.edu maxEntries[tid] = threshold; 916019Shines@cs.fsu.edu } 926019Shines@cs.fsu.edu } else { 936019Shines@cs.fsu.edu assert(0 && "Invalid ROB Sharing Policy.Options Are:{Dynamic," 946252Sgblack@eecs.umich.edu "Partitioned, Threshold}"); 956243Sgblack@eecs.umich.edu } 966243Sgblack@eecs.umich.edu 976243Sgblack@eecs.umich.edu // Set the per-thread iterators to the end of the instruction list. 986019Shines@cs.fsu.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 996019Shines@cs.fsu.edu squashIt[tid] = instList[tid].end(); 1006019Shines@cs.fsu.edu } 1016019Shines@cs.fsu.edu 1026019Shines@cs.fsu.edu // Initialize the "universal" ROB head & tail point to invalid 1036252Sgblack@eecs.umich.edu // pointers 1046243Sgblack@eecs.umich.edu head = instList[0].end(); 1056243Sgblack@eecs.umich.edu tail = instList[0].end(); 1066243Sgblack@eecs.umich.edu} 1076019Shines@cs.fsu.edu 1086019Shines@cs.fsu.edutemplate <class Impl> 1096019Shines@cs.fsu.edustd::string 1106019Shines@cs.fsu.eduROB<Impl>::name() const 1116019Shines@cs.fsu.edu{ 1126019Shines@cs.fsu.edu return cpu->name() + ".rob"; 1136019Shines@cs.fsu.edu} 1146252Sgblack@eecs.umich.edu 1156243Sgblack@eecs.umich.edutemplate <class Impl> 1166243Sgblack@eecs.umich.eduvoid 1176243Sgblack@eecs.umich.eduROB<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 1186019Shines@cs.fsu.edu{ 1196019Shines@cs.fsu.edu DPRINTF(ROB, "Setting active threads list pointer.\n"); 1206019Shines@cs.fsu.edu activeThreads = at_ptr; 1216019Shines@cs.fsu.edu} 1226019Shines@cs.fsu.edu 1236019Shines@cs.fsu.edutemplate <class Impl> 1246019Shines@cs.fsu.eduvoid 1256019Shines@cs.fsu.eduROB<Impl>::switchOut() 1266019Shines@cs.fsu.edu{ 1276019Shines@cs.fsu.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 1286019Shines@cs.fsu.edu instList[tid].clear(); 1296019Shines@cs.fsu.edu } 1306019Shines@cs.fsu.edu} 1316019Shines@cs.fsu.edu 1326019Shines@cs.fsu.edutemplate <class Impl> 1336019Shines@cs.fsu.eduvoid 1346724Sgblack@eecs.umich.eduROB<Impl>::takeOverFrom() 1356724Sgblack@eecs.umich.edu{ 1366019Shines@cs.fsu.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 1376019Shines@cs.fsu.edu doneSquashing[tid] = true; 1386019Shines@cs.fsu.edu threadEntries[tid] = 0; 1396019Shines@cs.fsu.edu squashIt[tid] = instList[tid].end(); 1406019Shines@cs.fsu.edu } 1416252Sgblack@eecs.umich.edu numInstsInROB = 0; 1426243Sgblack@eecs.umich.edu 1436243Sgblack@eecs.umich.edu // Initialize the "universal" ROB head & tail point to invalid 1446243Sgblack@eecs.umich.edu // pointers 1456019Shines@cs.fsu.edu head = instList[0].end(); 1466019Shines@cs.fsu.edu tail = instList[0].end(); 1476019Shines@cs.fsu.edu} 1486019Shines@cs.fsu.edu 1496019Shines@cs.fsu.edutemplate <class Impl> 1506019Shines@cs.fsu.eduvoid 1517356Sgblack@eecs.umich.eduROB<Impl>::resetEntries() 1527356Sgblack@eecs.umich.edu{ 1537356Sgblack@eecs.umich.edu if (robPolicy != Dynamic || numThreads > 1) { 1547356Sgblack@eecs.umich.edu int active_threads = activeThreads->size(); 1557356Sgblack@eecs.umich.edu 1567356Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 1577356Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 1587356Sgblack@eecs.umich.edu 1597178Sgblack@eecs.umich.edu while (threads != end) { 1607178Sgblack@eecs.umich.edu ThreadID tid = *threads++; 1617178Sgblack@eecs.umich.edu 1627337Sgblack@eecs.umich.edu if (robPolicy == Partitioned) { 1637178Sgblack@eecs.umich.edu maxEntries[tid] = numEntries / active_threads; 1647178Sgblack@eecs.umich.edu } else if (robPolicy == Threshold && active_threads == 1) { 1657178Sgblack@eecs.umich.edu maxEntries[tid] = numEntries; 1667178Sgblack@eecs.umich.edu } 1677178Sgblack@eecs.umich.edu } 1687178Sgblack@eecs.umich.edu } 1697178Sgblack@eecs.umich.edu} 1707178Sgblack@eecs.umich.edu 1717178Sgblack@eecs.umich.edutemplate <class Impl> 1727178Sgblack@eecs.umich.eduint 1737178Sgblack@eecs.umich.eduROB<Impl>::entryAmount(ThreadID num_threads) 1747335Sgblack@eecs.umich.edu{ 1757335Sgblack@eecs.umich.edu if (robPolicy == Partitioned) { 1767335Sgblack@eecs.umich.edu return numEntries / num_threads; 1777335Sgblack@eecs.umich.edu } else { 1787335Sgblack@eecs.umich.edu return 0; 1797335Sgblack@eecs.umich.edu } 1807335Sgblack@eecs.umich.edu} 1817335Sgblack@eecs.umich.edu 1827335Sgblack@eecs.umich.edutemplate <class Impl> 1837335Sgblack@eecs.umich.eduint 1847335Sgblack@eecs.umich.eduROB<Impl>::countInsts() 1857335Sgblack@eecs.umich.edu{ 1867337Sgblack@eecs.umich.edu int total = 0; 1877335Sgblack@eecs.umich.edu 1887335Sgblack@eecs.umich.edu for (ThreadID tid = 0; tid < numThreads; tid++) 1897335Sgblack@eecs.umich.edu total += countInsts(tid); 1907335Sgblack@eecs.umich.edu 1917335Sgblack@eecs.umich.edu return total; 1927335Sgblack@eecs.umich.edu} 1937335Sgblack@eecs.umich.edu 1947335Sgblack@eecs.umich.edutemplate <class Impl> 1957335Sgblack@eecs.umich.eduint 1967335Sgblack@eecs.umich.eduROB<Impl>::countInsts(ThreadID tid) 1977335Sgblack@eecs.umich.edu{ 1987335Sgblack@eecs.umich.edu return instList[tid].size(); 1997178Sgblack@eecs.umich.edu} 2007178Sgblack@eecs.umich.edu 2017178Sgblack@eecs.umich.edutemplate <class Impl> 2027178Sgblack@eecs.umich.eduvoid 2037178Sgblack@eecs.umich.eduROB<Impl>::insertInst(DynInstPtr &inst) 2047178Sgblack@eecs.umich.edu{ 2057178Sgblack@eecs.umich.edu //assert(numInstsInROB == countInsts()); 2067178Sgblack@eecs.umich.edu assert(inst); 2077178Sgblack@eecs.umich.edu 2087178Sgblack@eecs.umich.edu DPRINTF(ROB, "Adding inst PC %#x to the ROB.\n", inst->readPC()); 2097178Sgblack@eecs.umich.edu 2107178Sgblack@eecs.umich.edu assert(numInstsInROB != numEntries); 2117178Sgblack@eecs.umich.edu 2127178Sgblack@eecs.umich.edu ThreadID tid = inst->threadNumber; 2137178Sgblack@eecs.umich.edu 2147178Sgblack@eecs.umich.edu instList[tid].push_back(inst); 2157178Sgblack@eecs.umich.edu 2167178Sgblack@eecs.umich.edu //Set Up head iterator if this is the 1st instruction in the ROB 2177178Sgblack@eecs.umich.edu if (numInstsInROB == 0) { 2187178Sgblack@eecs.umich.edu head = instList[tid].begin(); 2197178Sgblack@eecs.umich.edu assert((*head) == inst); 2207178Sgblack@eecs.umich.edu } 2217178Sgblack@eecs.umich.edu 2227178Sgblack@eecs.umich.edu //Must Decrement for iterator to actually be valid since __.end() 2237178Sgblack@eecs.umich.edu //actually points to 1 after the last inst 2247178Sgblack@eecs.umich.edu tail = instList[tid].end(); 2257178Sgblack@eecs.umich.edu tail--; 2267178Sgblack@eecs.umich.edu 2277178Sgblack@eecs.umich.edu inst->setInROB(); 2287346Sgblack@eecs.umich.edu 2297346Sgblack@eecs.umich.edu ++numInstsInROB; 2307346Sgblack@eecs.umich.edu ++threadEntries[tid]; 2317346Sgblack@eecs.umich.edu 2327346Sgblack@eecs.umich.edu assert((*tail) == inst); 2337346Sgblack@eecs.umich.edu 2347346Sgblack@eecs.umich.edu DPRINTF(ROB, "[tid:%i] Now has %d instructions.\n", tid, threadEntries[tid]); 2357346Sgblack@eecs.umich.edu} 2367346Sgblack@eecs.umich.edu 2377346Sgblack@eecs.umich.edu// Whatever calls this function needs to ensure that it properly frees up 2387178Sgblack@eecs.umich.edu// registers prior to this function. 2397346Sgblack@eecs.umich.edu/* 2407346Sgblack@eecs.umich.edutemplate <class Impl> 2417346Sgblack@eecs.umich.eduvoid 2427346Sgblack@eecs.umich.eduROB<Impl>::retireHead() 2437346Sgblack@eecs.umich.edu{ 2447346Sgblack@eecs.umich.edu //assert(numInstsInROB == countInsts()); 2457346Sgblack@eecs.umich.edu assert(numInstsInROB > 0); 2467346Sgblack@eecs.umich.edu 2477346Sgblack@eecs.umich.edu ThreadID tid = (*head)->threadNumber; 2487346Sgblack@eecs.umich.edu 2497346Sgblack@eecs.umich.edu retireHead(tid); 2507346Sgblack@eecs.umich.edu 2517346Sgblack@eecs.umich.edu if (numInstsInROB == 0) { 2527346Sgblack@eecs.umich.edu tail = instList[tid].end(); 2537346Sgblack@eecs.umich.edu } 2547178Sgblack@eecs.umich.edu} 2557337Sgblack@eecs.umich.edu*/ 2567337Sgblack@eecs.umich.edu 2577337Sgblack@eecs.umich.edutemplate <class Impl> 2587337Sgblack@eecs.umich.eduvoid 2597337Sgblack@eecs.umich.eduROB<Impl>::retireHead(ThreadID tid) 2607337Sgblack@eecs.umich.edu{ 2617337Sgblack@eecs.umich.edu //assert(numInstsInROB == countInsts()); 2627337Sgblack@eecs.umich.edu assert(numInstsInROB > 0); 2637337Sgblack@eecs.umich.edu 2647337Sgblack@eecs.umich.edu // Get the head ROB instruction. 2657337Sgblack@eecs.umich.edu InstIt head_it = instList[tid].begin(); 2667337Sgblack@eecs.umich.edu 2677337Sgblack@eecs.umich.edu DynInstPtr head_inst = (*head_it); 2687337Sgblack@eecs.umich.edu 2697337Sgblack@eecs.umich.edu assert(head_inst->readyToCommit()); 2707178Sgblack@eecs.umich.edu 2717178Sgblack@eecs.umich.edu DPRINTF(ROB, "[tid:%u]: Retiring head instruction, " 2727178Sgblack@eecs.umich.edu "instruction PC %#x,[sn:%lli]\n", tid, head_inst->readPC(), 2737178Sgblack@eecs.umich.edu head_inst->seqNum); 2747337Sgblack@eecs.umich.edu 2757337Sgblack@eecs.umich.edu --numInstsInROB; 2767337Sgblack@eecs.umich.edu --threadEntries[tid]; 2777337Sgblack@eecs.umich.edu 2787346Sgblack@eecs.umich.edu head_inst->clearInROB(); 2797346Sgblack@eecs.umich.edu head_inst->setCommitted(); 2807346Sgblack@eecs.umich.edu 2817346Sgblack@eecs.umich.edu instList[tid].erase(head_it); 2827346Sgblack@eecs.umich.edu 2837337Sgblack@eecs.umich.edu //Update "Global" Head of ROB 2847178Sgblack@eecs.umich.edu updateHead(); 2857321Sgblack@eecs.umich.edu 2867356Sgblack@eecs.umich.edu // @todo: A special case is needed if the instruction being 2877321Sgblack@eecs.umich.edu // retired is the only instruction in the ROB; otherwise the tail 2887356Sgblack@eecs.umich.edu // iterator will become invalidated. 2897356Sgblack@eecs.umich.edu cpu->removeFrontInst(head_inst); 2907356Sgblack@eecs.umich.edu} 2917356Sgblack@eecs.umich.edu/* 2927356Sgblack@eecs.umich.edutemplate <class Impl> 2937356Sgblack@eecs.umich.edubool 2947356Sgblack@eecs.umich.eduROB<Impl>::isHeadReady() 2957356Sgblack@eecs.umich.edu{ 2967356Sgblack@eecs.umich.edu if (numInstsInROB != 0) { 2977356Sgblack@eecs.umich.edu return (*head)->readyToCommit(); 2987356Sgblack@eecs.umich.edu } 2997356Sgblack@eecs.umich.edu 3007321Sgblack@eecs.umich.edu return false; 3017321Sgblack@eecs.umich.edu} 3027321Sgblack@eecs.umich.edu*/ 3037321Sgblack@eecs.umich.edutemplate <class Impl> 3047321Sgblack@eecs.umich.edubool 3057321Sgblack@eecs.umich.eduROB<Impl>::isHeadReady(ThreadID tid) 3067321Sgblack@eecs.umich.edu{ 3077321Sgblack@eecs.umich.edu if (threadEntries[tid] != 0) { 3087321Sgblack@eecs.umich.edu return instList[tid].front()->readyToCommit(); 3097321Sgblack@eecs.umich.edu } 3107321Sgblack@eecs.umich.edu 3117335Sgblack@eecs.umich.edu return false; 3127335Sgblack@eecs.umich.edu} 3137335Sgblack@eecs.umich.edu 3147335Sgblack@eecs.umich.edutemplate <class Impl> 3157335Sgblack@eecs.umich.edubool 3167335Sgblack@eecs.umich.eduROB<Impl>::canCommit() 3177335Sgblack@eecs.umich.edu{ 3187335Sgblack@eecs.umich.edu //@todo: set ActiveThreads through ROB or CPU 3197335Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 3207321Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 3217323Sgblack@eecs.umich.edu 3227323Sgblack@eecs.umich.edu while (threads != end) { 3237323Sgblack@eecs.umich.edu ThreadID tid = *threads++; 3247323Sgblack@eecs.umich.edu 3257323Sgblack@eecs.umich.edu if (isHeadReady(tid)) { 3267323Sgblack@eecs.umich.edu return true; 3277323Sgblack@eecs.umich.edu } 3287323Sgblack@eecs.umich.edu } 3297323Sgblack@eecs.umich.edu 3307323Sgblack@eecs.umich.edu return false; 3317323Sgblack@eecs.umich.edu} 3327323Sgblack@eecs.umich.edu 3337323Sgblack@eecs.umich.edutemplate <class Impl> 3347323Sgblack@eecs.umich.eduunsigned 3357323Sgblack@eecs.umich.eduROB<Impl>::numFreeEntries() 3367323Sgblack@eecs.umich.edu{ 3377323Sgblack@eecs.umich.edu //assert(numInstsInROB == countInsts()); 3387321Sgblack@eecs.umich.edu 3397321Sgblack@eecs.umich.edu return numEntries - numInstsInROB; 3407321Sgblack@eecs.umich.edu} 3417335Sgblack@eecs.umich.edu 3427335Sgblack@eecs.umich.edutemplate <class Impl> 3437335Sgblack@eecs.umich.eduunsigned 3447335Sgblack@eecs.umich.eduROB<Impl>::numFreeEntries(ThreadID tid) 3457335Sgblack@eecs.umich.edu{ 3467335Sgblack@eecs.umich.edu return maxEntries[tid] - threadEntries[tid]; 3477335Sgblack@eecs.umich.edu} 3487335Sgblack@eecs.umich.edu 3497335Sgblack@eecs.umich.edutemplate <class Impl> 3507335Sgblack@eecs.umich.eduvoid 3517335Sgblack@eecs.umich.eduROB<Impl>::doSquash(ThreadID tid) 3527335Sgblack@eecs.umich.edu{ 3537335Sgblack@eecs.umich.edu DPRINTF(ROB, "[tid:%u]: Squashing instructions until [sn:%i].\n", 3547335Sgblack@eecs.umich.edu tid, squashedSeqNum[tid]); 3557335Sgblack@eecs.umich.edu 3567335Sgblack@eecs.umich.edu assert(squashIt[tid] != instList[tid].end()); 3577335Sgblack@eecs.umich.edu 3587335Sgblack@eecs.umich.edu if ((*squashIt[tid])->seqNum < squashedSeqNum[tid]) { 3597335Sgblack@eecs.umich.edu DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n", 3607335Sgblack@eecs.umich.edu tid); 3617335Sgblack@eecs.umich.edu 3627335Sgblack@eecs.umich.edu squashIt[tid] = instList[tid].end(); 3637335Sgblack@eecs.umich.edu 3647335Sgblack@eecs.umich.edu doneSquashing[tid] = true; 3657335Sgblack@eecs.umich.edu return; 3667335Sgblack@eecs.umich.edu } 3677335Sgblack@eecs.umich.edu 3687335Sgblack@eecs.umich.edu bool robTailUpdate = false; 3697335Sgblack@eecs.umich.edu 3707335Sgblack@eecs.umich.edu for (int numSquashed = 0; 3717335Sgblack@eecs.umich.edu numSquashed < squashWidth && 3727335Sgblack@eecs.umich.edu squashIt[tid] != instList[tid].end() && 3737335Sgblack@eecs.umich.edu (*squashIt[tid])->seqNum > squashedSeqNum[tid]; 3747321Sgblack@eecs.umich.edu ++numSquashed) 3757321Sgblack@eecs.umich.edu { 3767321Sgblack@eecs.umich.edu DPRINTF(ROB, "[tid:%u]: Squashing instruction PC %#x, seq num %i.\n", 3777321Sgblack@eecs.umich.edu (*squashIt[tid])->threadNumber, 3787321Sgblack@eecs.umich.edu (*squashIt[tid])->readPC(), 3797321Sgblack@eecs.umich.edu (*squashIt[tid])->seqNum); 3807335Sgblack@eecs.umich.edu 3817335Sgblack@eecs.umich.edu // Mark the instruction as squashed, and ready to commit so that 3827335Sgblack@eecs.umich.edu // it can drain out of the pipeline. 3837335Sgblack@eecs.umich.edu (*squashIt[tid])->setSquashed(); 3847335Sgblack@eecs.umich.edu 3857335Sgblack@eecs.umich.edu (*squashIt[tid])->setCanCommit(); 3867335Sgblack@eecs.umich.edu 3877335Sgblack@eecs.umich.edu 3887335Sgblack@eecs.umich.edu if (squashIt[tid] == instList[tid].begin()) { 3897321Sgblack@eecs.umich.edu DPRINTF(ROB, "Reached head of instruction list while " 3907326Sgblack@eecs.umich.edu "squashing.\n"); 3917326Sgblack@eecs.umich.edu 3927326Sgblack@eecs.umich.edu squashIt[tid] = instList[tid].end(); 3937326Sgblack@eecs.umich.edu 3947326Sgblack@eecs.umich.edu doneSquashing[tid] = true; 3957326Sgblack@eecs.umich.edu 3967326Sgblack@eecs.umich.edu return; 3977326Sgblack@eecs.umich.edu } 3987326Sgblack@eecs.umich.edu 3997326Sgblack@eecs.umich.edu InstIt tail_thread = instList[tid].end(); 4007326Sgblack@eecs.umich.edu tail_thread--; 4017326Sgblack@eecs.umich.edu 4027326Sgblack@eecs.umich.edu if ((*squashIt[tid]) == (*tail_thread)) 4037326Sgblack@eecs.umich.edu robTailUpdate = true; 4047326Sgblack@eecs.umich.edu 4057326Sgblack@eecs.umich.edu squashIt[tid]--; 4067326Sgblack@eecs.umich.edu } 4077326Sgblack@eecs.umich.edu 4087326Sgblack@eecs.umich.edu 4097326Sgblack@eecs.umich.edu // Check if ROB is done squashing. 4107326Sgblack@eecs.umich.edu if ((*squashIt[tid])->seqNum <= squashedSeqNum[tid]) { 4117326Sgblack@eecs.umich.edu DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n", 4127326Sgblack@eecs.umich.edu tid); 4137321Sgblack@eecs.umich.edu 4147321Sgblack@eecs.umich.edu squashIt[tid] = instList[tid].end(); 4157335Sgblack@eecs.umich.edu 4167335Sgblack@eecs.umich.edu doneSquashing[tid] = true; 4177335Sgblack@eecs.umich.edu } 4187335Sgblack@eecs.umich.edu 4197335Sgblack@eecs.umich.edu if (robTailUpdate) { 4207335Sgblack@eecs.umich.edu updateTail(); 4217335Sgblack@eecs.umich.edu } 4227335Sgblack@eecs.umich.edu} 4237335Sgblack@eecs.umich.edu 4247335Sgblack@eecs.umich.edu 4257335Sgblack@eecs.umich.edutemplate <class Impl> 4267335Sgblack@eecs.umich.eduvoid 4277335Sgblack@eecs.umich.eduROB<Impl>::updateHead() 4287335Sgblack@eecs.umich.edu{ 4297335Sgblack@eecs.umich.edu DynInstPtr head_inst; 4307335Sgblack@eecs.umich.edu InstSeqNum lowest_num = 0; 4317335Sgblack@eecs.umich.edu bool first_valid = true; 4327335Sgblack@eecs.umich.edu 4337335Sgblack@eecs.umich.edu // @todo: set ActiveThreads through ROB or CPU 4347335Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 4357335Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 4367335Sgblack@eecs.umich.edu 4377335Sgblack@eecs.umich.edu while (threads != end) { 4387335Sgblack@eecs.umich.edu ThreadID tid = *threads++; 4397335Sgblack@eecs.umich.edu 4407335Sgblack@eecs.umich.edu if (instList[tid].empty()) 4417335Sgblack@eecs.umich.edu continue; 4427335Sgblack@eecs.umich.edu 4437335Sgblack@eecs.umich.edu if (first_valid) { 4447335Sgblack@eecs.umich.edu head = instList[tid].begin(); 4457335Sgblack@eecs.umich.edu lowest_num = (*head)->seqNum; 4467335Sgblack@eecs.umich.edu first_valid = false; 4477335Sgblack@eecs.umich.edu continue; 4487335Sgblack@eecs.umich.edu } 4497335Sgblack@eecs.umich.edu 4507335Sgblack@eecs.umich.edu InstIt head_thread = instList[tid].begin(); 4517335Sgblack@eecs.umich.edu 4527335Sgblack@eecs.umich.edu DynInstPtr head_inst = (*head_thread); 4537335Sgblack@eecs.umich.edu 4547335Sgblack@eecs.umich.edu assert(head_inst != 0); 4557335Sgblack@eecs.umich.edu 4567335Sgblack@eecs.umich.edu if (head_inst->seqNum < lowest_num) { 4577335Sgblack@eecs.umich.edu head = head_thread; 4587335Sgblack@eecs.umich.edu lowest_num = head_inst->seqNum; 4597321Sgblack@eecs.umich.edu } 4607321Sgblack@eecs.umich.edu } 4617321Sgblack@eecs.umich.edu 4627321Sgblack@eecs.umich.edu if (first_valid) { 4637321Sgblack@eecs.umich.edu head = instList[0].end(); 4647356Sgblack@eecs.umich.edu } 4657356Sgblack@eecs.umich.edu 4667356Sgblack@eecs.umich.edu} 4677356Sgblack@eecs.umich.edu 4687356Sgblack@eecs.umich.edutemplate <class Impl> 4697356Sgblack@eecs.umich.eduvoid 4707363Sgblack@eecs.umich.eduROB<Impl>::updateTail() 4717363Sgblack@eecs.umich.edu{ 4727363Sgblack@eecs.umich.edu tail = instList[0].end(); 4737363Sgblack@eecs.umich.edu bool first_valid = true; 4747363Sgblack@eecs.umich.edu 4757363Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 4767363Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 4777363Sgblack@eecs.umich.edu 4787363Sgblack@eecs.umich.edu while (threads != end) { 4797363Sgblack@eecs.umich.edu ThreadID tid = *threads++; 4807363Sgblack@eecs.umich.edu 4817363Sgblack@eecs.umich.edu if (instList[tid].empty()) { 4827363Sgblack@eecs.umich.edu continue; 4837363Sgblack@eecs.umich.edu } 4847372Sgblack@eecs.umich.edu 4857372Sgblack@eecs.umich.edu // If this is the first valid then assign w/out 4867372Sgblack@eecs.umich.edu // comparison 4877372Sgblack@eecs.umich.edu if (first_valid) { 4887372Sgblack@eecs.umich.edu tail = instList[tid].end(); 4897372Sgblack@eecs.umich.edu tail--; 4907372Sgblack@eecs.umich.edu first_valid = false; 4917372Sgblack@eecs.umich.edu continue; 4927372Sgblack@eecs.umich.edu } 4937372Sgblack@eecs.umich.edu 4947372Sgblack@eecs.umich.edu // Assign new tail if this thread's tail is younger 4957372Sgblack@eecs.umich.edu // than our current "tail high" 4967372Sgblack@eecs.umich.edu InstIt tail_thread = instList[tid].end(); 4977372Sgblack@eecs.umich.edu tail_thread--; 4987372Sgblack@eecs.umich.edu 4997372Sgblack@eecs.umich.edu if ((*tail_thread)->seqNum > (*tail)->seqNum) { 5007372Sgblack@eecs.umich.edu tail = tail_thread; 5017372Sgblack@eecs.umich.edu } 5027372Sgblack@eecs.umich.edu } 5037363Sgblack@eecs.umich.edu} 5047363Sgblack@eecs.umich.edu 5057370Sgblack@eecs.umich.edu 5067372Sgblack@eecs.umich.edutemplate <class Impl> 5077376Sgblack@eecs.umich.eduvoid 5087376Sgblack@eecs.umich.eduROB<Impl>::squash(InstSeqNum squash_num, ThreadID tid) 5097370Sgblack@eecs.umich.edu{ 5107376Sgblack@eecs.umich.edu if (isEmpty()) { 5117376Sgblack@eecs.umich.edu DPRINTF(ROB, "Does not need to squash due to being empty " 5127370Sgblack@eecs.umich.edu "[sn:%i]\n", 5137370Sgblack@eecs.umich.edu squash_num); 5147372Sgblack@eecs.umich.edu 5157376Sgblack@eecs.umich.edu return; 5167376Sgblack@eecs.umich.edu } 5177370Sgblack@eecs.umich.edu 5187376Sgblack@eecs.umich.edu DPRINTF(ROB, "Starting to squash within the ROB.\n"); 5197376Sgblack@eecs.umich.edu 5207370Sgblack@eecs.umich.edu robStatus[tid] = ROBSquashing; 5217370Sgblack@eecs.umich.edu 5227371Sgblack@eecs.umich.edu doneSquashing[tid] = false; 5237371Sgblack@eecs.umich.edu 5247372Sgblack@eecs.umich.edu squashedSeqNum[tid] = squash_num; 5257376Sgblack@eecs.umich.edu 5267376Sgblack@eecs.umich.edu if (!instList[tid].empty()) { 5277371Sgblack@eecs.umich.edu InstIt tail_thread = instList[tid].end(); 5287376Sgblack@eecs.umich.edu tail_thread--; 5297376Sgblack@eecs.umich.edu 5307371Sgblack@eecs.umich.edu squashIt[tid] = tail_thread; 5317371Sgblack@eecs.umich.edu 5327372Sgblack@eecs.umich.edu doSquash(tid); 5337376Sgblack@eecs.umich.edu } 5347376Sgblack@eecs.umich.edu} 5357371Sgblack@eecs.umich.edu/* 5367376Sgblack@eecs.umich.edutemplate <class Impl> 5377376Sgblack@eecs.umich.edutypename Impl::DynInstPtr 5387371Sgblack@eecs.umich.eduROB<Impl>::readHeadInst() 5397371Sgblack@eecs.umich.edu{ 5407363Sgblack@eecs.umich.edu if (numInstsInROB != 0) { 5417363Sgblack@eecs.umich.edu assert((*head)->isInROB()==true); 5427372Sgblack@eecs.umich.edu return *head; 5437376Sgblack@eecs.umich.edu } else { 5447376Sgblack@eecs.umich.edu return dummyInst; 5457364Sgblack@eecs.umich.edu } 5467376Sgblack@eecs.umich.edu} 5477376Sgblack@eecs.umich.edu*/ 5487364Sgblack@eecs.umich.edu 5497371Sgblack@eecs.umich.edutemplate <class Impl> 5507372Sgblack@eecs.umich.edutypename Impl::DynInstPtr 5517376Sgblack@eecs.umich.eduROB<Impl>::readHeadInst(ThreadID tid) 5527376Sgblack@eecs.umich.edu{ 5537371Sgblack@eecs.umich.edu if (threadEntries[tid] != 0) { 5547376Sgblack@eecs.umich.edu InstIt head_thread = instList[tid].begin(); 5557376Sgblack@eecs.umich.edu 5567371Sgblack@eecs.umich.edu assert((*head_thread)->isInROB()==true); 5577363Sgblack@eecs.umich.edu 5587363Sgblack@eecs.umich.edu return *head_thread; 5597363Sgblack@eecs.umich.edu } else { 5607372Sgblack@eecs.umich.edu return dummyInst; 5617376Sgblack@eecs.umich.edu } 5627376Sgblack@eecs.umich.edu} 5637367Sgblack@eecs.umich.edu 5647376Sgblack@eecs.umich.edu/* 5657376Sgblack@eecs.umich.edutemplate <class Impl> 5667367Sgblack@eecs.umich.eduuint64_t 5677363Sgblack@eecs.umich.eduROB<Impl>::readHeadPC() 5687372Sgblack@eecs.umich.edu{ 5697376Sgblack@eecs.umich.edu //assert(numInstsInROB == countInsts()); 5707376Sgblack@eecs.umich.edu 5717368Sgblack@eecs.umich.edu DynInstPtr head_inst = *head; 5727376Sgblack@eecs.umich.edu 5737376Sgblack@eecs.umich.edu return head_inst->readPC(); 5747368Sgblack@eecs.umich.edu} 5757363Sgblack@eecs.umich.edu 5767363Sgblack@eecs.umich.edutemplate <class Impl> 5777363Sgblack@eecs.umich.eduuint64_t 5787372Sgblack@eecs.umich.eduROB<Impl>::readHeadPC(ThreadID tid) 5797376Sgblack@eecs.umich.edu{ 5807376Sgblack@eecs.umich.edu //assert(numInstsInROB == countInsts()); 5817369Sgblack@eecs.umich.edu InstIt head_thread = instList[tid].begin(); 5827376Sgblack@eecs.umich.edu 5837376Sgblack@eecs.umich.edu return (*head_thread)->readPC(); 5847369Sgblack@eecs.umich.edu} 5857363Sgblack@eecs.umich.edu 5867363Sgblack@eecs.umich.edu 5877363Sgblack@eecs.umich.edutemplate <class Impl> 5887363Sgblack@eecs.umich.eduuint64_t 5897363Sgblack@eecs.umich.eduROB<Impl>::readHeadNextPC() 5907363Sgblack@eecs.umich.edu{ 5917372Sgblack@eecs.umich.edu //assert(numInstsInROB == countInsts()); 5927363Sgblack@eecs.umich.edu 5937376Sgblack@eecs.umich.edu DynInstPtr head_inst = *head; 5947376Sgblack@eecs.umich.edu 5957363Sgblack@eecs.umich.edu return head_inst->readNextPC(); 5967363Sgblack@eecs.umich.edu} 5977376Sgblack@eecs.umich.edu 5987376Sgblack@eecs.umich.edutemplate <class Impl> 5997363Sgblack@eecs.umich.eduuint64_t 6007363Sgblack@eecs.umich.eduROB<Impl>::readHeadNextPC(ThreadID tid) 6017363Sgblack@eecs.umich.edu{ 6027363Sgblack@eecs.umich.edu //assert(numInstsInROB == countInsts()); 6037363Sgblack@eecs.umich.edu InstIt head_thread = instList[tid].begin(); 6047372Sgblack@eecs.umich.edu 6057376Sgblack@eecs.umich.edu return (*head_thread)->readNextPC(); 6067376Sgblack@eecs.umich.edu} 6077363Sgblack@eecs.umich.edu 6087376Sgblack@eecs.umich.edutemplate <class Impl> 6097376Sgblack@eecs.umich.eduInstSeqNum 6107363Sgblack@eecs.umich.eduROB<Impl>::readHeadSeqNum() 6117363Sgblack@eecs.umich.edu{ 6127372Sgblack@eecs.umich.edu //assert(numInstsInROB == countInsts()); 6137376Sgblack@eecs.umich.edu DynInstPtr head_inst = *head; 6147376Sgblack@eecs.umich.edu 6157366Sgblack@eecs.umich.edu return head_inst->seqNum; 6167376Sgblack@eecs.umich.edu} 6177376Sgblack@eecs.umich.edu 6187366Sgblack@eecs.umich.edutemplate <class Impl> 6197363Sgblack@eecs.umich.eduInstSeqNum 6207363Sgblack@eecs.umich.eduROB<Impl>::readHeadSeqNum(ThreadID tid) 6217363Sgblack@eecs.umich.edu{ 6227372Sgblack@eecs.umich.edu InstIt head_thread = instList[tid].begin(); 6237376Sgblack@eecs.umich.edu 6247376Sgblack@eecs.umich.edu return ((*head_thread)->seqNum); 6257365Sgblack@eecs.umich.edu} 6267376Sgblack@eecs.umich.edu 6277376Sgblack@eecs.umich.edutemplate <class Impl> 6287365Sgblack@eecs.umich.edutypename Impl::DynInstPtr 6297363Sgblack@eecs.umich.eduROB<Impl>::readTailInst() 6307372Sgblack@eecs.umich.edu{ 6317376Sgblack@eecs.umich.edu //assert(numInstsInROB == countInsts()); 6327376Sgblack@eecs.umich.edu //assert(tail != instList[0].end()); 6337369Sgblack@eecs.umich.edu 6347376Sgblack@eecs.umich.edu return (*tail); 6357376Sgblack@eecs.umich.edu} 6367369Sgblack@eecs.umich.edu*/ 6377363Sgblack@eecs.umich.edutemplate <class Impl> 6387363Sgblack@eecs.umich.edutypename Impl::DynInstPtr 6397363Sgblack@eecs.umich.eduROB<Impl>::readTailInst(ThreadID tid) 6407363Sgblack@eecs.umich.edu{ 6417363Sgblack@eecs.umich.edu //assert(tail_thread[tid] != instList[tid].end()); 6427363Sgblack@eecs.umich.edu 6437363Sgblack@eecs.umich.edu InstIt tail_thread = instList[tid].end(); 6447363Sgblack@eecs.umich.edu tail_thread--; 6457363Sgblack@eecs.umich.edu 6467363Sgblack@eecs.umich.edu return *tail_thread; 6477374Sgblack@eecs.umich.edu} 6487374Sgblack@eecs.umich.edu 6497374Sgblack@eecs.umich.edu/* 6507374Sgblack@eecs.umich.edutemplate <class Impl> 6517374Sgblack@eecs.umich.eduuint64_t 6527374Sgblack@eecs.umich.eduROB<Impl>::readTailPC() 6537374Sgblack@eecs.umich.edu{ 6547374Sgblack@eecs.umich.edu //assert(numInstsInROB == countInsts()); 6557374Sgblack@eecs.umich.edu 6567363Sgblack@eecs.umich.edu //assert(tail != instList[0].end()); 6577363Sgblack@eecs.umich.edu 6587363Sgblack@eecs.umich.edu return (*tail)->readPC(); 6597373Sgblack@eecs.umich.edu} 6607373Sgblack@eecs.umich.edu 6617373Sgblack@eecs.umich.edutemplate <class Impl> 6627373Sgblack@eecs.umich.eduuint64_t 6637373Sgblack@eecs.umich.eduROB<Impl>::readTailPC(ThreadID tid) 6647373Sgblack@eecs.umich.edu{ 6657373Sgblack@eecs.umich.edu //assert(tail_thread[tid] != instList[tid].end()); 6667373Sgblack@eecs.umich.edu 6677373Sgblack@eecs.umich.edu InstIt tail_thread = instList[tid].end(); 6687373Sgblack@eecs.umich.edu tail_thread--; 6697373Sgblack@eecs.umich.edu 6707373Sgblack@eecs.umich.edu return (*tail_thread)->readPC(); 6717373Sgblack@eecs.umich.edu} 6727373Sgblack@eecs.umich.edu 6737373Sgblack@eecs.umich.edutemplate <class Impl> 6747373Sgblack@eecs.umich.eduInstSeqNum 6757373Sgblack@eecs.umich.eduROB<Impl>::readTailSeqNum() 6767363Sgblack@eecs.umich.edu{ 6777363Sgblack@eecs.umich.edu // Return the last sequence number that has not been squashed. Other 6787363Sgblack@eecs.umich.edu // stages can use it to squash any instructions younger than the current 6797363Sgblack@eecs.umich.edu // tail. 6807363Sgblack@eecs.umich.edu return (*tail)->seqNum; 6817373Sgblack@eecs.umich.edu} 6827373Sgblack@eecs.umich.edu 6837373Sgblack@eecs.umich.edutemplate <class Impl> 6847373Sgblack@eecs.umich.eduInstSeqNum 6857373Sgblack@eecs.umich.eduROB<Impl>::readTailSeqNum(ThreadID tid) 6867373Sgblack@eecs.umich.edu{ 6877373Sgblack@eecs.umich.edu // Return the last sequence number that has not been squashed. Other 6887363Sgblack@eecs.umich.edu // stages can use it to squash any instructions younger than the current 6897373Sgblack@eecs.umich.edu // tail. 6907373Sgblack@eecs.umich.edu // assert(tail_thread[tid] != instList[tid].end()); 6917373Sgblack@eecs.umich.edu 6927373Sgblack@eecs.umich.edu InstIt tail_thread = instList[tid].end(); 6937373Sgblack@eecs.umich.edu tail_thread--; 6947373Sgblack@eecs.umich.edu 6957373Sgblack@eecs.umich.edu return (*tail_thread)->seqNum; 6967363Sgblack@eecs.umich.edu} 6977363Sgblack@eecs.umich.edu*/ 6987363Sgblack@eecs.umich.edu