iew_impl.hh revision 2326
1360SN/A/* 21458SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan 3360SN/A * All rights reserved. 4360SN/A * 5360SN/A * Redistribution and use in source and binary forms, with or without 6360SN/A * modification, are permitted provided that the following conditions are 7360SN/A * met: redistributions of source code must retain the above copyright 8360SN/A * notice, this list of conditions and the following disclaimer; 9360SN/A * redistributions in binary form must reproduce the above copyright 10360SN/A * notice, this list of conditions and the following disclaimer in the 11360SN/A * documentation and/or other materials provided with the distribution; 12360SN/A * neither the name of the copyright holders nor the names of its 13360SN/A * contributors may be used to endorse or promote products derived from 14360SN/A * this software without specific prior written permission. 15360SN/A * 16360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26360SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292665Ssaidi@eecs.umich.edu// @todo: Fix the instantaneous communication among all the stages within 30360SN/A// iew. There's a clear delay between issue and execute, yet backwards 31360SN/A// communication happens simultaneously. 321354SN/A 331354SN/A#include <queue> 34360SN/A 352764Sstever@eecs.umich.edu#include "base/timebuf.hh" 362764Sstever@eecs.umich.edu#include "cpu/o3/fu_pool.hh" 372064SN/A#include "cpu/o3/iew.hh" 38360SN/A 39360SN/Ausing namespace std; 40360SN/A 41360SN/Atemplate<class Impl> 42360SN/ADefaultIEW<Impl>::LdWritebackEvent::LdWritebackEvent(DynInstPtr &_inst, 43360SN/A DefaultIEW<Impl> *_iew) 441354SN/A : Event(&mainEventQueue), inst(_inst), iewStage(_iew) 45360SN/A{ 461809SN/A this->setFlags(Event::AutoDelete); 475543Ssaidi@eecs.umich.edu} 481809SN/A 493113Sgblack@eecs.umich.edutemplate<class Impl> 503113Sgblack@eecs.umich.eduvoid 511999SN/ADefaultIEW<Impl>::LdWritebackEvent::process() 52360SN/A{ 535543Ssaidi@eecs.umich.edu DPRINTF(IEW, "Load writeback event [sn:%lli]\n", inst->seqNum); 542474SN/A DPRINTF(Activity, "Activity: Ld Writeback event [sn:%lli]\n", inst->seqNum); 555543Ssaidi@eecs.umich.edu 562462SN/A //iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum); 571354SN/A 582474SN/A if (iewStage->isSwitchedOut()) { 592680Sktlim@umich.edu inst = NULL; 602474SN/A return; 612474SN/A } else if (inst->isSquashed()) { 621354SN/A iewStage->wakeCPU(); 63360SN/A inst = NULL; 64360SN/A return; 65360SN/A } 66360SN/A 67360SN/A iewStage->wakeCPU(); 68360SN/A 69360SN/A if (!inst->isExecuted()) { 70360SN/A inst->setExecuted(); 71378SN/A 721450SN/A // Complete access to copy data to proper place. 733114Sgblack@eecs.umich.edu if (inst->isStore()) { 74360SN/A inst->completeAcc(); 755543Ssaidi@eecs.umich.edu } 765543Ssaidi@eecs.umich.edu } 775543Ssaidi@eecs.umich.edu 78360SN/A // Need to insert instruction into queue to commit 79360SN/A iewStage->instToCommit(inst); 80360SN/A 81360SN/A iewStage->activityThisCycle(); 82360SN/A 832680Sktlim@umich.edu inst = NULL; 84360SN/A} 85360SN/A 86360SN/Atemplate<class Impl> 87360SN/Aconst char * 88360SN/ADefaultIEW<Impl>::LdWritebackEvent::description() 89360SN/A{ 90360SN/A return "Load writeback event"; 91360SN/A} 92360SN/A 93360SN/Atemplate<class Impl> 94360SN/ADefaultIEW<Impl>::DefaultIEW(Params *params) 953114Sgblack@eecs.umich.edu : // @todo: Make this into a parameter. 96360SN/A issueToExecQueue(5, 5), 97360SN/A instQueue(params), 98360SN/A ldstQueue(params), 99360SN/A fuPool(params->fuPool), 100360SN/A commitToIEWDelay(params->commitToIEWDelay), 101360SN/A renameToIEWDelay(params->renameToIEWDelay), 102360SN/A issueToExecuteDelay(params->issueToExecuteDelay), 103360SN/A issueReadWidth(params->issueWidth), 104360SN/A issueWidth(params->issueWidth), 105360SN/A executeWidth(params->executeWidth), 106360SN/A numThreads(params->numberOfThreads), 107360SN/A switchedOut(false) 108360SN/A{ 109360SN/A _status = Active; 110360SN/A exeStatus = Running; 111360SN/A wbStatus = Idle; 112360SN/A 113360SN/A // Setup wire to read instructions coming from issue. 114360SN/A fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay); 115360SN/A 116360SN/A // Instruction queue needs the queue between issue and execute. 1172400SN/A instQueue.setIssueToExecuteQueue(&issueToExecQueue); 118360SN/A 1192461SN/A instQueue.setIEW(this); 1205543Ssaidi@eecs.umich.edu ldstQueue.setIEW(this); 121360SN/A 122360SN/A for (int i=0; i < numThreads; i++) { 123360SN/A dispatchStatus[i] = Running; 124360SN/A stalls[i].commit = false; 125360SN/A fetchRedirect[i] = false; 1262400SN/A } 127360SN/A 1282461SN/A updateLSQNextCycle = false; 1295543Ssaidi@eecs.umich.edu 130360SN/A skidBufferMax = (3 * (renameToIEWDelay * params->renameWidth)) + issueWidth; 131360SN/A} 132360SN/A 133360SN/Atemplate <class Impl> 134360SN/Astd::string 135360SN/ADefaultIEW<Impl>::name() const 136360SN/A{ 137360SN/A return cpu->name() + ".iew"; 138360SN/A} 139360SN/A 140360SN/Atemplate <class Impl> 141360SN/Avoid 142360SN/ADefaultIEW<Impl>::regStats() 1435543Ssaidi@eecs.umich.edu{ 144360SN/A using namespace Stats; 145360SN/A 146360SN/A instQueue.regStats(); 147360SN/A 148360SN/A iewIdleCycles 149360SN/A .name(name() + ".iewIdleCycles") 150360SN/A .desc("Number of cycles IEW is idle"); 151360SN/A 152360SN/A iewSquashCycles 153360SN/A .name(name() + ".iewSquashCycles") 154360SN/A .desc("Number of cycles IEW is squashing"); 155360SN/A 156360SN/A iewBlockCycles 157360SN/A .name(name() + ".iewBlockCycles") 158360SN/A .desc("Number of cycles IEW is blocking"); 159360SN/A 160360SN/A iewUnblockCycles 1615543Ssaidi@eecs.umich.edu .name(name() + ".iewUnblockCycles") 1625543Ssaidi@eecs.umich.edu .desc("Number of cycles IEW is unblocking"); 163502SN/A 164360SN/A iewDispatchedInsts 165360SN/A .name(name() + ".iewDispatchedInsts") 166360SN/A .desc("Number of instructions dispatched to IQ"); 167360SN/A 168360SN/A iewDispSquashedInsts 169360SN/A .name(name() + ".iewDispSquashedInsts") 170360SN/A .desc("Number of squashed instructions skipped by dispatch"); 171360SN/A 172360SN/A iewDispLoadInsts 173360SN/A .name(name() + ".iewDispLoadInsts") 174360SN/A .desc("Number of dispatched load instructions"); 175378SN/A 1761706SN/A iewDispStoreInsts 1773114Sgblack@eecs.umich.edu .name(name() + ".iewDispStoreInsts") 178378SN/A .desc("Number of dispatched store instructions"); 179378SN/A 180378SN/A iewDispNonSpecInsts 181378SN/A .name(name() + ".iewDispNonSpecInsts") 182378SN/A .desc("Number of dispatched non-speculative instructions"); 1831706SN/A 1843114Sgblack@eecs.umich.edu iewIQFullEvents 185360SN/A .name(name() + ".iewIQFullEvents") 186378SN/A .desc("Number of times the IQ has become full, causing a stall"); 1871706SN/A 1883114Sgblack@eecs.umich.edu iewLSQFullEvents 189378SN/A .name(name() + ".iewLSQFullEvents") 190378SN/A .desc("Number of times the LSQ has become full, causing a stall"); 1911706SN/A 1923114Sgblack@eecs.umich.edu iewExecutedInsts 193378SN/A .name(name() + ".iewExecutedInsts") 1945748SSteve.Reinhardt@amd.com .desc("Number of executed instructions"); 1955748SSteve.Reinhardt@amd.com 1965748SSteve.Reinhardt@amd.com iewExecLoadInsts 197378SN/A .init(cpu->number_of_threads) 198378SN/A .name(name() + ".iewExecLoadInsts") 1991706SN/A .desc("Number of load instructions executed") 2003114Sgblack@eecs.umich.edu .flags(total); 201378SN/A 202378SN/A iewExecSquashedInsts 2031706SN/A .name(name() + ".iewExecSquashedInsts") 2043114Sgblack@eecs.umich.edu .desc("Number of squashed instructions skipped in execute"); 205378SN/A 206378SN/A memOrderViolationEvents 2071706SN/A .name(name() + ".memOrderViolationEvents") 2083114Sgblack@eecs.umich.edu .desc("Number of memory order violations"); 209378SN/A 210378SN/A predictedTakenIncorrect 2111706SN/A .name(name() + ".predictedTakenIncorrect") 2123114Sgblack@eecs.umich.edu .desc("Number of branches that were predicted taken incorrectly"); 213378SN/A 2144118Sgblack@eecs.umich.edu predictedNotTakenIncorrect 2154118Sgblack@eecs.umich.edu .name(name() + ".predictedNotTakenIncorrect") 2164118Sgblack@eecs.umich.edu .desc("Number of branches that were predicted not taken incorrectly"); 2174118Sgblack@eecs.umich.edu 218378SN/A branchMispredicts 2191706SN/A .name(name() + ".branchMispredicts") 2203114Sgblack@eecs.umich.edu .desc("Number of branch mispredicts detected at execute"); 221378SN/A 222378SN/A branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect; 2231706SN/A 2243114Sgblack@eecs.umich.edu exeSwp 225360SN/A .init(cpu->number_of_threads) 2265513SMichael.Adler@intel.com .name(name() + ".EXEC:swp") 2275513SMichael.Adler@intel.com .desc("number of swp insts executed") 2285513SMichael.Adler@intel.com .flags(total) 2295513SMichael.Adler@intel.com ; 2305513SMichael.Adler@intel.com 2315513SMichael.Adler@intel.com exeNop 2325513SMichael.Adler@intel.com .init(cpu->number_of_threads) 2335513SMichael.Adler@intel.com .name(name() + ".EXEC:nop") 234511SN/A .desc("number of nop insts executed") 2351706SN/A .flags(total) 2363114Sgblack@eecs.umich.edu ; 237511SN/A 2385513SMichael.Adler@intel.com exeRefs 2395513SMichael.Adler@intel.com .init(cpu->number_of_threads) 2405513SMichael.Adler@intel.com .name(name() + ".EXEC:refs") 2415513SMichael.Adler@intel.com .desc("number of memory reference insts executed") 242511SN/A .flags(total) 2431706SN/A ; 2443114Sgblack@eecs.umich.edu 2451706SN/A exeBranches 2461706SN/A .init(cpu->number_of_threads) 2471706SN/A .name(name() + ".EXEC:branches") 2481706SN/A .desc("Number of branches executed") 2493114Sgblack@eecs.umich.edu .flags(total) 2501706SN/A ; 2511706SN/A 2521706SN/A issueRate 2531706SN/A .name(name() + ".EXEC:rate") 2543114Sgblack@eecs.umich.edu .desc("Inst execution rate") 2551706SN/A .flags(total) 256511SN/A ; 2575513SMichael.Adler@intel.com issueRate = iewExecutedInsts / cpu->numCycles; 2585513SMichael.Adler@intel.com 2595513SMichael.Adler@intel.com iewExecStoreInsts 2605513SMichael.Adler@intel.com .name(name() + ".EXEC:stores") 2615513SMichael.Adler@intel.com .desc("Number of stores executed") 2621999SN/A .flags(total) 2631999SN/A ; 2643114Sgblack@eecs.umich.edu iewExecStoreInsts = exeRefs - iewExecLoadInsts; 2651999SN/A/* 2661999SN/A for (int i=0; i<Num_OpClasses; ++i) { 2671999SN/A stringstream subname; 2681999SN/A subname << opClassStrings[i] << "_delay"; 2693114Sgblack@eecs.umich.edu issue_delay_dist.subname(i, subname.str()); 2701999SN/A } 2713079Sstever@eecs.umich.edu*/ 2723079Sstever@eecs.umich.edu // 2733114Sgblack@eecs.umich.edu // Other stats 2743079Sstever@eecs.umich.edu // 2752093SN/A 2762093SN/A iewInstsToCommit 2773114Sgblack@eecs.umich.edu .init(cpu->number_of_threads) 2782093SN/A .name(name() + ".WB:sent") 2792687Sksewell@umich.edu .desc("cumulative count of insts sent to commit") 2802687Sksewell@umich.edu .flags(total) 2813114Sgblack@eecs.umich.edu ; 2822687Sksewell@umich.edu 2832238SN/A writebackCount 2842238SN/A .init(cpu->number_of_threads) 2853114Sgblack@eecs.umich.edu .name(name() + ".WB:count") 2862238SN/A .desc("cumulative count of insts written-back") 2872238SN/A .flags(total) 2882238SN/A ; 2893114Sgblack@eecs.umich.edu 2902238SN/A producerInst 2912238SN/A .init(cpu->number_of_threads) 2922238SN/A .name(name() + ".WB:producers") 2933114Sgblack@eecs.umich.edu .desc("num instructions producing a value") 2942238SN/A .flags(total) 2952238SN/A ; 2962238SN/A 2973114Sgblack@eecs.umich.edu consumerInst 2982238SN/A .init(cpu->number_of_threads) 2992238SN/A .name(name() + ".WB:consumers") 3002238SN/A .desc("num instructions consuming a value") 3013114Sgblack@eecs.umich.edu .flags(total) 3022238SN/A ; 3032238SN/A 3042238SN/A wbPenalized 3053114Sgblack@eecs.umich.edu .init(cpu->number_of_threads) 3062238SN/A .name(name() + ".WB:penalized") 3072238SN/A .desc("number of instrctions required to write to 'other' IQ") 3082238SN/A .flags(total) 3093114Sgblack@eecs.umich.edu ; 3102238SN/A 3112238SN/A wbPenalizedRate 3122238SN/A .name(name() + ".WB:penalized_rate") 3132238SN/A .desc ("fraction of instructions written-back that wrote to 'other' IQ") 3142238SN/A .flags(total) 3152238SN/A ; 3163114Sgblack@eecs.umich.edu 3172238SN/A wbPenalizedRate = wbPenalized / writebackCount; 3182238SN/A 3192238SN/A wbFanout 3203114Sgblack@eecs.umich.edu .name(name() + ".WB:fanout") 3212238SN/A .desc("average fanout of values written-back") 3222238SN/A .flags(total) 3232238SN/A ; 3243114Sgblack@eecs.umich.edu 3252238SN/A wbFanout = producerInst / consumerInst; 3262238SN/A 3272238SN/A wbRate 3283114Sgblack@eecs.umich.edu .name(name() + ".WB:rate") 3292238SN/A .desc("insts written-back per cycle") 3302238SN/A .flags(total) 3311354SN/A ; 3321354SN/A wbRate = writebackCount / cpu->numCycles; 3331354SN/A} 3341354SN/A 3351354SN/Atemplate<class Impl> 3361354SN/Avoid 3371354SN/ADefaultIEW<Impl>::initStage() 3381354SN/A{ 3391354SN/A for (int tid=0; tid < numThreads; tid++) { 3401354SN/A toRename->iewInfo[tid].usedIQ = true; 3411354SN/A toRename->iewInfo[tid].freeIQEntries = 3421354SN/A instQueue.numFreeEntries(tid); 3431354SN/A 3441354SN/A toRename->iewInfo[tid].usedLSQ = true; 3451609SN/A toRename->iewInfo[tid].freeLSQEntries = 3461354SN/A ldstQueue.numFreeEntries(tid); 3471354SN/A } 3481354SN/A} 3491354SN/A 350360SN/Atemplate<class Impl> 351360SN/Avoid 352360SN/ADefaultIEW<Impl>::setCPU(FullCPU *cpu_ptr) 353360SN/A{ 354360SN/A DPRINTF(IEW, "Setting CPU pointer.\n"); 355360SN/A cpu = cpu_ptr; 356360SN/A 3573113Sgblack@eecs.umich.edu instQueue.setCPU(cpu_ptr); 3583113Sgblack@eecs.umich.edu ldstQueue.setCPU(cpu_ptr); 3593113Sgblack@eecs.umich.edu 3603113Sgblack@eecs.umich.edu cpu->activateStage(FullCPU::IEWIdx); 3613113Sgblack@eecs.umich.edu} 3623113Sgblack@eecs.umich.edu 3633113Sgblack@eecs.umich.edutemplate<class Impl> 3643113Sgblack@eecs.umich.eduvoid 3653113Sgblack@eecs.umich.eduDefaultIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 3663113Sgblack@eecs.umich.edu{ 3673113Sgblack@eecs.umich.edu DPRINTF(IEW, "Setting time buffer pointer.\n"); 3683113Sgblack@eecs.umich.edu timeBuffer = tb_ptr; 3693113Sgblack@eecs.umich.edu 3703113Sgblack@eecs.umich.edu // Setup wire to read information from time buffer, from commit. 3713113Sgblack@eecs.umich.edu fromCommit = timeBuffer->getWire(-commitToIEWDelay); 3723113Sgblack@eecs.umich.edu 3734189Sgblack@eecs.umich.edu // Setup wire to write information back to previous stages. 3744189Sgblack@eecs.umich.edu toRename = timeBuffer->getWire(0); 3753113Sgblack@eecs.umich.edu 3763113Sgblack@eecs.umich.edu toFetch = timeBuffer->getWire(0); 3773113Sgblack@eecs.umich.edu 3783113Sgblack@eecs.umich.edu // Instruction queue also needs main time buffer. 3793113Sgblack@eecs.umich.edu instQueue.setTimeBuffer(tb_ptr); 3803113Sgblack@eecs.umich.edu} 3813113Sgblack@eecs.umich.edu 3823277Sgblack@eecs.umich.edutemplate<class Impl> 3835515SMichael.Adler@intel.comvoid 3845515SMichael.Adler@intel.comDefaultIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) 3855515SMichael.Adler@intel.com{ 3865515SMichael.Adler@intel.com DPRINTF(IEW, "Setting rename queue pointer.\n"); 3875515SMichael.Adler@intel.com renameQueue = rq_ptr; 3883277Sgblack@eecs.umich.edu 3893277Sgblack@eecs.umich.edu // Setup wire to read information from rename queue. 3903277Sgblack@eecs.umich.edu fromRename = renameQueue->getWire(-renameToIEWDelay); 3913277Sgblack@eecs.umich.edu} 3923277Sgblack@eecs.umich.edu 3933277Sgblack@eecs.umich.edutemplate<class Impl> 3943277Sgblack@eecs.umich.eduvoid 3953113Sgblack@eecs.umich.eduDefaultIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr) 3963113Sgblack@eecs.umich.edu{ 3973113Sgblack@eecs.umich.edu DPRINTF(IEW, "Setting IEW queue pointer.\n"); 3983113Sgblack@eecs.umich.edu iewQueue = iq_ptr; 3993113Sgblack@eecs.umich.edu 4003113Sgblack@eecs.umich.edu // Setup wire to write instructions to commit. 4013113Sgblack@eecs.umich.edu toCommit = iewQueue->getWire(0); 4023114Sgblack@eecs.umich.edu} 4033113Sgblack@eecs.umich.edu 4043114Sgblack@eecs.umich.edutemplate<class Impl> 4053113Sgblack@eecs.umich.eduvoid 4063114Sgblack@eecs.umich.eduDefaultIEW<Impl>::setActiveThreads(list<unsigned> *at_ptr) 4073113Sgblack@eecs.umich.edu{ 4084061Sgblack@eecs.umich.edu DPRINTF(IEW, "Setting active threads list pointer.\n"); 4094061Sgblack@eecs.umich.edu activeThreads = at_ptr; 4104061Sgblack@eecs.umich.edu 4113113Sgblack@eecs.umich.edu ldstQueue.setActiveThreads(at_ptr); 4123113Sgblack@eecs.umich.edu instQueue.setActiveThreads(at_ptr); 4133113Sgblack@eecs.umich.edu} 4143113Sgblack@eecs.umich.edu 4153113Sgblack@eecs.umich.edutemplate<class Impl> 4163113Sgblack@eecs.umich.eduvoid 4173113Sgblack@eecs.umich.eduDefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr) 4183113Sgblack@eecs.umich.edu{ 4193113Sgblack@eecs.umich.edu DPRINTF(IEW, "Setting scoreboard pointer.\n"); 4203113Sgblack@eecs.umich.edu scoreboard = sb_ptr; 4213113Sgblack@eecs.umich.edu} 4224189Sgblack@eecs.umich.edu 4234189Sgblack@eecs.umich.edu#if 0 4243113Sgblack@eecs.umich.edutemplate<class Impl> 4253113Sgblack@eecs.umich.eduvoid 4263113Sgblack@eecs.umich.eduDefaultIEW<Impl>::setPageTable(PageTable *pt_ptr) 4273113Sgblack@eecs.umich.edu{ 4283113Sgblack@eecs.umich.edu ldstQueue.setPageTable(pt_ptr); 4293113Sgblack@eecs.umich.edu} 4303113Sgblack@eecs.umich.edu#endif 4313113Sgblack@eecs.umich.edu 4323113Sgblack@eecs.umich.edutemplate <class Impl> 4333113Sgblack@eecs.umich.eduvoid 4343113Sgblack@eecs.umich.eduDefaultIEW<Impl>::switchOut() 4353113Sgblack@eecs.umich.edu{ 4363113Sgblack@eecs.umich.edu cpu->signalSwitched(); 4373113Sgblack@eecs.umich.edu} 4383113Sgblack@eecs.umich.edu 4393113Sgblack@eecs.umich.edutemplate <class Impl> 4403113Sgblack@eecs.umich.eduvoid 4413113Sgblack@eecs.umich.eduDefaultIEW<Impl>::doSwitchOut() 4423113Sgblack@eecs.umich.edu{ 4433113Sgblack@eecs.umich.edu switchedOut = true; 4443113Sgblack@eecs.umich.edu 4453113Sgblack@eecs.umich.edu instQueue.switchOut(); 4463113Sgblack@eecs.umich.edu ldstQueue.switchOut(); 4473113Sgblack@eecs.umich.edu fuPool->switchOut(); 4483113Sgblack@eecs.umich.edu 4493113Sgblack@eecs.umich.edu for (int i = 0; i < numThreads; i++) { 4503113Sgblack@eecs.umich.edu while (!insts[i].empty()) 4513113Sgblack@eecs.umich.edu insts[i].pop(); 4523113Sgblack@eecs.umich.edu while (!skidBuffer[i].empty()) 4533113Sgblack@eecs.umich.edu skidBuffer[i].pop(); 4543113Sgblack@eecs.umich.edu } 4553113Sgblack@eecs.umich.edu} 4563113Sgblack@eecs.umich.edu 4573113Sgblack@eecs.umich.edutemplate <class Impl> 4583113Sgblack@eecs.umich.eduvoid 4593113Sgblack@eecs.umich.eduDefaultIEW<Impl>::takeOverFrom() 4603113Sgblack@eecs.umich.edu{ 4613113Sgblack@eecs.umich.edu _status = Active; 462378SN/A exeStatus = Running; 463378SN/A wbStatus = Idle; 464378SN/A switchedOut = false; 465360SN/A 4661450SN/A instQueue.takeOverFrom(); 4673114Sgblack@eecs.umich.edu ldstQueue.takeOverFrom(); 4682680Sktlim@umich.edu fuPool->takeOverFrom(); 469360SN/A 4705958Sgblack@eecs.umich.edu initStage(); 4715958Sgblack@eecs.umich.edu cpu->activityThisCycle(); 472360SN/A 4731969SN/A for (int i=0; i < numThreads; i++) { 474360SN/A dispatchStatus[i] = Running; 475360SN/A stalls[i].commit = false; 476360SN/A fetchRedirect[i] = false; 4771458SN/A } 478360SN/A 479360SN/A updateLSQNextCycle = false; 480360SN/A 4814131Sbinkertn@umich.edu // @todo: Fix hardcoded number 4824131Sbinkertn@umich.edu for (int i = 0; i < 6; ++i) { 4834131Sbinkertn@umich.edu issueToExecQueue.advance(); 4844131Sbinkertn@umich.edu } 4854131Sbinkertn@umich.edu} 4864131Sbinkertn@umich.edu 4874131Sbinkertn@umich.edutemplate<class Impl> 4884131Sbinkertn@umich.eduvoid 4891458SN/ADefaultIEW<Impl>::squash(unsigned tid) 490360SN/A{ 491360SN/A DPRINTF(IEW, "[tid:%i]: Squashing all instructions.\n", 4921706SN/A tid); 4932680Sktlim@umich.edu 494360SN/A // Tell the IQ to start squashing. 495360SN/A instQueue.squash(tid); 496360SN/A 497378SN/A // Tell the LDSTQ to start squashing. 498360SN/A ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid); 4991450SN/A 5003114Sgblack@eecs.umich.edu updatedQueues = true; 5012680Sktlim@umich.edu 502360SN/A // Clear the skid buffer in case it has any data in it. 503360SN/A while (!skidBuffer[tid].empty()) { 504360SN/A 5055958Sgblack@eecs.umich.edu if (skidBuffer[tid].front()->isLoad() || 5061458SN/A skidBuffer[tid].front()->isStore() ) { 507360SN/A toRename->iewInfo[tid].dispatchedToLSQ++; 508360SN/A } 509360SN/A 510360SN/A toRename->iewInfo[tid].dispatched++; 5111706SN/A 5121458SN/A skidBuffer[tid].pop(); 513360SN/A } 514360SN/A 5155958Sgblack@eecs.umich.edu while (!insts[tid].empty()) { 5165958Sgblack@eecs.umich.edu if (insts[tid].front()->isLoad() || 517360SN/A insts[tid].front()->isStore() ) { 518360SN/A toRename->iewInfo[tid].dispatchedToLSQ++; 519360SN/A } 520360SN/A 521360SN/A toRename->iewInfo[tid].dispatched++; 522360SN/A 523360SN/A insts[tid].pop(); 524360SN/A } 525360SN/A} 526360SN/A 527360SN/Atemplate<class Impl> 528360SN/Avoid 5291706SN/ADefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, unsigned tid) 530360SN/A{ 531360SN/A DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %#x " 532360SN/A "[sn:%i].\n", tid, inst->readPC(), inst->seqNum); 533360SN/A 534360SN/A toCommit->squash[tid] = true; 5353669Sbinkertn@umich.edu toCommit->squashedSeqNum[tid] = inst->seqNum; 5363669Sbinkertn@umich.edu toCommit->mispredPC[tid] = inst->readPC(); 5373669Sbinkertn@umich.edu toCommit->nextPC[tid] = inst->readNextPC(); 5381706SN/A toCommit->branchMispredict[tid] = true; 5391706SN/A toCommit->branchTaken[tid] = inst->readNextPC() != 5405795Ssaidi@eecs.umich.edu (inst->readPC() + sizeof(TheISA::MachInst)); 5415795Ssaidi@eecs.umich.edu 5425795Ssaidi@eecs.umich.edu toCommit->includeSquashInst[tid] = false; 5435795Ssaidi@eecs.umich.edu 5445795Ssaidi@eecs.umich.edu wroteToTimeBuffer = true; 5455795Ssaidi@eecs.umich.edu} 5465795Ssaidi@eecs.umich.edu 5475795Ssaidi@eecs.umich.edutemplate<class Impl> 5485795Ssaidi@eecs.umich.eduvoid 5495795Ssaidi@eecs.umich.eduDefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid) 5505795Ssaidi@eecs.umich.edu{ 551360SN/A DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, " 552360SN/A "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum); 553360SN/A 554360SN/A toCommit->squash[tid] = true; 5551999SN/A toCommit->squashedSeqNum[tid] = inst->seqNum; 5561999SN/A toCommit->nextPC[tid] = inst->readNextPC(); 5571999SN/A 5583114Sgblack@eecs.umich.edu toCommit->includeSquashInst[tid] = false; 5592680Sktlim@umich.edu 5601999SN/A wroteToTimeBuffer = true; 5611999SN/A} 5621999SN/A 5635958Sgblack@eecs.umich.edutemplate<class Impl> 5641999SN/Avoid 5651999SN/ADefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid) 5665958Sgblack@eecs.umich.edu{ 5671999SN/A DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, " 5681999SN/A "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum); 5691999SN/A 5701999SN/A toCommit->squash[tid] = true; 5711999SN/A toCommit->squashedSeqNum[tid] = inst->seqNum; 5723669Sbinkertn@umich.edu toCommit->nextPC[tid] = inst->readPC(); 5733669Sbinkertn@umich.edu 5743669Sbinkertn@umich.edu toCommit->includeSquashInst[tid] = true; 5751999SN/A 5761999SN/A ldstQueue.setLoadBlockedHandled(tid); 5771999SN/A 5782218SN/A wroteToTimeBuffer = true; 5791999SN/A} 5801999SN/A 5811999SN/Atemplate<class Impl> 5821999SN/Avoid 5831999SN/ADefaultIEW<Impl>::block(unsigned tid) 5841999SN/A{ 5851999SN/A DPRINTF(IEW, "[tid:%u]: Blocking.\n", tid); 5861999SN/A 5873114Sgblack@eecs.umich.edu if (dispatchStatus[tid] != Blocked && 5882680Sktlim@umich.edu dispatchStatus[tid] != Unblocking) { 5891999SN/A toRename->iewBlock[tid] = true; 5905958Sgblack@eecs.umich.edu wroteToTimeBuffer = true; 5911999SN/A } 5921999SN/A 5931999SN/A // Add the current inputs to the skid buffer so they can be 5941999SN/A // reprocessed when this stage unblocks. 5951999SN/A skidInsert(tid); 5965958Sgblack@eecs.umich.edu 5971999SN/A dispatchStatus[tid] = Blocked; 5981999SN/A} 5991999SN/A 6001999SN/Atemplate<class Impl> 6011999SN/Avoid 6021999SN/ADefaultIEW<Impl>::unblock(unsigned tid) 6031999SN/A{ 6041999SN/A DPRINTF(IEW, "[tid:%i]: Reading instructions out of the skid " 6052218SN/A "buffer %u.\n",tid, tid); 6061999SN/A 6071999SN/A // If the skid bufffer is empty, signal back to previous stages to unblock. 6081999SN/A // Also switch status to running. 6091999SN/A if (skidBuffer[tid].empty()) { 6105877Shsul@eecs.umich.edu toRename->iewUnblock[tid] = true; 6115877Shsul@eecs.umich.edu wroteToTimeBuffer = true; 6125877Shsul@eecs.umich.edu DPRINTF(IEW, "[tid:%i]: Done unblocking.\n",tid); 6135877Shsul@eecs.umich.edu dispatchStatus[tid] = Running; 6145877Shsul@eecs.umich.edu } 6155958Sgblack@eecs.umich.edu} 6165958Sgblack@eecs.umich.edu 6175958Sgblack@eecs.umich.edutemplate<class Impl> 6185958Sgblack@eecs.umich.eduvoid 6195877Shsul@eecs.umich.eduDefaultIEW<Impl>::wakeDependents(DynInstPtr &inst) 6205877Shsul@eecs.umich.edu{ 6215877Shsul@eecs.umich.edu instQueue.wakeDependents(inst); 6225877Shsul@eecs.umich.edu} 6235877Shsul@eecs.umich.edu 6245877Shsul@eecs.umich.edutemplate<class Impl> 6255877Shsul@eecs.umich.eduvoid 6265877Shsul@eecs.umich.eduDefaultIEW<Impl>::rescheduleMemInst(DynInstPtr &inst) 6275877Shsul@eecs.umich.edu{ 6285877Shsul@eecs.umich.edu instQueue.rescheduleMemInst(inst); 6295877Shsul@eecs.umich.edu} 6305877Shsul@eecs.umich.edu 6315877Shsul@eecs.umich.edutemplate<class Impl> 6325877Shsul@eecs.umich.eduvoid 6335877Shsul@eecs.umich.eduDefaultIEW<Impl>::replayMemInst(DynInstPtr &inst) 6345877Shsul@eecs.umich.edu{ 6355877Shsul@eecs.umich.edu instQueue.replayMemInst(inst); 6365877Shsul@eecs.umich.edu} 6375877Shsul@eecs.umich.edu 6385877Shsul@eecs.umich.edutemplate<class Impl> 6395877Shsul@eecs.umich.eduvoid 6405877Shsul@eecs.umich.eduDefaultIEW<Impl>::instToCommit(DynInstPtr &inst) 6415877Shsul@eecs.umich.edu{ 6425877Shsul@eecs.umich.edu // First check the time slot that this instruction will write 6435877Shsul@eecs.umich.edu // to. If there are free write ports at the time, then go ahead 6445877Shsul@eecs.umich.edu // and write the instruction to that time. If there are not, 6455877Shsul@eecs.umich.edu // keep looking back to see where's the first time there's a 6465877Shsul@eecs.umich.edu // free slot. 6475877Shsul@eecs.umich.edu while ((*iewQueue)[wbCycle].insts[wbNumInst]) { 6485877Shsul@eecs.umich.edu ++wbNumInst; 6495877Shsul@eecs.umich.edu if (wbNumInst == issueWidth) { 6505877Shsul@eecs.umich.edu ++wbCycle; 6515877Shsul@eecs.umich.edu wbNumInst = 0; 6525877Shsul@eecs.umich.edu } 6535877Shsul@eecs.umich.edu 6545877Shsul@eecs.umich.edu assert(wbCycle < 5); 6551999SN/A } 656378SN/A 657360SN/A // Add finished instruction to queue to commit. 6581450SN/A (*iewQueue)[wbCycle].insts[wbNumInst] = inst; 6593114Sgblack@eecs.umich.edu (*iewQueue)[wbCycle].size++; 6602680Sktlim@umich.edu} 661360SN/A 662360SN/Atemplate <class Impl> 663360SN/Aunsigned 6645958Sgblack@eecs.umich.eduDefaultIEW<Impl>::validInstsFromRename() 6652400SN/A{ 666360SN/A unsigned inst_count = 0; 6673669Sbinkertn@umich.edu 6683669Sbinkertn@umich.edu for (int i=0; i<fromRename->size; i++) { 6693669Sbinkertn@umich.edu if (!fromRename->insts[i]->squashed) 670360SN/A inst_count++; 671360SN/A } 672360SN/A 673360SN/A return inst_count; 6742218SN/A} 675360SN/A 6765958Sgblack@eecs.umich.edutemplate<class Impl> 6775958Sgblack@eecs.umich.eduvoid 678360SN/ADefaultIEW<Impl>::skidInsert(unsigned tid) 6791458SN/A{ 680360SN/A DynInstPtr inst = NULL; 681360SN/A 682360SN/A while (!insts[tid].empty()) { 6835074Ssaidi@eecs.umich.edu inst = insts[tid].front(); 6845074Ssaidi@eecs.umich.edu 6855074Ssaidi@eecs.umich.edu insts[tid].pop(); 6865074Ssaidi@eecs.umich.edu 6875074Ssaidi@eecs.umich.edu DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%#x into " 6885074Ssaidi@eecs.umich.edu "dispatch skidBuffer %i\n",tid, inst->seqNum, 6895074Ssaidi@eecs.umich.edu inst->readPC(),tid); 6905074Ssaidi@eecs.umich.edu 6915958Sgblack@eecs.umich.edu skidBuffer[tid].push(inst); 6925074Ssaidi@eecs.umich.edu } 6935074Ssaidi@eecs.umich.edu 6945074Ssaidi@eecs.umich.edu assert(skidBuffer[tid].size() <= skidBufferMax && 6955074Ssaidi@eecs.umich.edu "Skidbuffer Exceeded Max Size"); 6965074Ssaidi@eecs.umich.edu} 6975208Ssaidi@eecs.umich.edu 6985208Ssaidi@eecs.umich.edutemplate<class Impl> 6995208Ssaidi@eecs.umich.eduint 7005208Ssaidi@eecs.umich.eduDefaultIEW<Impl>::skidCount() 7015074Ssaidi@eecs.umich.edu{ 7025074Ssaidi@eecs.umich.edu int max=0; 7035208Ssaidi@eecs.umich.edu 7045074Ssaidi@eecs.umich.edu list<unsigned>::iterator threads = (*activeThreads).begin(); 7055074Ssaidi@eecs.umich.edu 7065074Ssaidi@eecs.umich.edu while (threads != (*activeThreads).end()) { 7075074Ssaidi@eecs.umich.edu unsigned thread_count = skidBuffer[*threads++].size(); 7085958Sgblack@eecs.umich.edu if (max < thread_count) 7095958Sgblack@eecs.umich.edu max = thread_count; 7105074Ssaidi@eecs.umich.edu } 7115074Ssaidi@eecs.umich.edu 7125074Ssaidi@eecs.umich.edu return max; 7135074Ssaidi@eecs.umich.edu} 7145074Ssaidi@eecs.umich.edu 7151999SN/Atemplate<class Impl> 7161999SN/Abool 7171999SN/ADefaultIEW<Impl>::skidsEmpty() 7183114Sgblack@eecs.umich.edu{ 7192680Sktlim@umich.edu list<unsigned>::iterator threads = (*activeThreads).begin(); 7201999SN/A 7215958Sgblack@eecs.umich.edu while (threads != (*activeThreads).end()) { 7221999SN/A if (!skidBuffer[*threads++].empty()) 7231999SN/A return false; 7241999SN/A } 7251999SN/A 7261999SN/A return true; 7272764Sstever@eecs.umich.edu} 7282064SN/A 7292064SN/Atemplate <class Impl> 7302064SN/Avoid 7312064SN/ADefaultIEW<Impl>::updateStatus() 7321999SN/A{ 7332064SN/A bool any_unblocking = false; 7341999SN/A 7351999SN/A list<unsigned>::iterator threads = (*activeThreads).begin(); 7362218SN/A 7371999SN/A threads = (*activeThreads).begin(); 7385958Sgblack@eecs.umich.edu 7393114Sgblack@eecs.umich.edu while (threads != (*activeThreads).end()) { 7401999SN/A unsigned tid = *threads++; 7411999SN/A 7421999SN/A if (dispatchStatus[tid] == Unblocking) { 7431999SN/A any_unblocking = true; 7441999SN/A break; 745378SN/A } 746360SN/A } 7471450SN/A 7483114Sgblack@eecs.umich.edu // If there are no ready instructions waiting to be scheduled by the IQ, 7492680Sktlim@umich.edu // and there's no stores waiting to write back, and dispatch is not 750360SN/A // unblocking, then there is no internal activity for the IEW stage. 751360SN/A if (_status == Active && !instQueue.hasReadyInsts() && 752360SN/A !ldstQueue.willWB() && !any_unblocking) { 7535958Sgblack@eecs.umich.edu DPRINTF(IEW, "IEW switching to idle\n"); 7542400SN/A 755360SN/A deactivateStage(); 7563669Sbinkertn@umich.edu 7573669Sbinkertn@umich.edu _status = Inactive; 7583669Sbinkertn@umich.edu } else if (_status == Inactive && (instQueue.hasReadyInsts() || 759360SN/A ldstQueue.willWB() || 760360SN/A any_unblocking)) { 761360SN/A // Otherwise there is internal activity. Set to active. 762360SN/A DPRINTF(IEW, "IEW switching to active\n"); 7631458SN/A 764360SN/A activateStage(); 7655958Sgblack@eecs.umich.edu 7665958Sgblack@eecs.umich.edu _status = Active; 767360SN/A } 7681458SN/A} 769360SN/A 770360SN/Atemplate <class Impl> 7711999SN/Avoid 7721999SN/ADefaultIEW<Impl>::resetEntries() 7731999SN/A{ 7743114Sgblack@eecs.umich.edu instQueue.resetEntries(); 7752680Sktlim@umich.edu ldstQueue.resetEntries(); 7761999SN/A} 7771999SN/A 7781999SN/Atemplate <class Impl> 7795958Sgblack@eecs.umich.eduvoid 7802400SN/ADefaultIEW<Impl>::readStallSignals(unsigned tid) 7811999SN/A{ 7823669Sbinkertn@umich.edu if (fromCommit->commitBlock[tid]) { 7833669Sbinkertn@umich.edu stalls[tid].commit = true; 7843669Sbinkertn@umich.edu } 7852764Sstever@eecs.umich.edu 7862064SN/A if (fromCommit->commitUnblock[tid]) { 7872064SN/A assert(stalls[tid].commit); 7882064SN/A stalls[tid].commit = false; 7891999SN/A } 7901999SN/A} 7912064SN/A 7921999SN/Atemplate <class Impl> 7931999SN/Abool 7941999SN/ADefaultIEW<Impl>::checkStall(unsigned tid) 7951999SN/A{ 7965958Sgblack@eecs.umich.edu bool ret_val(false); 7975958Sgblack@eecs.umich.edu 7981999SN/A if (stalls[tid].commit) { 7991999SN/A DPRINTF(IEW,"[tid:%i]: Stall from Commit stage detected.\n",tid); 8001999SN/A ret_val = true; 8011999SN/A } else if (instQueue.isFull(tid)) { 802378SN/A DPRINTF(IEW,"[tid:%i]: Stall: IQ is full.\n",tid); 803360SN/A ret_val = true; 8041450SN/A } else if (ldstQueue.isFull(tid)) { 8053114Sgblack@eecs.umich.edu DPRINTF(IEW,"[tid:%i]: Stall: LSQ is full\n",tid); 8062680Sktlim@umich.edu 807360SN/A if (ldstQueue.numLoads(tid) > 0 ) { 8085958Sgblack@eecs.umich.edu 809360SN/A DPRINTF(IEW,"[tid:%i]: LSQ oldest load: [sn:%i] \n", 8101969SN/A tid,ldstQueue.getLoadHeadSeqNum(tid)); 811360SN/A } 812360SN/A 8131458SN/A if (ldstQueue.numStores(tid) > 0) { 814360SN/A 815360SN/A DPRINTF(IEW,"[tid:%i]: LSQ oldest store: [sn:%i] \n", 816360SN/A tid,ldstQueue.getStoreHeadSeqNum(tid)); 817360SN/A } 818360SN/A 8191458SN/A ret_val = true; 820360SN/A } else if (ldstQueue.isStalled(tid)) { 8215958Sgblack@eecs.umich.edu DPRINTF(IEW,"[tid:%i]: Stall: LSQ stall detected.\n",tid); 8223114Sgblack@eecs.umich.edu ret_val = true; 8232021SN/A } 8241458SN/A 825360SN/A return ret_val; 826360SN/A} 827360SN/A 8281706SN/Atemplate <class Impl> 8291706SN/Avoid 8301706SN/ADefaultIEW<Impl>::checkSignalsAndUpdate(unsigned tid) 8313114Sgblack@eecs.umich.edu{ 8322680Sktlim@umich.edu // Check if there's a squash signal, squash if there is 8331706SN/A // Check stall signals, block if there is. 8341706SN/A // If status was Blocked 8351706SN/A // if so then go to unblocking 8365958Sgblack@eecs.umich.edu // If status was Squashing 8372400SN/A // check if squashing is not high. Switch to running this cycle. 8381706SN/A 8393669Sbinkertn@umich.edu readStallSignals(tid); 8403669Sbinkertn@umich.edu 8413669Sbinkertn@umich.edu if (fromCommit->commitInfo[tid].squash) { 8421706SN/A squash(tid); 8431706SN/A 8441706SN/A if (dispatchStatus[tid] == Blocked || 8451706SN/A dispatchStatus[tid] == Unblocking) { 8462218SN/A toRename->iewUnblock[tid] = true; 8471706SN/A wroteToTimeBuffer = true; 8483114Sgblack@eecs.umich.edu } 8495958Sgblack@eecs.umich.edu 8501706SN/A dispatchStatus[tid] = Squashing; 8511706SN/A 8521706SN/A fetchRedirect[tid] = false; 8531706SN/A return; 8541706SN/A } 8551706SN/A 8561706SN/A if (fromCommit->commitInfo[tid].robSquashing) { 8571706SN/A DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n"); 8583114Sgblack@eecs.umich.edu 8592680Sktlim@umich.edu dispatchStatus[tid] = Squashing; 8601706SN/A 8615958Sgblack@eecs.umich.edu return; 8621706SN/A } 8631706SN/A 8641706SN/A if (checkStall(tid)) { 8651706SN/A block(tid); 8661706SN/A dispatchStatus[tid] = Blocked; 8671706SN/A return; 8681706SN/A } 8691706SN/A 8702218SN/A if (dispatchStatus[tid] == Blocked) { 8711706SN/A // Status from previous cycle was blocked, but there are no more stall 8725958Sgblack@eecs.umich.edu // conditions. Switch over to unblocking. 8733114Sgblack@eecs.umich.edu DPRINTF(IEW, "[tid:%i]: Done blocking, switching to unblocking.\n", 8741706SN/A tid); 8751706SN/A 8761706SN/A dispatchStatus[tid] = Unblocking; 8771706SN/A 8781706SN/A unblock(tid); 8791999SN/A 8801999SN/A return; 8811999SN/A } 8823114Sgblack@eecs.umich.edu 8832680Sktlim@umich.edu if (dispatchStatus[tid] == Squashing) { 8841999SN/A // Switch status to running if rename isn't being told to block or 8855958Sgblack@eecs.umich.edu // squash this cycle. 8861999SN/A DPRINTF(IEW, "[tid:%i]: Done squashing, switching to running.\n", 8871999SN/A tid); 8881999SN/A 8891999SN/A dispatchStatus[tid] = Running; 8901999SN/A 8912680Sktlim@umich.edu return; 8925958Sgblack@eecs.umich.edu } 8935958Sgblack@eecs.umich.edu} 8941999SN/A 8951999SN/Atemplate <class Impl> 8961999SN/Avoid 8971999SN/ADefaultIEW<Impl>::sortInsts() 8982461SN/A{ 8992461SN/A int insts_from_rename = fromRename->size; 9002461SN/A#ifdef DEBUG 9012091SN/A for (int i = 0; i < numThreads; i++) 9021999SN/A assert(insts[i].empty()); 9032461SN/A#endif 9042461SN/A for (int i = 0; i < insts_from_rename; ++i) { 9051999SN/A insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]); 9061999SN/A } 9071999SN/A} 9081999SN/A 9091999SN/Atemplate <class Impl> 9101999SN/Avoid 9111999SN/ADefaultIEW<Impl>::wakeCPU() 9121999SN/A{ 9131999SN/A cpu->wakeCPU(); 9141999SN/A} 9152218SN/A 9161999SN/Atemplate <class Impl> 9171999SN/Avoid 9181999SN/ADefaultIEW<Impl>::activityThisCycle() 9191999SN/A{ 9201999SN/A DPRINTF(Activity, "Activity this cycle.\n"); 921378SN/A cpu->activityThisCycle(); 922378SN/A} 923378SN/A 924378SN/Atemplate <class Impl> 925378SN/Ainline void 926378SN/ADefaultIEW<Impl>::activateStage() 927378SN/A{ 928378SN/A DPRINTF(Activity, "Activating stage.\n"); 929360SN/A cpu->activateStage(FullCPU::IEWIdx); 930378SN/A} 931378SN/A 932378SN/Atemplate <class Impl> 933360SN/Ainline void 9341450SN/ADefaultIEW<Impl>::deactivateStage() 9353114Sgblack@eecs.umich.edu{ 936360SN/A DPRINTF(Activity, "Deactivating stage.\n"); 9375958Sgblack@eecs.umich.edu cpu->deactivateStage(FullCPU::IEWIdx); 9385958Sgblack@eecs.umich.edu} 9395958Sgblack@eecs.umich.edu 9405958Sgblack@eecs.umich.edutemplate<class Impl> 9415958Sgblack@eecs.umich.eduvoid 9425958Sgblack@eecs.umich.eduDefaultIEW<Impl>::dispatch(unsigned tid) 943360SN/A{ 9445877Shsul@eecs.umich.edu // If status is Running or idle, 9452544SN/A // call dispatchInsts() 9462544SN/A // If status is Unblocking, 9472544SN/A // buffer any instructions coming from rename 9482544SN/A // continue trying to empty skid buffer 9492544SN/A // check if stall conditions have passed 9502544SN/A 951360SN/A if (dispatchStatus[tid] == Blocked) { 952360SN/A ++iewBlockCycles; 9532544SN/A 9542544SN/A } else if (dispatchStatus[tid] == Squashing) { 9552544SN/A ++iewSquashCycles; 9562544SN/A } 9572544SN/A 9582544SN/A // Dispatch should try to dispatch as many instructions as its bandwidth 9592544SN/A // will allow, as long as it is not currently blocked. 9602544SN/A if (dispatchStatus[tid] == Running || 9612544SN/A dispatchStatus[tid] == Idle) { 9622544SN/A DPRINTF(IEW, "[tid:%i] Not blocked, so attempting to run " 9632553SN/A "dispatch.\n", tid); 9641969SN/A 9655958Sgblack@eecs.umich.edu dispatchInsts(tid); 966360SN/A } else if (dispatchStatus[tid] == Unblocking) { 967360SN/A // Make sure that the skid buffer has something in it if the 9681458SN/A // status is unblocking. 969360SN/A assert(!skidsEmpty()); 970360SN/A 971378SN/A // If the status was unblocking, then instructions from the skid 972360SN/A // buffer were used. Remove those instructions and handle 9731450SN/A // the rest of unblocking. 9743114Sgblack@eecs.umich.edu dispatchInsts(tid); 9752680Sktlim@umich.edu 976360SN/A ++iewUnblockCycles; 9775958Sgblack@eecs.umich.edu 9785958Sgblack@eecs.umich.edu if (validInstsFromRename() && dispatchedAllInsts) { 979360SN/A // Add the current inputs to the skid buffer so they can be 980360SN/A // reprocessed when this stage unblocks. 9812064SN/A skidInsert(tid); 9825877Shsul@eecs.umich.edu } 9832064SN/A 9842091SN/A unblock(tid); 9852091SN/A } 9862064SN/A} 987360SN/A 9885877Shsul@eecs.umich.edutemplate <class Impl> 9895877Shsul@eecs.umich.eduvoid 9905877Shsul@eecs.umich.eduDefaultIEW<Impl>::dispatchInsts(unsigned tid) 9915877Shsul@eecs.umich.edu{ 9925877Shsul@eecs.umich.edu dispatchedAllInsts = true; 9935877Shsul@eecs.umich.edu 9945877Shsul@eecs.umich.edu // Obtain instructions from skid buffer if unblocking, or queue from rename 9952064SN/A // otherwise. 9962064SN/A std::queue<DynInstPtr> &insts_to_dispatch = 9972064SN/A dispatchStatus[tid] == Unblocking ? 9982064SN/A skidBuffer[tid] : insts[tid]; 9992064SN/A 1000360SN/A int insts_to_add = insts_to_dispatch.size(); 1001360SN/A 10022680Sktlim@umich.edu DynInstPtr inst; 10031458SN/A bool add_to_iq = false; 1004360SN/A int dis_num_inst = 0; 1005360SN/A 1006378SN/A // Loop through the instructions, putting them in the instruction 1007360SN/A // queue. 10081450SN/A for ( ; dis_num_inst < insts_to_add && 10093114Sgblack@eecs.umich.edu dis_num_inst < issueReadWidth; 10102680Sktlim@umich.edu ++dis_num_inst) 1011360SN/A { 10125958Sgblack@eecs.umich.edu inst = insts_to_dispatch.front(); 1013360SN/A 1014360SN/A if (dispatchStatus[tid] == Unblocking) { 1015360SN/A DPRINTF(IEW, "[tid:%i]: Issue: Examining instruction from skid " 10162091SN/A "buffer\n", tid); 10172091SN/A } 1018360SN/A 10192680Sktlim@umich.edu // Make sure there's a valid instruction there. 1020360SN/A assert(inst); 10211458SN/A 1022360SN/A DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %#x [sn:%lli] [tid:%i] to " 1023360SN/A "IQ.\n", 1024360SN/A tid, inst->readPC(), inst->seqNum, inst->threadNumber); 10251999SN/A 10261999SN/A // Be sure to mark these instructions as ready so that the 10271999SN/A // commit stage can go ahead and execute them, and mark 10283114Sgblack@eecs.umich.edu // them as issued so the IQ doesn't reprocess them. 10292680Sktlim@umich.edu 10301999SN/A // Check for squashed instructions. 10311999SN/A if (inst->isSquashed()) { 10321999SN/A DPRINTF(IEW, "[tid:%i]: Issue: Squashed instruction encountered, " 10335958Sgblack@eecs.umich.edu "not adding to IQ.\n", tid); 10342400SN/A 10351999SN/A ++iewDispSquashedInsts; 10365958Sgblack@eecs.umich.edu 10372680Sktlim@umich.edu insts_to_dispatch.pop(); 10381999SN/A 10391999SN/A //Tell Rename That An Instruction has been processed 10401999SN/A if (inst->isLoad() || inst->isStore()) { 10411999SN/A toRename->iewInfo[tid].dispatchedToLSQ++; 10422091SN/A } 10432091SN/A toRename->iewInfo[tid].dispatched++; 10441999SN/A 10453669Sbinkertn@umich.edu continue; 10463669Sbinkertn@umich.edu } 10473669Sbinkertn@umich.edu 10483669Sbinkertn@umich.edu // Check for full conditions. 10491999SN/A if (instQueue.isFull(tid)) { 10501999SN/A DPRINTF(IEW, "[tid:%i]: Issue: IQ has become full.\n", tid); 10511999SN/A 10521999SN/A // Call function to start blocking. 10531999SN/A block(tid); 10541999SN/A 10551999SN/A // Set unblock to false. Special case where we are using 1056378SN/A // skidbuffer (unblocking) instructions but then we still 1057360SN/A // get full in the IQ. 10581450SN/A toRename->iewUnblock[tid] = false; 10593114Sgblack@eecs.umich.edu 10602680Sktlim@umich.edu dispatchedAllInsts = false; 1061360SN/A 10625958Sgblack@eecs.umich.edu ++iewIQFullEvents; 10635958Sgblack@eecs.umich.edu break; 1064360SN/A } else if (ldstQueue.isFull(tid)) { 10653670Sbinkertn@umich.edu DPRINTF(IEW, "[tid:%i]: Issue: LSQ has become full.\n",tid); 10663670Sbinkertn@umich.edu 1067360SN/A // Call function to start blocking. 1068360SN/A block(tid); 1069360SN/A 1070360SN/A // Set unblock to false. Special case where we are using 1071360SN/A // skidbuffer (unblocking) instructions but then we still 1072360SN/A // get full in the IQ. 1073360SN/A toRename->iewUnblock[tid] = false; 1074360SN/A 1075360SN/A dispatchedAllInsts = false; 1076360SN/A 1077360SN/A ++iewLSQFullEvents; 1078360SN/A break; 1079360SN/A } 1080360SN/A 1081360SN/A // Otherwise issue the instruction just fine. 1082360SN/A if (inst->isLoad()) { 1083360SN/A DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction " 10843670Sbinkertn@umich.edu "encountered, adding to LSQ.\n", tid); 10853670Sbinkertn@umich.edu 10863670Sbinkertn@umich.edu // Reserve a spot in the load store queue for this 10873670Sbinkertn@umich.edu // memory access. 10883670Sbinkertn@umich.edu ldstQueue.insertLoad(inst); 10893670Sbinkertn@umich.edu 10903670Sbinkertn@umich.edu ++iewDispLoadInsts; 10913670Sbinkertn@umich.edu 10923670Sbinkertn@umich.edu add_to_iq = true; 10933670Sbinkertn@umich.edu 10943670Sbinkertn@umich.edu toRename->iewInfo[tid].dispatchedToLSQ++; 10953670Sbinkertn@umich.edu } else if (inst->isStore()) { 10963670Sbinkertn@umich.edu DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction " 10973670Sbinkertn@umich.edu "encountered, adding to LSQ.\n", tid); 10983670Sbinkertn@umich.edu 10993670Sbinkertn@umich.edu ldstQueue.insertStore(inst); 11003670Sbinkertn@umich.edu 11013670Sbinkertn@umich.edu ++iewDispStoreInsts; 11022680Sktlim@umich.edu 1103360SN/A if (inst->isNonSpeculative()) { 11041458SN/A // Non-speculative stores (namely store conditionals) 1105360SN/A // need to be set as "canCommit()" so that commit can 1106360SN/A // process them when they reach the head of commit. 11072553SN/A inst->setCanCommit(); 11082553SN/A instQueue.insertNonSpec(inst); 11092553SN/A add_to_iq = false; 11101354SN/A 1111 ++iewDispNonSpecInsts; 1112 } else { 1113 add_to_iq = true; 1114 } 1115 1116 toRename->iewInfo[tid].dispatchedToLSQ++; 1117#if FULL_SYSTEM 1118 } else if (inst->isMemBarrier() || inst->isWriteBarrier()) { 1119 // Same as non-speculative stores. 1120 inst->setCanCommit(); 1121 instQueue.insertBarrier(inst); 1122 add_to_iq = false; 1123#endif 1124 } else if (inst->isNonSpeculative()) { 1125 DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction " 1126 "encountered, skipping.\n", tid); 1127 1128 // Same as non-speculative stores. 1129 inst->setCanCommit(); 1130 1131 // Specifically insert it as nonspeculative. 1132 instQueue.insertNonSpec(inst); 1133 1134 ++iewDispNonSpecInsts; 1135 1136 add_to_iq = false; 1137 } else if (inst->isNop()) { 1138 DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, " 1139 "skipping.\n", tid); 1140 1141 inst->setIssued(); 1142 inst->setExecuted(); 1143 inst->setCanCommit(); 1144 1145 instQueue.recordProducer(inst); 1146 1147 exeNop[tid]++; 1148 1149 add_to_iq = false; 1150 } else if (inst->isExecuted()) { 1151 assert(0 && "Instruction shouldn't be executed.\n"); 1152 DPRINTF(IEW, "Issue: Executed branch encountered, " 1153 "skipping.\n"); 1154 1155 inst->setIssued(); 1156 inst->setCanCommit(); 1157 1158 instQueue.recordProducer(inst); 1159 1160 add_to_iq = false; 1161 } else { 1162 add_to_iq = true; 1163 } 1164 1165 // If the instruction queue is not full, then add the 1166 // instruction. 1167 if (add_to_iq) { 1168 instQueue.insert(inst); 1169 } 1170 1171 insts_to_dispatch.pop(); 1172 1173 toRename->iewInfo[tid].dispatched++; 1174 1175 ++iewDispatchedInsts; 1176 } 1177 1178 if (!insts_to_dispatch.empty()) { 1179 DPRINTF(IEW,"[tid:%i]: Issue: Bandwidth Full. Blocking.\n"); 1180 block(tid); 1181 toRename->iewUnblock[tid] = false; 1182 } 1183 1184 if (dispatchStatus[tid] == Idle && dis_num_inst) { 1185 dispatchStatus[tid] = Running; 1186 1187 updatedQueues = true; 1188 } 1189 1190 dis_num_inst = 0; 1191} 1192 1193template <class Impl> 1194void 1195DefaultIEW<Impl>::printAvailableInsts() 1196{ 1197 int inst = 0; 1198 1199 cout << "Available Instructions: "; 1200 1201 while (fromIssue->insts[inst]) { 1202 1203 if (inst%3==0) cout << "\n\t"; 1204 1205 cout << "PC: " << fromIssue->insts[inst]->readPC() 1206 << " TN: " << fromIssue->insts[inst]->threadNumber 1207 << " SN: " << fromIssue->insts[inst]->seqNum << " | "; 1208 1209 inst++; 1210 1211 } 1212 1213 cout << "\n"; 1214} 1215 1216template <class Impl> 1217void 1218DefaultIEW<Impl>::executeInsts() 1219{ 1220 wbNumInst = 0; 1221 wbCycle = 0; 1222 1223 list<unsigned>::iterator threads = (*activeThreads).begin(); 1224 1225 while (threads != (*activeThreads).end()) { 1226 unsigned tid = *threads++; 1227 fetchRedirect[tid] = false; 1228 } 1229 1230#if 0 1231 printAvailableInsts(); 1232#endif 1233 1234 // Execute/writeback any instructions that are available. 1235 int inst_num = 0; 1236 for ( ; inst_num < issueWidth && fromIssue->insts[inst_num]; 1237 ++inst_num) { 1238 1239 DPRINTF(IEW, "Execute: Executing instructions from IQ.\n"); 1240 1241 DynInstPtr inst = fromIssue->insts[inst_num]; 1242 1243 DPRINTF(IEW, "Execute: Processing PC %#x, [tid:%i] [sn:%i].\n", 1244 inst->readPC(), inst->threadNumber,inst->seqNum); 1245 1246 // Check if the instruction is squashed; if so then skip it 1247 if (inst->isSquashed()) { 1248 DPRINTF(IEW, "Execute: Instruction was squashed.\n"); 1249 1250 // Consider this instruction executed so that commit can go 1251 // ahead and retire the instruction. 1252 inst->setExecuted(); 1253 1254 // Not sure if I should set this here or just let commit try to 1255 // commit any squashed instructions. I like the latter a bit more. 1256 inst->setCanCommit(); 1257 1258 ++iewExecSquashedInsts; 1259 1260 continue; 1261 } 1262 1263 Fault fault = NoFault; 1264 1265 // Execute instruction. 1266 // Note that if the instruction faults, it will be handled 1267 // at the commit stage. 1268 if (inst->isMemRef() && 1269 (!inst->isDataPrefetch() && !inst->isInstPrefetch())) { 1270 DPRINTF(IEW, "Execute: Calculating address for memory " 1271 "reference.\n"); 1272 1273 // Tell the LDSTQ to execute this instruction (if it is a load). 1274 if (inst->isLoad()) { 1275 // Loads will mark themselves as executed, and their writeback 1276 // event adds the instruction to the queue to commit 1277 fault = ldstQueue.executeLoad(inst); 1278 } else if (inst->isStore()) { 1279 ldstQueue.executeStore(inst); 1280 1281 // If the store had a fault then it may not have a mem req 1282 if (inst->req && !(inst->req->flags & LOCKED)) { 1283 inst->setExecuted(); 1284 1285 instToCommit(inst); 1286 } 1287 1288 // Store conditionals will mark themselves as 1289 // executed, and their writeback event will add the 1290 // instruction to the queue to commit. 1291 } else { 1292 panic("Unexpected memory type!\n"); 1293 } 1294 1295 } else { 1296 inst->execute(); 1297 1298 inst->setExecuted(); 1299 1300 instToCommit(inst); 1301 } 1302 1303 updateExeInstStats(inst); 1304 1305 // Check if branch prediction was correct, if not then we need 1306 // to tell commit to squash in flight instructions. Only 1307 // handle this if there hasn't already been something that 1308 // redirects fetch in this group of instructions. 1309 1310 // This probably needs to prioritize the redirects if a different 1311 // scheduler is used. Currently the scheduler schedules the oldest 1312 // instruction first, so the branch resolution order will be correct. 1313 unsigned tid = inst->threadNumber; 1314 1315 if (!fetchRedirect[tid]) { 1316 1317 if (inst->mispredicted()) { 1318 fetchRedirect[tid] = true; 1319 1320 DPRINTF(IEW, "Execute: Branch mispredict detected.\n"); 1321 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n", 1322 inst->nextPC); 1323 1324 // If incorrect, then signal the ROB that it must be squashed. 1325 squashDueToBranch(inst, tid); 1326 1327 if (inst->predTaken()) { 1328 predictedTakenIncorrect++; 1329 } else { 1330 predictedNotTakenIncorrect++; 1331 } 1332 } else if (ldstQueue.violation(tid)) { 1333 fetchRedirect[tid] = true; 1334 1335 // If there was an ordering violation, then get the 1336 // DynInst that caused the violation. Note that this 1337 // clears the violation signal. 1338 DynInstPtr violator; 1339 violator = ldstQueue.getMemDepViolator(tid); 1340 1341 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: " 1342 "%#x, inst PC: %#x. Addr is: %#x.\n", 1343 violator->readPC(), inst->readPC(), inst->physEffAddr); 1344 1345 // Tell the instruction queue that a violation has occured. 1346 instQueue.violation(inst, violator); 1347 1348 // Squash. 1349 squashDueToMemOrder(inst,tid); 1350 1351 ++memOrderViolationEvents; 1352 } else if (ldstQueue.loadBlocked(tid) && 1353 !ldstQueue.isLoadBlockedHandled(tid)) { 1354 fetchRedirect[tid] = true; 1355 1356 DPRINTF(IEW, "Load operation couldn't execute because the " 1357 "memory system is blocked. PC: %#x [sn:%lli]\n", 1358 inst->readPC(), inst->seqNum); 1359 1360 squashDueToMemBlocked(inst, tid); 1361 } 1362 } 1363 } 1364 1365 if (inst_num) { 1366 if (exeStatus == Idle) { 1367 exeStatus = Running; 1368 } 1369 1370 updatedQueues = true; 1371 1372 cpu->activityThisCycle(); 1373 } 1374 1375 // Need to reset this in case a writeback event needs to write into the 1376 // iew queue. That way the writeback event will write into the correct 1377 // spot in the queue. 1378 wbNumInst = 0; 1379} 1380 1381template <class Impl> 1382void 1383DefaultIEW<Impl>::writebackInsts() 1384{ 1385 // Loop through the head of the time buffer and wake any 1386 // dependents. These instructions are about to write back. Also 1387 // mark scoreboard that this instruction is finally complete. 1388 // Either have IEW have direct access to scoreboard, or have this 1389 // as part of backwards communication. 1390 for (int inst_num = 0; inst_num < issueWidth && 1391 toCommit->insts[inst_num]; inst_num++) { 1392 DynInstPtr inst = toCommit->insts[inst_num]; 1393 int tid = inst->threadNumber; 1394 1395 DPRINTF(IEW, "Sending instructions to commit, PC %#x.\n", 1396 inst->readPC()); 1397 1398 iewInstsToCommit[tid]++; 1399 1400 // Some instructions will be sent to commit without having 1401 // executed because they need commit to handle them. 1402 // E.g. Uncached loads have not actually executed when they 1403 // are first sent to commit. Instead commit must tell the LSQ 1404 // when it's ready to execute the uncached load. 1405 if (!inst->isSquashed() && inst->isExecuted()) { 1406 int dependents = instQueue.wakeDependents(inst); 1407 1408 for (int i = 0; i < inst->numDestRegs(); i++) { 1409 //mark as Ready 1410 DPRINTF(IEW,"Setting Destination Register %i\n", 1411 inst->renamedDestRegIdx(i)); 1412 scoreboard->setReg(inst->renamedDestRegIdx(i)); 1413 } 1414 1415 producerInst[tid]++; 1416 consumerInst[tid]+= dependents; 1417 writebackCount[tid]++; 1418 } 1419 } 1420} 1421 1422template<class Impl> 1423void 1424DefaultIEW<Impl>::tick() 1425{ 1426 wbNumInst = 0; 1427 wbCycle = 0; 1428 1429 wroteToTimeBuffer = false; 1430 updatedQueues = false; 1431 1432 sortInsts(); 1433 1434 // Free function units marked as being freed this cycle. 1435 fuPool->processFreeUnits(); 1436 1437 list<unsigned>::iterator threads = (*activeThreads).begin(); 1438 1439 // Check stall and squash signals, dispatch any instructions. 1440 while (threads != (*activeThreads).end()) { 1441 unsigned tid = *threads++; 1442 1443 DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid); 1444 1445 checkSignalsAndUpdate(tid); 1446 dispatch(tid); 1447 } 1448 1449 if (exeStatus != Squashing) { 1450 executeInsts(); 1451 1452 writebackInsts(); 1453 1454 // Have the instruction queue try to schedule any ready instructions. 1455 // (In actuality, this scheduling is for instructions that will 1456 // be executed next cycle.) 1457 instQueue.scheduleReadyInsts(); 1458 1459 // Also should advance its own time buffers if the stage ran. 1460 // Not the best place for it, but this works (hopefully). 1461 issueToExecQueue.advance(); 1462 } 1463 1464 bool broadcast_free_entries = false; 1465 1466 if (updatedQueues || exeStatus == Running || updateLSQNextCycle) { 1467 exeStatus = Idle; 1468 updateLSQNextCycle = false; 1469 1470 broadcast_free_entries = true; 1471 } 1472 1473 // Writeback any stores using any leftover bandwidth. 1474 ldstQueue.writebackStores(); 1475 1476 // Check the committed load/store signals to see if there's a load 1477 // or store to commit. Also check if it's being told to execute a 1478 // nonspeculative instruction. 1479 // This is pretty inefficient... 1480 1481 threads = (*activeThreads).begin(); 1482 while (threads != (*activeThreads).end()) { 1483 unsigned tid = (*threads++); 1484 1485 DPRINTF(IEW,"Processing [tid:%i]\n",tid); 1486 1487 if (fromCommit->commitInfo[tid].doneSeqNum != 0 && 1488 !fromCommit->commitInfo[tid].squash && 1489 !fromCommit->commitInfo[tid].robSquashing) { 1490 1491 ldstQueue.commitStores(fromCommit->commitInfo[tid].doneSeqNum,tid); 1492 1493 ldstQueue.commitLoads(fromCommit->commitInfo[tid].doneSeqNum,tid); 1494 1495 updateLSQNextCycle = true; 1496 instQueue.commit(fromCommit->commitInfo[tid].doneSeqNum,tid); 1497 } 1498 1499 if (fromCommit->commitInfo[tid].nonSpecSeqNum != 0) { 1500 1501 //DPRINTF(IEW,"NonspecInst from thread %i",tid); 1502 if (fromCommit->commitInfo[tid].uncached) { 1503 instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad); 1504 } else { 1505 instQueue.scheduleNonSpec( 1506 fromCommit->commitInfo[tid].nonSpecSeqNum); 1507 } 1508 } 1509 1510 if (broadcast_free_entries) { 1511 toFetch->iewInfo[tid].iqCount = 1512 instQueue.getCount(tid); 1513 toFetch->iewInfo[tid].ldstqCount = 1514 ldstQueue.getCount(tid); 1515 1516 toRename->iewInfo[tid].usedIQ = true; 1517 toRename->iewInfo[tid].freeIQEntries = 1518 instQueue.numFreeEntries(); 1519 toRename->iewInfo[tid].usedLSQ = true; 1520 toRename->iewInfo[tid].freeLSQEntries = 1521 ldstQueue.numFreeEntries(tid); 1522 1523 wroteToTimeBuffer = true; 1524 } 1525 1526 DPRINTF(IEW, "[tid:%i], Dispatch dispatched %i instructions.\n", 1527 tid, toRename->iewInfo[tid].dispatched); 1528 } 1529 1530 DPRINTF(IEW, "IQ has %i free entries (Can schedule: %i). " 1531 "LSQ has %i free entries.\n", 1532 instQueue.numFreeEntries(), instQueue.hasReadyInsts(), 1533 ldstQueue.numFreeEntries()); 1534 1535 updateStatus(); 1536 1537 if (wroteToTimeBuffer) { 1538 DPRINTF(Activity, "Activity this cycle.\n"); 1539 cpu->activityThisCycle(); 1540 } 1541} 1542 1543template <class Impl> 1544void 1545DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst) 1546{ 1547 int thread_number = inst->threadNumber; 1548 1549 // 1550 // Pick off the software prefetches 1551 // 1552#ifdef TARGET_ALPHA 1553 if (inst->isDataPrefetch()) 1554 exeSwp[thread_number]++; 1555 else 1556 iewExecutedInsts++; 1557#else 1558 iewExecutedInsts[thread_number]++; 1559#endif 1560 1561 // 1562 // Control operations 1563 // 1564 if (inst->isControl()) 1565 exeBranches[thread_number]++; 1566 1567 // 1568 // Memory operations 1569 // 1570 if (inst->isMemRef()) { 1571 exeRefs[thread_number]++; 1572 1573 if (inst->isLoad()) { 1574 iewExecLoadInsts[thread_number]++; 1575 } 1576 } 1577} 1578