rob_impl.hh revision 9954
11689SN/A/*
27598Sminkyu.jeong@arm.com * Copyright (c) 2012 ARM Limited
37598Sminkyu.jeong@arm.com * All rights reserved
47598Sminkyu.jeong@arm.com *
57598Sminkyu.jeong@arm.com * The license below extends only to copyright in the software and shall
67598Sminkyu.jeong@arm.com * not be construed as granting a license to any other intellectual
77598Sminkyu.jeong@arm.com * property including but not limited to intellectual property relating
87598Sminkyu.jeong@arm.com * to a hardware implementation of the functionality of the software
97598Sminkyu.jeong@arm.com * licensed hereunder.  You may use the software subject to the license
107598Sminkyu.jeong@arm.com * terms below provided that you ensure that this notice is replicated
117598Sminkyu.jeong@arm.com * unmodified and in its entirety in all distributions of the software,
127598Sminkyu.jeong@arm.com * modified or unmodified, in source code or in binary form.
137598Sminkyu.jeong@arm.com *
142326SN/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
411689SN/A *          Korey Sewell
421689SN/A */
431060SN/A
441060SN/A#ifndef __CPU_O3_ROB_IMPL_HH__
451689SN/A#define __CPU_O3_ROB_IMPL_HH__
461060SN/A
471060SN/A#include <list>
481060SN/A
497813Ssteve.reinhardt@amd.com#include "cpu/o3/rob.hh"
506658Snate@binkert.org#include "debug/Fetch.hh"
512292SN/A#include "debug/ROB.hh"
521717SN/A#include "params/DerivO3CPU.hh"
535529Snate@binkert.org
541060SN/Ausing namespace std;
556221Snate@binkert.org
566221Snate@binkert.orgtemplate <class Impl>
571681SN/AROB<Impl>::ROB(O3CPU *_cpu, DerivO3CPUParams *params)
585529Snate@binkert.org    : cpu(_cpu),
592873Sktlim@umich.edu      numEntries(params->numROBEntries),
604329Sktlim@umich.edu      squashWidth(params->squashWidth),
614329Sktlim@umich.edu      numInstsInROB(0),
624329Sktlim@umich.edu      numThreads(params->numThreads)
632292SN/A{
642292SN/A    std::string policy = params->smtROBPolicy;
652292SN/A
662292SN/A    //Convert string to lowercase
672820Sktlim@umich.edu    std::transform(policy.begin(), policy.end(), policy.begin(),
682292SN/A                   (int(*)(int)) tolower);
692820Sktlim@umich.edu
702820Sktlim@umich.edu    //Figure out rob policy
715529Snate@binkert.org    if (policy == "dynamic") {
722307SN/A        robPolicy = Dynamic;
731060SN/A
742292SN/A        //Set Max Entries to Total ROB Capacity
752292SN/A        for (ThreadID tid = 0; tid < numThreads; tid++) {
762292SN/A            maxEntries[tid] = numEntries;
771060SN/A        }
781060SN/A
791060SN/A    } else if (policy == "partitioned") {
801060SN/A        robPolicy = Partitioned;
811060SN/A        DPRINTF(Fetch, "ROB sharing policy set to Partitioned\n");
821060SN/A
831681SN/A        //@todo:make work if part_amt doesnt divide evenly.
846221Snate@binkert.org        int part_amt = numEntries / numThreads;
856221Snate@binkert.org
866221Snate@binkert.org        //Divide ROB up evenly
876221Snate@binkert.org        for (ThreadID tid = 0; tid < numThreads; tid++) {
882292SN/A            maxEntries[tid] = part_amt;
892292SN/A        }
902820Sktlim@umich.edu
912820Sktlim@umich.edu    } else if (policy == "threshold") {
922292SN/A        robPolicy = Threshold;
932292SN/A        DPRINTF(Fetch, "ROB sharing policy set to Threshold\n");
942820Sktlim@umich.edu
952820Sktlim@umich.edu        int threshold =  params->smtROBThreshold;;
962292SN/A
972292SN/A        //Divide up by threshold amount
982292SN/A        for (ThreadID tid = 0; tid < numThreads; tid++) {
992292SN/A            maxEntries[tid] = threshold;
1002292SN/A        }
1012292SN/A    } else {
1022292SN/A        assert(0 && "Invalid ROB Sharing Policy.Options Are:{Dynamic,"
1032292SN/A                    "Partitioned, Threshold}");
1041060SN/A    }
1051060SN/A
1061681SN/A    resetState();
1071062SN/A}
1082292SN/A
1091062SN/Atemplate <class Impl>
1102301SN/Avoid
1112301SN/AROB<Impl>::resetState()
1121062SN/A{
1132727Sktlim@umich.edu    for (ThreadID tid = 0; tid  < numThreads; tid++) {
1141062SN/A        doneSquashing[tid] = true;
1151062SN/A        threadEntries[tid] = 0;
1161062SN/A        squashIt[tid] = instList[tid].end();
1171062SN/A        squashedSeqNum[tid] = 0;
1181062SN/A    }
1191062SN/A    numInstsInROB = 0;
1201062SN/A
1211062SN/A    // Initialize the "universal" ROB head & tail point to invalid
1221062SN/A    // pointers
1231062SN/A    head = instList[0].end();
1241062SN/A    tail = instList[0].end();
1251062SN/A}
1261062SN/A
1271062SN/Atemplate <class Impl>
1281062SN/Astd::string
1291062SN/AROB<Impl>::name() const
1301062SN/A{
1311062SN/A    return cpu->name() + ".rob";
1321062SN/A}
1331062SN/A
1341062SN/Atemplate <class Impl>
1351062SN/Avoid
1361062SN/AROB<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
1371062SN/A{
1381062SN/A    DPRINTF(ROB, "Setting active threads list pointer.\n");
1391062SN/A    activeThreads = at_ptr;
1401062SN/A}
1411062SN/A
1421062SN/Atemplate <class Impl>
1431062SN/Avoid
1441062SN/AROB<Impl>::drainSanityCheck() const
1451062SN/A{
1461062SN/A    for (ThreadID tid = 0; tid  < numThreads; tid++)
1471062SN/A        assert(instList[tid].empty());
1481062SN/A    assert(isEmpty());
1491062SN/A}
1501062SN/A
1511062SN/Atemplate <class Impl>
1521062SN/Avoid
1531062SN/AROB<Impl>::takeOverFrom()
1541062SN/A{
1552292SN/A    resetState();
1562292SN/A}
1572292SN/A
1582292SN/Atemplate <class Impl>
1591062SN/Avoid
1601062SN/AROB<Impl>::resetEntries()
1611062SN/A{
1621062SN/A    if (robPolicy != Dynamic || numThreads > 1) {
1631062SN/A        int active_threads = activeThreads->size();
1641062SN/A
1651062SN/A        list<ThreadID>::iterator threads = activeThreads->begin();
1662292SN/A        list<ThreadID>::iterator end = activeThreads->end();
1672292SN/A
1682292SN/A        while (threads != end) {
1692292SN/A            ThreadID tid = *threads++;
1702292SN/A
1712292SN/A            if (robPolicy == Partitioned) {
1722292SN/A                maxEntries[tid] = numEntries / active_threads;
1732292SN/A            } else if (robPolicy == Threshold && active_threads == 1) {
1742292SN/A                maxEntries[tid] = numEntries;
1752292SN/A            }
1762301SN/A        }
1772727Sktlim@umich.edu    }
1782353SN/A}
1792727Sktlim@umich.edu
1802727Sktlim@umich.edutemplate <class Impl>
1812727Sktlim@umich.eduint
1826221Snate@binkert.orgROB<Impl>::entryAmount(ThreadID num_threads)
1832353SN/A{
1842727Sktlim@umich.edu    if (robPolicy == Partitioned) {
1852727Sktlim@umich.edu        return numEntries / num_threads;
1862727Sktlim@umich.edu    } else {
1872727Sktlim@umich.edu        return 0;
1882353SN/A    }
1892727Sktlim@umich.edu}
1902727Sktlim@umich.edu
1912727Sktlim@umich.edutemplate <class Impl>
1926221Snate@binkert.orgint
1932301SN/AROB<Impl>::countInsts()
1942301SN/A{
1952727Sktlim@umich.edu    int total = 0;
1962301SN/A
1972727Sktlim@umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++)
1986221Snate@binkert.org        total += countInsts(tid);
1992301SN/A
2002301SN/A    return total;
2012727Sktlim@umich.edu}
2022301SN/A
2032727Sktlim@umich.edutemplate <class Impl>
2046221Snate@binkert.orgint
2052301SN/AROB<Impl>::countInsts(ThreadID tid)
2062301SN/A{
2072727Sktlim@umich.edu    return instList[tid].size();
2082301SN/A}
2092727Sktlim@umich.edu
2106221Snate@binkert.orgtemplate <class Impl>
2112301SN/Avoid
2122301SN/AROB<Impl>::insertInst(DynInstPtr &inst)
2132727Sktlim@umich.edu{
2142301SN/A    assert(inst);
2152301SN/A
2162301SN/A    robWrites++;
2172301SN/A
2182727Sktlim@umich.edu    DPRINTF(ROB, "Adding inst PC %s to the ROB.\n", inst->pcState());
2192727Sktlim@umich.edu
2202727Sktlim@umich.edu    assert(numInstsInROB != numEntries);
2212727Sktlim@umich.edu
2222727Sktlim@umich.edu    ThreadID tid = inst->threadNumber;
2232727Sktlim@umich.edu
2242727Sktlim@umich.edu    instList[tid].push_back(inst);
2252727Sktlim@umich.edu
2262727Sktlim@umich.edu    //Set Up head iterator if this is the 1st instruction in the ROB
2272301SN/A    if (numInstsInROB == 0) {
2282301SN/A        head = instList[tid].begin();
2296221Snate@binkert.org        assert((*head) == inst);
2302301SN/A    }
2312301SN/A
2322727Sktlim@umich.edu    //Must Decrement for iterator to actually be valid  since __.end()
2332301SN/A    //actually points to 1 after the last inst
2342326SN/A    tail = instList[tid].end();
2356221Snate@binkert.org    tail--;
2362301SN/A
2372301SN/A    inst->setInROB();
2382727Sktlim@umich.edu
2392301SN/A    ++numInstsInROB;
2402326SN/A    ++threadEntries[tid];
2416221Snate@binkert.org
2422301SN/A    assert((*tail) == inst);
2432301SN/A
2442727Sktlim@umich.edu    DPRINTF(ROB, "[tid:%i] Now has %d instructions.\n", tid, threadEntries[tid]);
2452301SN/A}
2462326SN/A
2476221Snate@binkert.orgtemplate <class Impl>
2482301SN/Avoid
2492301SN/AROB<Impl>::retireHead(ThreadID tid)
2502727Sktlim@umich.edu{
2512301SN/A    robWrites++;
2522326SN/A
2536221Snate@binkert.org    assert(numInstsInROB > 0);
2542301SN/A
2552301SN/A    // Get the head ROB instruction.
2562727Sktlim@umich.edu    InstIt head_it = instList[tid].begin();
2572301SN/A
2582326SN/A    DynInstPtr head_inst = (*head_it);
2592301SN/A
2602301SN/A    assert(head_inst->readyToCommit());
2612727Sktlim@umich.edu
2622301SN/A    DPRINTF(ROB, "[tid:%u]: Retiring head instruction, "
2632326SN/A            "instruction PC %s, [sn:%lli]\n", tid, head_inst->pcState(),
2642301SN/A            head_inst->seqNum);
2652326SN/A
2662301SN/A    --numInstsInROB;
2672301SN/A    --threadEntries[tid];
2682727Sktlim@umich.edu
2692301SN/A    head_inst->clearInROB();
2702326SN/A    head_inst->setCommitted();
2712301SN/A
2722326SN/A    instList[tid].erase(head_it);
2732301SN/A
2742301SN/A    //Update "Global" Head of ROB
2752727Sktlim@umich.edu    updateHead();
2762326SN/A
2771062SN/A    // @todo: A special case is needed if the instruction being
2781062SN/A    // retired is the only instruction in the ROB; otherwise the tail
2791681SN/A    // iterator will become invalidated.
2801060SN/A    cpu->removeFrontInst(head_inst);
2812292SN/A}
2821060SN/A
2836221Snate@binkert.orgtemplate <class Impl>
2842292SN/Abool
2852292SN/AROB<Impl>::isHeadReady(ThreadID tid)
2862292SN/A{
2872292SN/A    robReads++;
2882292SN/A    if (threadEntries[tid] != 0) {
2892292SN/A        return instList[tid].front()->readyToCommit();
2902292SN/A    }
2912292SN/A
2922292SN/A    return false;
2932733Sktlim@umich.edu}
2941060SN/A
2951060SN/Atemplate <class Impl>
2961681SN/Abool
2971060SN/AROB<Impl>::canCommit()
2982292SN/A{
2991060SN/A    //@todo: set ActiveThreads through ROB or CPU
3001060SN/A    list<ThreadID>::iterator threads = activeThreads->begin();
3011060SN/A    list<ThreadID>::iterator end = activeThreads->end();
3021060SN/A
3031060SN/A    while (threads != end) {
3041060SN/A        ThreadID tid = *threads++;
3051060SN/A
3061060SN/A        if (isHeadReady(tid)) {
3071060SN/A            return true;
3082292SN/A        }
3092292SN/A    }
3101060SN/A
3111060SN/A    return false;
3121060SN/A}
3131060SN/A
3141681SN/Atemplate <class Impl>
3151060SN/Aunsigned
3162292SN/AROB<Impl>::numFreeEntries()
3171060SN/A{
3181060SN/A    return numEntries - numInstsInROB;
3191060SN/A}
3201060SN/A
3211060SN/Atemplate <class Impl>
3221060SN/Aunsigned
3231060SN/AROB<Impl>::numFreeEntries(ThreadID tid)
3241681SN/A{
3251060SN/A    return maxEntries[tid] - threadEntries[tid];
3262292SN/A}
3271060SN/A
3281060SN/Atemplate <class Impl>
3291060SN/Avoid
3301060SN/AROB<Impl>::doSquash(ThreadID tid)
3311060SN/A{
3321060SN/A    robWrites++;
3331060SN/A    DPRINTF(ROB, "[tid:%u]: Squashing instructions until [sn:%i].\n",
3341681SN/A            tid, squashedSeqNum[tid]);
3351060SN/A
3366221Snate@binkert.org    assert(squashIt[tid] != instList[tid].end());
3371060SN/A
3382292SN/A    if ((*squashIt[tid])->seqNum < squashedSeqNum[tid]) {
3392292SN/A        DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n",
3402292SN/A                tid);
3412292SN/A
3421060SN/A        squashIt[tid] = instList[tid].end();
3431060SN/A
3441681SN/A        doneSquashing[tid] = true;
3451060SN/A        return;
3462292SN/A    }
3471060SN/A
3482292SN/A    bool robTailUpdate = false;
3491060SN/A
3501060SN/A    for (int numSquashed = 0;
3512307SN/A         numSquashed < squashWidth &&
3522863Sktlim@umich.edu         squashIt[tid] != instList[tid].end() &&
3532843Sktlim@umich.edu         (*squashIt[tid])->seqNum > squashedSeqNum[tid];
3542307SN/A         ++numSquashed)
3552843Sktlim@umich.edu    {
3562843Sktlim@umich.edu        DPRINTF(ROB, "[tid:%u]: Squashing instruction PC %s, seq num %i.\n",
3572863Sktlim@umich.edu                (*squashIt[tid])->threadNumber,
3581681SN/A                (*squashIt[tid])->pcState(),
3591681SN/A                (*squashIt[tid])->seqNum);
3602316SN/A
3611681SN/A        // Mark the instruction as squashed, and ready to commit so that
3622843Sktlim@umich.edu        // it can drain out of the pipeline.
3632843Sktlim@umich.edu        (*squashIt[tid])->setSquashed();
3642843Sktlim@umich.edu
3652843Sktlim@umich.edu        (*squashIt[tid])->setCanCommit();
3662843Sktlim@umich.edu
3672843Sktlim@umich.edu
3682843Sktlim@umich.edu        if (squashIt[tid] == instList[tid].begin()) {
3691681SN/A            DPRINTF(ROB, "Reached head of instruction list while "
3702348SN/A                    "squashing.\n");
3712307SN/A
3722367SN/A            squashIt[tid] = instList[tid].end();
3732367SN/A
3741681SN/A            doneSquashing[tid] = true;
3752307SN/A
3762307SN/A            return;
3772307SN/A        }
3782307SN/A
3796221Snate@binkert.org        InstIt tail_thread = instList[tid].end();
3806221Snate@binkert.org        tail_thread--;
3816221Snate@binkert.org
3826221Snate@binkert.org        if ((*squashIt[tid]) == (*tail_thread))
3836221Snate@binkert.org            robTailUpdate = true;
3842307SN/A
3851681SN/A        squashIt[tid]--;
3861681SN/A    }
3872307SN/A
3881681SN/A
3892307SN/A    // Check if ROB is done squashing.
3901060SN/A    if ((*squashIt[tid])->seqNum <= squashedSeqNum[tid]) {
3912348SN/A        DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n",
3922307SN/A                tid);
3932307SN/A
3942307SN/A        squashIt[tid] = instList[tid].end();
3952307SN/A
3961060SN/A        doneSquashing[tid] = true;
3972307SN/A    }
3982307SN/A
3992307SN/A    if (robTailUpdate) {
4001060SN/A        updateTail();
4012307SN/A    }
4022307SN/A}
4031060SN/A
4046221Snate@binkert.org
4056221Snate@binkert.orgtemplate <class Impl>
4066221Snate@binkert.orgvoid
4076221Snate@binkert.orgROB<Impl>::updateHead()
4082307SN/A{
4091060SN/A    InstSeqNum lowest_num = 0;
4102307SN/A    bool first_valid = true;
4112307SN/A
4122873Sktlim@umich.edu    // @todo: set ActiveThreads through ROB or CPU
4132307SN/A    list<ThreadID>::iterator threads = activeThreads->begin();
4141060SN/A    list<ThreadID>::iterator end = activeThreads->end();
4151060SN/A
4161060SN/A    while (threads != end) {
4171681SN/A        ThreadID tid = *threads++;
4181060SN/A
4196221Snate@binkert.org        if (instList[tid].empty())
4202107SN/A            continue;
4216221Snate@binkert.org
4222107SN/A        if (first_valid) {
4232292SN/A            head = instList[tid].begin();
4242292SN/A            lowest_num = (*head)->seqNum;
4252107SN/A            first_valid = false;
4262292SN/A            continue;
4272326SN/A        }
4282292SN/A
4292107SN/A        InstIt head_thread = instList[tid].begin();
4302292SN/A
4312935Sksewell@umich.edu        DynInstPtr head_inst = (*head_thread);
4324632Sgblack@eecs.umich.edu
4332935Sksewell@umich.edu        assert(head_inst != 0);
4342292SN/A
4352292SN/A        if (head_inst->seqNum < lowest_num) {
4362292SN/A            head = head_thread;
4372292SN/A            lowest_num = head_inst->seqNum;
4382292SN/A        }
4392107SN/A    }
4402292SN/A
4412107SN/A    if (first_valid) {
4422292SN/A        head = instList[0].end();
4432292SN/A    }
4442107SN/A
4452702Sktlim@umich.edu}
4462107SN/A
4472107SN/Atemplate <class Impl>
4482107SN/Avoid
4492107SN/AROB<Impl>::updateTail()
4506221Snate@binkert.org{
4512292SN/A    tail = instList[0].end();
4527720Sgblack@eecs.umich.edu    bool first_valid = true;
4537720Sgblack@eecs.umich.edu
4542292SN/A    list<ThreadID>::iterator threads = activeThreads->begin();
4557852SMatt.Horsnell@arm.com    list<ThreadID>::iterator end = activeThreads->end();
4567852SMatt.Horsnell@arm.com
4577852SMatt.Horsnell@arm.com    while (threads != end) {
4587852SMatt.Horsnell@arm.com        ThreadID tid = *threads++;
4597852SMatt.Horsnell@arm.com
4602935Sksewell@umich.edu        if (instList[tid].empty()) {
4617852SMatt.Horsnell@arm.com            continue;
4627852SMatt.Horsnell@arm.com        }
4632292SN/A
4647852SMatt.Horsnell@arm.com        // If this is the first valid then assign w/out
4657852SMatt.Horsnell@arm.com        // comparison
4667852SMatt.Horsnell@arm.com        if (first_valid) {
4672292SN/A            tail = instList[tid].end();
4687852SMatt.Horsnell@arm.com            tail--;
4697852SMatt.Horsnell@arm.com            first_valid = false;
4707852SMatt.Horsnell@arm.com            continue;
4712292SN/A        }
4722292SN/A
4732292SN/A        // Assign new tail if this thread's tail is younger
4742292SN/A        // than our current "tail high"
4756221Snate@binkert.org        InstIt tail_thread = instList[tid].end();
4762292SN/A        tail_thread--;
4772292SN/A
4787720Sgblack@eecs.umich.edu        if ((*tail_thread)->seqNum > (*tail)->seqNum) {
4792292SN/A            tail = tail_thread;
4807852SMatt.Horsnell@arm.com        }
4817852SMatt.Horsnell@arm.com    }
4827852SMatt.Horsnell@arm.com}
4837852SMatt.Horsnell@arm.com
4847852SMatt.Horsnell@arm.com
4857852SMatt.Horsnell@arm.comtemplate <class Impl>
4867852SMatt.Horsnell@arm.comvoid
4878137SAli.Saidi@ARM.comROB<Impl>::squash(InstSeqNum squash_num, ThreadID tid)
4882292SN/A{
4897852SMatt.Horsnell@arm.com    if (isEmpty()) {
4902292SN/A        DPRINTF(ROB, "Does not need to squash due to being empty "
4917852SMatt.Horsnell@arm.com                "[sn:%i]\n",
4927852SMatt.Horsnell@arm.com                squash_num);
4932292SN/A
4942292SN/A        return;
4952292SN/A    }
4962292SN/A
4976221Snate@binkert.org    DPRINTF(ROB, "Starting to squash within the ROB.\n");
4982292SN/A
4992292SN/A    robStatus[tid] = ROBSquashing;
5007720Sgblack@eecs.umich.edu
5017852SMatt.Horsnell@arm.com    doneSquashing[tid] = false;
5027852SMatt.Horsnell@arm.com
5037852SMatt.Horsnell@arm.com    squashedSeqNum[tid] = squash_num;
5042292SN/A
5057852SMatt.Horsnell@arm.com    if (!instList[tid].empty()) {
5067852SMatt.Horsnell@arm.com        InstIt tail_thread = instList[tid].end();
5078137SAli.Saidi@ARM.com        tail_thread--;
5082292SN/A
5097852SMatt.Horsnell@arm.com        squashIt[tid] = tail_thread;
5107852SMatt.Horsnell@arm.com
5112292SN/A        doSquash(tid);
5127852SMatt.Horsnell@arm.com    }
5132292SN/A}
5147852SMatt.Horsnell@arm.com
5157852SMatt.Horsnell@arm.comtemplate <class Impl>
5162292SN/Atypename Impl::DynInstPtr
5172292SN/AROB<Impl>::readHeadInst(ThreadID tid)
5182292SN/A{
5192292SN/A    if (threadEntries[tid] != 0) {
5206221Snate@binkert.org        InstIt head_thread = instList[tid].begin();
5212292SN/A
5222292SN/A        assert((*head_thread)->isInROB()==true);
5232292SN/A
5242292SN/A        return *head_thread;
5252292SN/A    } else {
5262292SN/A        return dummyInst;
5272292SN/A    }
5282292SN/A}
5292292SN/A
5302292SN/Atemplate <class Impl>
5312292SN/Atypename Impl::DynInstPtr
5322292SN/AROB<Impl>::readTailInst(ThreadID tid)
5332292SN/A{
5342292SN/A    InstIt tail_thread = instList[tid].end();
5352292SN/A    tail_thread--;
5362292SN/A
5372292SN/A    return *tail_thread;
5382292SN/A}
5396221Snate@binkert.org
5402292SN/Atemplate <class Impl>
5412292SN/Avoid
5422292SN/AROB<Impl>::regStats()
5432292SN/A{
5442292SN/A    using namespace Stats;
5452292SN/A    robReads
5462292SN/A        .name(name() + ".rob_reads")
5472292SN/A        .desc("The number of ROB reads");
5482292SN/A
5492292SN/A    robWrites
5502292SN/A        .name(name() + ".rob_writes")
5512292SN/A        .desc("The number of ROB writes");
5522292SN/A}
5532292SN/A
5542292SN/Atemplate <class Impl>
5552292SN/Atypename Impl::DynInstPtr
5562292SN/AROB<Impl>::findInst(ThreadID tid, InstSeqNum squash_inst)
5571060SN/A{
5581681SN/A    for (InstIt it = instList[tid].begin(); it != instList[tid].end(); it++) {
5591060SN/A        if ((*it)->seqNum == squash_inst) {
5601060SN/A            return *it;
5612292SN/A        }
5622292SN/A    }
5632292SN/A    return NULL;
5642292SN/A}
5652292SN/A
5662292SN/A#endif//__CPU_O3_ROB_IMPL_HH__
5671681SN/A