rob_impl.hh revision 13453
11689SN/A/* 29444SAndreas.Sandberg@ARM.com * Copyright (c) 2012 ARM Limited 39444SAndreas.Sandberg@ARM.com * All rights reserved 49444SAndreas.Sandberg@ARM.com * 59444SAndreas.Sandberg@ARM.com * The license below extends only to copyright in the software and shall 69444SAndreas.Sandberg@ARM.com * not be construed as granting a license to any other intellectual 79444SAndreas.Sandberg@ARM.com * property including but not limited to intellectual property relating 89444SAndreas.Sandberg@ARM.com * to a hardware implementation of the functionality of the software 99444SAndreas.Sandberg@ARM.com * licensed hereunder. You may use the software subject to the license 109444SAndreas.Sandberg@ARM.com * terms below provided that you ensure that this notice is replicated 119444SAndreas.Sandberg@ARM.com * unmodified and in its entirety in all distributions of the software, 129444SAndreas.Sandberg@ARM.com * modified or unmodified, in source code or in binary form. 139444SAndreas.Sandberg@ARM.com * 142329SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan 151689SN/A * All rights reserved. 161689SN/A * 171689SN/A * Redistribution and use in source and binary forms, with or without 181689SN/A * modification, are permitted provided that the following conditions are 191689SN/A * met: redistributions of source code must retain the above copyright 201689SN/A * notice, this list of conditions and the following disclaimer; 211689SN/A * redistributions in binary form must reproduce the above copyright 221689SN/A * notice, this list of conditions and the following disclaimer in the 231689SN/A * documentation and/or other materials provided with the distribution; 241689SN/A * neither the name of the copyright holders nor the names of its 251689SN/A * contributors may be used to endorse or promote products derived from 261689SN/A * this software without specific prior written permission. 271689SN/A * 281689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 291689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 301689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 311689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 321689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 331689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 341689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 351689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 361689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 371689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 381689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392665Ssaidi@eecs.umich.edu * 402665Ssaidi@eecs.umich.edu * Authors: Kevin Lim 412831Sksewell@umich.edu * Korey Sewell 421689SN/A */ 431689SN/A 449944Smatt.horsnell@ARM.com#ifndef __CPU_O3_ROB_IMPL_HH__ 459944Smatt.horsnell@ARM.com#define __CPU_O3_ROB_IMPL_HH__ 469944Smatt.horsnell@ARM.com 476221Snate@binkert.org#include <list> 486221Snate@binkert.org 4913449Sgabeblack@google.com#include "base/logging.hh" 501717SN/A#include "cpu/o3/rob.hh" 518232Snate@binkert.org#include "debug/Fetch.hh" 528232Snate@binkert.org#include "debug/ROB.hh" 539954SFaissal.Sleiman@arm.com#include "params/DerivO3CPU.hh" 541060SN/A 556221Snate@binkert.orgusing namespace std; 562292SN/A 571061SN/Atemplate <class Impl> 589954SFaissal.Sleiman@arm.comROB<Impl>::ROB(O3CPU *_cpu, DerivO3CPUParams *params) 594329Sktlim@umich.edu : cpu(_cpu), 609954SFaissal.Sleiman@arm.com numEntries(params->numROBEntries), 619954SFaissal.Sleiman@arm.com squashWidth(params->squashWidth), 621060SN/A numInstsInROB(0), 639954SFaissal.Sleiman@arm.com numThreads(params->numThreads) 641060SN/A{ 659954SFaissal.Sleiman@arm.com std::string policy = params->smtROBPolicy; 662292SN/A 672292SN/A //Convert string to lowercase 682292SN/A std::transform(policy.begin(), policy.end(), policy.begin(), 692292SN/A (int(*)(int)) tolower); 702292SN/A 712292SN/A //Figure out rob policy 722292SN/A if (policy == "dynamic") { 732292SN/A robPolicy = Dynamic; 742292SN/A 752292SN/A //Set Max Entries to Total ROB Capacity 766221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 776221Snate@binkert.org maxEntries[tid] = numEntries; 782292SN/A } 792292SN/A 802292SN/A } else if (policy == "partitioned") { 812292SN/A robPolicy = Partitioned; 824329Sktlim@umich.edu DPRINTF(Fetch, "ROB sharing policy set to Partitioned\n"); 832292SN/A 842292SN/A //@todo:make work if part_amt doesnt divide evenly. 852292SN/A int part_amt = numEntries / numThreads; 862292SN/A 872292SN/A //Divide ROB up evenly 886221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 896221Snate@binkert.org maxEntries[tid] = part_amt; 902292SN/A } 912292SN/A 922292SN/A } else if (policy == "threshold") { 932292SN/A robPolicy = Threshold; 944329Sktlim@umich.edu DPRINTF(Fetch, "ROB sharing policy set to Threshold\n"); 952292SN/A 969954SFaissal.Sleiman@arm.com int threshold = params->smtROBThreshold;; 972292SN/A 982292SN/A //Divide up by threshold amount 996221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 1006221Snate@binkert.org maxEntries[tid] = threshold; 1012292SN/A } 1022292SN/A } else { 10313449Sgabeblack@google.com panic("Invalid ROB sharing policy. Options are: Dynamic, " 10413449Sgabeblack@google.com "Partitioned, Threshold"); 1052292SN/A } 10613453Srekai.gonzalezalberquilla@arm.com for (ThreadID tid = numThreads; tid < Impl::MaxThreads; tid++) { 10713453Srekai.gonzalezalberquilla@arm.com maxEntries[tid] = 0; 10813453Srekai.gonzalezalberquilla@arm.com } 1091060SN/A 1109444SAndreas.Sandberg@ARM.com resetState(); 1119444SAndreas.Sandberg@ARM.com} 1129444SAndreas.Sandberg@ARM.com 1139444SAndreas.Sandberg@ARM.comtemplate <class Impl> 1149444SAndreas.Sandberg@ARM.comvoid 1159444SAndreas.Sandberg@ARM.comROB<Impl>::resetState() 1169444SAndreas.Sandberg@ARM.com{ 11713453Srekai.gonzalezalberquilla@arm.com for (ThreadID tid = 0; tid < Impl::MaxThreads; tid++) { 1189444SAndreas.Sandberg@ARM.com threadEntries[tid] = 0; 1196221Snate@binkert.org squashIt[tid] = instList[tid].end(); 1209444SAndreas.Sandberg@ARM.com squashedSeqNum[tid] = 0; 12113453Srekai.gonzalezalberquilla@arm.com doneSquashing[tid] = true; 1222292SN/A } 1239444SAndreas.Sandberg@ARM.com numInstsInROB = 0; 1241060SN/A 1252292SN/A // Initialize the "universal" ROB head & tail point to invalid 1262292SN/A // pointers 1272292SN/A head = instList[0].end(); 1282292SN/A tail = instList[0].end(); 1292292SN/A} 1302292SN/A 1312292SN/Atemplate <class Impl> 1324329Sktlim@umich.edustd::string 1334329Sktlim@umich.eduROB<Impl>::name() const 1344329Sktlim@umich.edu{ 1354329Sktlim@umich.edu return cpu->name() + ".rob"; 1364329Sktlim@umich.edu} 1374329Sktlim@umich.edu 1384329Sktlim@umich.edutemplate <class Impl> 1392292SN/Avoid 1406221Snate@binkert.orgROB<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 1412292SN/A{ 1422292SN/A DPRINTF(ROB, "Setting active threads list pointer.\n"); 1432292SN/A activeThreads = at_ptr; 1442292SN/A} 1452292SN/A 1462307SN/Atemplate <class Impl> 1472307SN/Avoid 1489444SAndreas.Sandberg@ARM.comROB<Impl>::drainSanityCheck() const 1492307SN/A{ 1509444SAndreas.Sandberg@ARM.com for (ThreadID tid = 0; tid < numThreads; tid++) 1519444SAndreas.Sandberg@ARM.com assert(instList[tid].empty()); 1529444SAndreas.Sandberg@ARM.com assert(isEmpty()); 1532307SN/A} 1542307SN/A 1552307SN/Atemplate <class Impl> 1562307SN/Avoid 1572307SN/AROB<Impl>::takeOverFrom() 1582307SN/A{ 1599444SAndreas.Sandberg@ARM.com resetState(); 1602307SN/A} 1612292SN/A 1622292SN/Atemplate <class Impl> 1632292SN/Avoid 1642292SN/AROB<Impl>::resetEntries() 1652292SN/A{ 1662292SN/A if (robPolicy != Dynamic || numThreads > 1) { 1673867Sbinkertn@umich.edu int active_threads = activeThreads->size(); 1682292SN/A 1696221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 1706221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 1712292SN/A 1723867Sbinkertn@umich.edu while (threads != end) { 1736221Snate@binkert.org ThreadID tid = *threads++; 1743867Sbinkertn@umich.edu 1752292SN/A if (robPolicy == Partitioned) { 1763867Sbinkertn@umich.edu maxEntries[tid] = numEntries / active_threads; 1772292SN/A } else if (robPolicy == Threshold && active_threads == 1) { 1783867Sbinkertn@umich.edu maxEntries[tid] = numEntries; 1792292SN/A } 1802292SN/A } 1812292SN/A } 1822292SN/A} 1832292SN/A 1842292SN/Atemplate <class Impl> 1852292SN/Aint 1866221Snate@binkert.orgROB<Impl>::entryAmount(ThreadID num_threads) 1872292SN/A{ 1882292SN/A if (robPolicy == Partitioned) { 1892292SN/A return numEntries / num_threads; 1902292SN/A } else { 1912292SN/A return 0; 1922292SN/A } 1931060SN/A} 1941060SN/A 1951061SN/Atemplate <class Impl> 1961060SN/Aint 1971060SN/AROB<Impl>::countInsts() 1981060SN/A{ 1996221Snate@binkert.org int total = 0; 2001061SN/A 2016221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) 2026221Snate@binkert.org total += countInsts(tid); 2031060SN/A 2042292SN/A return total; 2052292SN/A} 2061060SN/A 2072292SN/Atemplate <class Impl> 2082292SN/Aint 2096221Snate@binkert.orgROB<Impl>::countInsts(ThreadID tid) 2102292SN/A{ 2112292SN/A return instList[tid].size(); 2121060SN/A} 2131060SN/A 2141061SN/Atemplate <class Impl> 2151060SN/Avoid 21613429Srekai.gonzalezalberquilla@arm.comROB<Impl>::insertInst(const DynInstPtr &inst) 2171060SN/A{ 2181060SN/A assert(inst); 2191060SN/A 2207897Shestness@cs.utexas.edu robWrites++; 2217897Shestness@cs.utexas.edu 2227720Sgblack@eecs.umich.edu DPRINTF(ROB, "Adding inst PC %s to the ROB.\n", inst->pcState()); 2231060SN/A 2241060SN/A assert(numInstsInROB != numEntries); 2251060SN/A 2266221Snate@binkert.org ThreadID tid = inst->threadNumber; 2271060SN/A 2282292SN/A instList[tid].push_back(inst); 2292292SN/A 2302292SN/A //Set Up head iterator if this is the 1st instruction in the ROB 2312292SN/A if (numInstsInROB == 0) { 2322292SN/A head = instList[tid].begin(); 2332292SN/A assert((*head) == inst); 2341060SN/A } 2351060SN/A 2362292SN/A //Must Decrement for iterator to actually be valid since __.end() 2372292SN/A //actually points to 1 after the last inst 2382292SN/A tail = instList[tid].end(); 2392292SN/A tail--; 2402292SN/A 2412292SN/A inst->setInROB(); 2422292SN/A 2432292SN/A ++numInstsInROB; 2442292SN/A ++threadEntries[tid]; 2452292SN/A 2461060SN/A assert((*tail) == inst); 2471060SN/A 2482292SN/A DPRINTF(ROB, "[tid:%i] Now has %d instructions.\n", tid, threadEntries[tid]); 2491060SN/A} 2501060SN/A 2512292SN/Atemplate <class Impl> 2522292SN/Avoid 2536221Snate@binkert.orgROB<Impl>::retireHead(ThreadID tid) 2542292SN/A{ 2557897Shestness@cs.utexas.edu robWrites++; 2567897Shestness@cs.utexas.edu 2571061SN/A assert(numInstsInROB > 0); 2581060SN/A 25913429Srekai.gonzalezalberquilla@arm.com // Get the head ROB instruction by copying it and remove it from the list 2602292SN/A InstIt head_it = instList[tid].begin(); 2611060SN/A 26213429Srekai.gonzalezalberquilla@arm.com DynInstPtr head_inst = std::move(*head_it); 26313429Srekai.gonzalezalberquilla@arm.com instList[tid].erase(head_it); 2641858SN/A 2651060SN/A assert(head_inst->readyToCommit()); 2661060SN/A 2672292SN/A DPRINTF(ROB, "[tid:%u]: Retiring head instruction, " 2687720Sgblack@eecs.umich.edu "instruction PC %s, [sn:%lli]\n", tid, head_inst->pcState(), 2691060SN/A head_inst->seqNum); 2701060SN/A 2711060SN/A --numInstsInROB; 2722292SN/A --threadEntries[tid]; 2731060SN/A 2742731Sktlim@umich.edu head_inst->clearInROB(); 2752292SN/A head_inst->setCommitted(); 2762292SN/A 2772292SN/A //Update "Global" Head of ROB 2782292SN/A updateHead(); 2792292SN/A 2802329SN/A // @todo: A special case is needed if the instruction being 2812329SN/A // retired is the only instruction in the ROB; otherwise the tail 2822329SN/A // iterator will become invalidated. 2831681SN/A cpu->removeFrontInst(head_inst); 2841060SN/A} 2852292SN/A 2862292SN/Atemplate <class Impl> 2872292SN/Abool 2886221Snate@binkert.orgROB<Impl>::isHeadReady(ThreadID tid) 2892292SN/A{ 2907897Shestness@cs.utexas.edu robReads++; 2912292SN/A if (threadEntries[tid] != 0) { 2922292SN/A return instList[tid].front()->readyToCommit(); 2932292SN/A } 2942292SN/A 2952292SN/A return false; 2962292SN/A} 2972292SN/A 2982292SN/Atemplate <class Impl> 2992292SN/Abool 3002292SN/AROB<Impl>::canCommit() 3012292SN/A{ 3022292SN/A //@todo: set ActiveThreads through ROB or CPU 3036221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 3046221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 3052292SN/A 3063867Sbinkertn@umich.edu while (threads != end) { 3076221Snate@binkert.org ThreadID tid = *threads++; 3082292SN/A 3092292SN/A if (isHeadReady(tid)) { 3102292SN/A return true; 3112292SN/A } 3121060SN/A } 3131060SN/A 3141060SN/A return false; 3151060SN/A} 3161060SN/A 3171061SN/Atemplate <class Impl> 3181060SN/Aunsigned 3191060SN/AROB<Impl>::numFreeEntries() 3201060SN/A{ 3211060SN/A return numEntries - numInstsInROB; 3221060SN/A} 3231060SN/A 3241061SN/Atemplate <class Impl> 3252292SN/Aunsigned 3266221Snate@binkert.orgROB<Impl>::numFreeEntries(ThreadID tid) 3271060SN/A{ 3282292SN/A return maxEntries[tid] - threadEntries[tid]; 3291060SN/A} 3301060SN/A 3311061SN/Atemplate <class Impl> 3321060SN/Avoid 3336221Snate@binkert.orgROB<Impl>::doSquash(ThreadID tid) 3341060SN/A{ 3357897Shestness@cs.utexas.edu robWrites++; 3362292SN/A DPRINTF(ROB, "[tid:%u]: Squashing instructions until [sn:%i].\n", 3372877Sksewell@umich.edu tid, squashedSeqNum[tid]); 3381858SN/A 3392292SN/A assert(squashIt[tid] != instList[tid].end()); 3402292SN/A 3412877Sksewell@umich.edu if ((*squashIt[tid])->seqNum < squashedSeqNum[tid]) { 3422292SN/A DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n", 3432292SN/A tid); 3442292SN/A 3452292SN/A squashIt[tid] = instList[tid].end(); 3462292SN/A 3472292SN/A doneSquashing[tid] = true; 3482292SN/A return; 3492292SN/A } 3502292SN/A 3512292SN/A bool robTailUpdate = false; 3521858SN/A 3531858SN/A for (int numSquashed = 0; 3542292SN/A numSquashed < squashWidth && 3552292SN/A squashIt[tid] != instList[tid].end() && 3562877Sksewell@umich.edu (*squashIt[tid])->seqNum > squashedSeqNum[tid]; 3571858SN/A ++numSquashed) 3581858SN/A { 3597720Sgblack@eecs.umich.edu DPRINTF(ROB, "[tid:%u]: Squashing instruction PC %s, seq num %i.\n", 3602292SN/A (*squashIt[tid])->threadNumber, 3617720Sgblack@eecs.umich.edu (*squashIt[tid])->pcState(), 3622292SN/A (*squashIt[tid])->seqNum); 3631858SN/A 3641858SN/A // Mark the instruction as squashed, and ready to commit so that 3651858SN/A // it can drain out of the pipeline. 3662292SN/A (*squashIt[tid])->setSquashed(); 3671858SN/A 3682292SN/A (*squashIt[tid])->setCanCommit(); 3691858SN/A 3702292SN/A 3712292SN/A if (squashIt[tid] == instList[tid].begin()) { 3722292SN/A DPRINTF(ROB, "Reached head of instruction list while " 3731858SN/A "squashing.\n"); 3741858SN/A 3752292SN/A squashIt[tid] = instList[tid].end(); 3761858SN/A 3772292SN/A doneSquashing[tid] = true; 3781858SN/A 3791858SN/A return; 3801858SN/A } 3811858SN/A 3822292SN/A InstIt tail_thread = instList[tid].end(); 3832292SN/A tail_thread--; 3842292SN/A 3852292SN/A if ((*squashIt[tid]) == (*tail_thread)) 3862292SN/A robTailUpdate = true; 3872292SN/A 3882292SN/A squashIt[tid]--; 3891858SN/A } 3901858SN/A 3911858SN/A 3921858SN/A // Check if ROB is done squashing. 3932877Sksewell@umich.edu if ((*squashIt[tid])->seqNum <= squashedSeqNum[tid]) { 3942292SN/A DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n", 3952292SN/A tid); 3961858SN/A 3972292SN/A squashIt[tid] = instList[tid].end(); 3981858SN/A 3992292SN/A doneSquashing[tid] = true; 4002292SN/A } 4012292SN/A 4022292SN/A if (robTailUpdate) { 4032292SN/A updateTail(); 4042292SN/A } 4052292SN/A} 4062292SN/A 4072292SN/A 4082292SN/Atemplate <class Impl> 4092292SN/Avoid 4102292SN/AROB<Impl>::updateHead() 4112292SN/A{ 4122292SN/A InstSeqNum lowest_num = 0; 4132292SN/A bool first_valid = true; 4142292SN/A 4152292SN/A // @todo: set ActiveThreads through ROB or CPU 4166221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 4176221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 4182292SN/A 4193867Sbinkertn@umich.edu while (threads != end) { 4206221Snate@binkert.org ThreadID tid = *threads++; 4212292SN/A 4223867Sbinkertn@umich.edu if (instList[tid].empty()) 4232292SN/A continue; 4242292SN/A 4252292SN/A if (first_valid) { 4263867Sbinkertn@umich.edu head = instList[tid].begin(); 4272292SN/A lowest_num = (*head)->seqNum; 4282292SN/A first_valid = false; 4292292SN/A continue; 4302292SN/A } 4312292SN/A 4323867Sbinkertn@umich.edu InstIt head_thread = instList[tid].begin(); 4332292SN/A 4342292SN/A DynInstPtr head_inst = (*head_thread); 4352292SN/A 4362292SN/A assert(head_inst != 0); 4372292SN/A 4382292SN/A if (head_inst->seqNum < lowest_num) { 4392292SN/A head = head_thread; 4402292SN/A lowest_num = head_inst->seqNum; 4412292SN/A } 4422292SN/A } 4432292SN/A 4442292SN/A if (first_valid) { 4452292SN/A head = instList[0].end(); 4462292SN/A } 4472292SN/A 4482292SN/A} 4492292SN/A 4502292SN/Atemplate <class Impl> 4512292SN/Avoid 4522292SN/AROB<Impl>::updateTail() 4532292SN/A{ 4542292SN/A tail = instList[0].end(); 4552292SN/A bool first_valid = true; 4562292SN/A 4576221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 4586221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 4592292SN/A 4603867Sbinkertn@umich.edu while (threads != end) { 4616221Snate@binkert.org ThreadID tid = *threads++; 4622292SN/A 4632292SN/A if (instList[tid].empty()) { 4642292SN/A continue; 4652292SN/A } 4662292SN/A 4672292SN/A // If this is the first valid then assign w/out 4682292SN/A // comparison 4692292SN/A if (first_valid) { 4702292SN/A tail = instList[tid].end(); 4712292SN/A tail--; 4722292SN/A first_valid = false; 4732292SN/A continue; 4742292SN/A } 4752292SN/A 4762292SN/A // Assign new tail if this thread's tail is younger 4772292SN/A // than our current "tail high" 4782292SN/A InstIt tail_thread = instList[tid].end(); 4792292SN/A tail_thread--; 4802292SN/A 4812292SN/A if ((*tail_thread)->seqNum > (*tail)->seqNum) { 4822292SN/A tail = tail_thread; 4832292SN/A } 4842292SN/A } 4852292SN/A} 4862292SN/A 4872292SN/A 4882292SN/Atemplate <class Impl> 4892292SN/Avoid 4906221Snate@binkert.orgROB<Impl>::squash(InstSeqNum squash_num, ThreadID tid) 4912292SN/A{ 49210164Ssleimanf@umich.edu if (isEmpty(tid)) { 4932292SN/A DPRINTF(ROB, "Does not need to squash due to being empty " 4942292SN/A "[sn:%i]\n", 4952292SN/A squash_num); 4962292SN/A 4972292SN/A return; 4982292SN/A } 4992292SN/A 5002292SN/A DPRINTF(ROB, "Starting to squash within the ROB.\n"); 5012292SN/A 5022292SN/A robStatus[tid] = ROBSquashing; 5032292SN/A 5042292SN/A doneSquashing[tid] = false; 5051060SN/A 5062877Sksewell@umich.edu squashedSeqNum[tid] = squash_num; 5071060SN/A 5082292SN/A if (!instList[tid].empty()) { 5092292SN/A InstIt tail_thread = instList[tid].end(); 5102292SN/A tail_thread--; 5111060SN/A 5122292SN/A squashIt[tid] = tail_thread; 5131060SN/A 5142292SN/A doSquash(tid); 5151858SN/A } 5161060SN/A} 5172877Sksewell@umich.edu 5182292SN/Atemplate <class Impl> 51913429Srekai.gonzalezalberquilla@arm.comconst typename Impl::DynInstPtr& 5206221Snate@binkert.orgROB<Impl>::readHeadInst(ThreadID tid) 5212292SN/A{ 5222292SN/A if (threadEntries[tid] != 0) { 5232292SN/A InstIt head_thread = instList[tid].begin(); 5241060SN/A 52510231Ssteve.reinhardt@amd.com assert((*head_thread)->isInROB()); 5261858SN/A 5272292SN/A return *head_thread; 5282292SN/A } else { 5292292SN/A return dummyInst; 5302292SN/A } 5311858SN/A} 5322877Sksewell@umich.edu 5332292SN/Atemplate <class Impl> 5342292SN/Atypename Impl::DynInstPtr 5356221Snate@binkert.orgROB<Impl>::readTailInst(ThreadID tid) 5362292SN/A{ 5372292SN/A InstIt tail_thread = instList[tid].end(); 5382292SN/A tail_thread--; 5392292SN/A 5402292SN/A return *tail_thread; 5412292SN/A} 5422292SN/A 5437897Shestness@cs.utexas.edutemplate <class Impl> 5447897Shestness@cs.utexas.eduvoid 5457897Shestness@cs.utexas.eduROB<Impl>::regStats() 5467897Shestness@cs.utexas.edu{ 5477897Shestness@cs.utexas.edu using namespace Stats; 5487897Shestness@cs.utexas.edu robReads 5497897Shestness@cs.utexas.edu .name(name() + ".rob_reads") 5507897Shestness@cs.utexas.edu .desc("The number of ROB reads"); 5517897Shestness@cs.utexas.edu 5527897Shestness@cs.utexas.edu robWrites 5537897Shestness@cs.utexas.edu .name(name() + ".rob_writes") 5547897Shestness@cs.utexas.edu .desc("The number of ROB writes"); 5557897Shestness@cs.utexas.edu} 5567897Shestness@cs.utexas.edu 5578822Snilay@cs.wisc.edutemplate <class Impl> 5588822Snilay@cs.wisc.edutypename Impl::DynInstPtr 5598822Snilay@cs.wisc.eduROB<Impl>::findInst(ThreadID tid, InstSeqNum squash_inst) 5608822Snilay@cs.wisc.edu{ 5618822Snilay@cs.wisc.edu for (InstIt it = instList[tid].begin(); it != instList[tid].end(); it++) { 5628822Snilay@cs.wisc.edu if ((*it)->seqNum == squash_inst) { 5638822Snilay@cs.wisc.edu return *it; 5648822Snilay@cs.wisc.edu } 5658822Snilay@cs.wisc.edu } 5668822Snilay@cs.wisc.edu return NULL; 5678822Snilay@cs.wisc.edu} 5689944Smatt.horsnell@ARM.com 5699944Smatt.horsnell@ARM.com#endif//__CPU_O3_ROB_IMPL_HH__ 570