base.cc revision 10061
114039Sstacze01@arm.com/* 214039Sstacze01@arm.com * Copyright (c) 2010-2012 ARM Limited 314039Sstacze01@arm.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 414039Sstacze01@arm.com * All rights reserved 514039Sstacze01@arm.com * 614039Sstacze01@arm.com * The license below extends only to copyright in the software and shall 714039Sstacze01@arm.com * not be construed as granting a license to any other intellectual 814039Sstacze01@arm.com * property including but not limited to intellectual property relating 914039Sstacze01@arm.com * to a hardware implementation of the functionality of the software 1014039Sstacze01@arm.com * licensed hereunder. You may use the software subject to the license 1114039Sstacze01@arm.com * terms below provided that you ensure that this notice is replicated 1214039Sstacze01@arm.com * unmodified and in its entirety in all distributions of the software, 1314039Sstacze01@arm.com * modified or unmodified, in source code or in binary form. 1414039Sstacze01@arm.com * 1514039Sstacze01@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 1614039Sstacze01@arm.com * All rights reserved. 1714039Sstacze01@arm.com * 1814039Sstacze01@arm.com * Redistribution and use in source and binary forms, with or without 1914039Sstacze01@arm.com * modification, are permitted provided that the following conditions are 2014039Sstacze01@arm.com * met: redistributions of source code must retain the above copyright 2114039Sstacze01@arm.com * notice, this list of conditions and the following disclaimer; 2214039Sstacze01@arm.com * redistributions in binary form must reproduce the above copyright 2314039Sstacze01@arm.com * notice, this list of conditions and the following disclaimer in the 2414039Sstacze01@arm.com * documentation and/or other materials provided with the distribution; 2514039Sstacze01@arm.com * neither the name of the copyright holders nor the names of its 2614039Sstacze01@arm.com * contributors may be used to endorse or promote products derived from 2714039Sstacze01@arm.com * this software without specific prior written permission. 2814039Sstacze01@arm.com * 2914039Sstacze01@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3014039Sstacze01@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3114039Sstacze01@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3214039Sstacze01@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3314039Sstacze01@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3414039Sstacze01@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3514039Sstacze01@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3614039Sstacze01@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3714039Sstacze01@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3814039Sstacze01@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3914039Sstacze01@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4014039Sstacze01@arm.com * 4114039Sstacze01@arm.com * Authors: Steve Reinhardt 4214039Sstacze01@arm.com */ 4314039Sstacze01@arm.com 4414039Sstacze01@arm.com#include "arch/kernel_stats.hh" 4514039Sstacze01@arm.com#include "arch/stacktrace.hh" 4614039Sstacze01@arm.com#include "arch/tlb.hh" 4714039Sstacze01@arm.com#include "arch/utility.hh" 4814039Sstacze01@arm.com#include "arch/vtophys.hh" 4914039Sstacze01@arm.com#include "base/loader/symtab.hh" 5014039Sstacze01@arm.com#include "base/cp_annotate.hh" 5114039Sstacze01@arm.com#include "base/cprintf.hh" 5214039Sstacze01@arm.com#include "base/inifile.hh" 5314039Sstacze01@arm.com#include "base/misc.hh" 5414039Sstacze01@arm.com#include "base/pollevent.hh" 5514039Sstacze01@arm.com#include "base/trace.hh" 5614039Sstacze01@arm.com#include "base/types.hh" 5714039Sstacze01@arm.com#include "config/the_isa.hh" 5814039Sstacze01@arm.com#include "cpu/simple/base.hh" 5914039Sstacze01@arm.com#include "cpu/base.hh" 6014039Sstacze01@arm.com#include "cpu/checker/cpu.hh" 6114039Sstacze01@arm.com#include "cpu/checker/thread_context.hh" 6214039Sstacze01@arm.com#include "cpu/exetrace.hh" 6314039Sstacze01@arm.com#include "cpu/pred/bpred_unit.hh" 6414039Sstacze01@arm.com#include "cpu/profile.hh" 6514039Sstacze01@arm.com#include "cpu/simple_thread.hh" 6614039Sstacze01@arm.com#include "cpu/smt.hh" 6714039Sstacze01@arm.com#include "cpu/static_inst.hh" 6814039Sstacze01@arm.com#include "cpu/thread_context.hh" 6914039Sstacze01@arm.com#include "debug/Decode.hh" 7014039Sstacze01@arm.com#include "debug/Fetch.hh" 7114039Sstacze01@arm.com#include "debug/Quiesce.hh" 7214039Sstacze01@arm.com#include "mem/mem_object.hh" 7314039Sstacze01@arm.com#include "mem/packet.hh" 7414039Sstacze01@arm.com#include "mem/request.hh" 7514039Sstacze01@arm.com#include "params/BaseSimpleCPU.hh" 7614039Sstacze01@arm.com#include "sim/byteswap.hh" 7714039Sstacze01@arm.com#include "sim/debug.hh" 7814039Sstacze01@arm.com#include "sim/faults.hh" 7914039Sstacze01@arm.com#include "sim/full_system.hh" 8014039Sstacze01@arm.com#include "sim/sim_events.hh" 8114063Sadrian.herrera@arm.com#include "sim/sim_object.hh" 8214063Sadrian.herrera@arm.com#include "sim/stats.hh" 8314063Sadrian.herrera@arm.com#include "sim/system.hh" 8414063Sadrian.herrera@arm.com 8514063Sadrian.herrera@arm.comusing namespace std; 8614063Sadrian.herrera@arm.comusing namespace TheISA; 8714063Sadrian.herrera@arm.com 8814063Sadrian.herrera@arm.comBaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p) 8914063Sadrian.herrera@arm.com : BaseCPU(p), 9014063Sadrian.herrera@arm.com branchPred(p->branchPred), 9114063Sadrian.herrera@arm.com traceData(NULL), thread(NULL) 9214063Sadrian.herrera@arm.com{ 9314063Sadrian.herrera@arm.com if (FullSystem) 9414063Sadrian.herrera@arm.com thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb, 9514063Sadrian.herrera@arm.com p->isa[0]); 9614063Sadrian.herrera@arm.com else 9714064Sadrian.herrera@arm.com thread = new SimpleThread(this, /* thread_num */ 0, p->system, 9814064Sadrian.herrera@arm.com p->workload[0], p->itb, p->dtb, p->isa[0]); 9914064Sadrian.herrera@arm.com 10014064Sadrian.herrera@arm.com thread->setStatus(ThreadContext::Halted); 10114064Sadrian.herrera@arm.com 10214063Sadrian.herrera@arm.com tc = thread->getTC(); 10314063Sadrian.herrera@arm.com 10414039Sstacze01@arm.com if (p->checker) { 10514039Sstacze01@arm.com BaseCPU *temp_checker = p->checker; 10614039Sstacze01@arm.com checker = dynamic_cast<CheckerCPU *>(temp_checker); 10714039Sstacze01@arm.com checker->setSystem(p->system); 10814039Sstacze01@arm.com // Manipulate thread context 10914039Sstacze01@arm.com ThreadContext *cpu_tc = tc; 11014039Sstacze01@arm.com tc = new CheckerThreadContext<ThreadContext>(cpu_tc, this->checker); 11114039Sstacze01@arm.com } else { 11214039Sstacze01@arm.com checker = NULL; 11314039Sstacze01@arm.com } 11414039Sstacze01@arm.com 11514039Sstacze01@arm.com numInst = 0; 11614039Sstacze01@arm.com startNumInst = 0; 11714039Sstacze01@arm.com numOp = 0; 11814039Sstacze01@arm.com startNumOp = 0; 11914039Sstacze01@arm.com numLoad = 0; 12014039Sstacze01@arm.com startNumLoad = 0; 12114039Sstacze01@arm.com lastIcacheStall = 0; 12214039Sstacze01@arm.com lastDcacheStall = 0; 12314039Sstacze01@arm.com 12414039Sstacze01@arm.com threadContexts.push_back(tc); 12514039Sstacze01@arm.com 12614039Sstacze01@arm.com 12714039Sstacze01@arm.com fetchOffset = 0; 12814039Sstacze01@arm.com stayAtPC = false; 12914039Sstacze01@arm.com} 13014039Sstacze01@arm.com 13114039Sstacze01@arm.comBaseSimpleCPU::~BaseSimpleCPU() 13214039Sstacze01@arm.com{ 13314039Sstacze01@arm.com} 13414039Sstacze01@arm.com 13514039Sstacze01@arm.comvoid 13614039Sstacze01@arm.comBaseSimpleCPU::deallocateContext(ThreadID thread_num) 13714039Sstacze01@arm.com{ 13814039Sstacze01@arm.com // for now, these are equivalent 13914039Sstacze01@arm.com suspendContext(thread_num); 14014039Sstacze01@arm.com} 14114039Sstacze01@arm.com 14214039Sstacze01@arm.com 14314039Sstacze01@arm.comvoid 14414039Sstacze01@arm.comBaseSimpleCPU::haltContext(ThreadID thread_num) 14514039Sstacze01@arm.com{ 14614039Sstacze01@arm.com // for now, these are equivalent 14714039Sstacze01@arm.com suspendContext(thread_num); 14814039Sstacze01@arm.com} 14914039Sstacze01@arm.com 15014039Sstacze01@arm.com 15114039Sstacze01@arm.comvoid 15214039Sstacze01@arm.comBaseSimpleCPU::regStats() 15314039Sstacze01@arm.com{ 15414039Sstacze01@arm.com using namespace Stats; 15514039Sstacze01@arm.com 15614039Sstacze01@arm.com BaseCPU::regStats(); 15714039Sstacze01@arm.com 15814039Sstacze01@arm.com numInsts 15914039Sstacze01@arm.com .name(name() + ".committedInsts") 16014039Sstacze01@arm.com .desc("Number of instructions committed") 16114039Sstacze01@arm.com ; 16214039Sstacze01@arm.com 16314039Sstacze01@arm.com numOps 16414039Sstacze01@arm.com .name(name() + ".committedOps") 16514039Sstacze01@arm.com .desc("Number of ops (including micro ops) committed") 16614039Sstacze01@arm.com ; 16714039Sstacze01@arm.com 16814039Sstacze01@arm.com numIntAluAccesses 16914039Sstacze01@arm.com .name(name() + ".num_int_alu_accesses") 17014039Sstacze01@arm.com .desc("Number of integer alu accesses") 17114039Sstacze01@arm.com ; 17214039Sstacze01@arm.com 17314039Sstacze01@arm.com numFpAluAccesses 17414039Sstacze01@arm.com .name(name() + ".num_fp_alu_accesses") 17514039Sstacze01@arm.com .desc("Number of float alu accesses") 17614039Sstacze01@arm.com ; 17714039Sstacze01@arm.com 17814039Sstacze01@arm.com numCallsReturns 17914039Sstacze01@arm.com .name(name() + ".num_func_calls") 18014039Sstacze01@arm.com .desc("number of times a function call or return occured") 18114039Sstacze01@arm.com ; 18214039Sstacze01@arm.com 18314039Sstacze01@arm.com numCondCtrlInsts 18414039Sstacze01@arm.com .name(name() + ".num_conditional_control_insts") 18514039Sstacze01@arm.com .desc("number of instructions that are conditional controls") 18614039Sstacze01@arm.com ; 18714039Sstacze01@arm.com 18814039Sstacze01@arm.com numIntInsts 18914039Sstacze01@arm.com .name(name() + ".num_int_insts") 19014039Sstacze01@arm.com .desc("number of integer instructions") 19114039Sstacze01@arm.com ; 19214039Sstacze01@arm.com 19314039Sstacze01@arm.com numFpInsts 19414039Sstacze01@arm.com .name(name() + ".num_fp_insts") 19514039Sstacze01@arm.com .desc("number of float instructions") 19614039Sstacze01@arm.com ; 19714039Sstacze01@arm.com 19814039Sstacze01@arm.com numIntRegReads 19914039Sstacze01@arm.com .name(name() + ".num_int_register_reads") 20014039Sstacze01@arm.com .desc("number of times the integer registers were read") 20114039Sstacze01@arm.com ; 20214039Sstacze01@arm.com 20314039Sstacze01@arm.com numIntRegWrites 20414039Sstacze01@arm.com .name(name() + ".num_int_register_writes") 20514039Sstacze01@arm.com .desc("number of times the integer registers were written") 20614039Sstacze01@arm.com ; 20714039Sstacze01@arm.com 20814039Sstacze01@arm.com numFpRegReads 20914039Sstacze01@arm.com .name(name() + ".num_fp_register_reads") 21014039Sstacze01@arm.com .desc("number of times the floating registers were read") 21114039Sstacze01@arm.com ; 21214039Sstacze01@arm.com 21314039Sstacze01@arm.com numFpRegWrites 21414039Sstacze01@arm.com .name(name() + ".num_fp_register_writes") 21514039Sstacze01@arm.com .desc("number of times the floating registers were written") 21614039Sstacze01@arm.com ; 21714039Sstacze01@arm.com 21814039Sstacze01@arm.com numCCRegReads 21914039Sstacze01@arm.com .name(name() + ".num_cc_register_reads") 22014039Sstacze01@arm.com .desc("number of times the CC registers were read") 22114039Sstacze01@arm.com .flags(nozero) 22214039Sstacze01@arm.com ; 22314039Sstacze01@arm.com 22414039Sstacze01@arm.com numCCRegWrites 22514039Sstacze01@arm.com .name(name() + ".num_cc_register_writes") 22614039Sstacze01@arm.com .desc("number of times the CC registers were written") 22714039Sstacze01@arm.com .flags(nozero) 22814039Sstacze01@arm.com ; 22914039Sstacze01@arm.com 23014039Sstacze01@arm.com numMemRefs 23114039Sstacze01@arm.com .name(name()+".num_mem_refs") 23214039Sstacze01@arm.com .desc("number of memory refs") 23314039Sstacze01@arm.com ; 23414039Sstacze01@arm.com 23514039Sstacze01@arm.com numStoreInsts 23614039Sstacze01@arm.com .name(name() + ".num_store_insts") 23714039Sstacze01@arm.com .desc("Number of store instructions") 23814039Sstacze01@arm.com ; 23914039Sstacze01@arm.com 24014039Sstacze01@arm.com numLoadInsts 24114039Sstacze01@arm.com .name(name() + ".num_load_insts") 24214039Sstacze01@arm.com .desc("Number of load instructions") 24314039Sstacze01@arm.com ; 24414039Sstacze01@arm.com 24514039Sstacze01@arm.com notIdleFraction 24614039Sstacze01@arm.com .name(name() + ".not_idle_fraction") 24714039Sstacze01@arm.com .desc("Percentage of non-idle cycles") 24814039Sstacze01@arm.com ; 24914039Sstacze01@arm.com 25014039Sstacze01@arm.com idleFraction 25114039Sstacze01@arm.com .name(name() + ".idle_fraction") 25214039Sstacze01@arm.com .desc("Percentage of idle cycles") 25314039Sstacze01@arm.com ; 25414039Sstacze01@arm.com 25514039Sstacze01@arm.com numBusyCycles 25614039Sstacze01@arm.com .name(name() + ".num_busy_cycles") 25714039Sstacze01@arm.com .desc("Number of busy cycles") 25814039Sstacze01@arm.com ; 25914039Sstacze01@arm.com 26014039Sstacze01@arm.com numIdleCycles 26114039Sstacze01@arm.com .name(name()+".num_idle_cycles") 26214039Sstacze01@arm.com .desc("Number of idle cycles") 26314039Sstacze01@arm.com ; 26414039Sstacze01@arm.com 26514039Sstacze01@arm.com icacheStallCycles 26614039Sstacze01@arm.com .name(name() + ".icache_stall_cycles") 26714039Sstacze01@arm.com .desc("ICache total stall cycles") 26814039Sstacze01@arm.com .prereq(icacheStallCycles) 26914039Sstacze01@arm.com ; 27014039Sstacze01@arm.com 27114039Sstacze01@arm.com dcacheStallCycles 27214039Sstacze01@arm.com .name(name() + ".dcache_stall_cycles") 27314039Sstacze01@arm.com .desc("DCache total stall cycles") 27414039Sstacze01@arm.com .prereq(dcacheStallCycles) 27514039Sstacze01@arm.com ; 27614039Sstacze01@arm.com 27714039Sstacze01@arm.com icacheRetryCycles 27814039Sstacze01@arm.com .name(name() + ".icache_retry_cycles") 27914039Sstacze01@arm.com .desc("ICache total retry cycles") 28014039Sstacze01@arm.com .prereq(icacheRetryCycles) 28114039Sstacze01@arm.com ; 28214039Sstacze01@arm.com 28314039Sstacze01@arm.com dcacheRetryCycles 28414039Sstacze01@arm.com .name(name() + ".dcache_retry_cycles") 28514039Sstacze01@arm.com .desc("DCache total retry cycles") 28614039Sstacze01@arm.com .prereq(dcacheRetryCycles) 28714039Sstacze01@arm.com ; 28814039Sstacze01@arm.com 28914039Sstacze01@arm.com idleFraction = constant(1.0) - notIdleFraction; 29014039Sstacze01@arm.com numIdleCycles = idleFraction * numCycles; 29114039Sstacze01@arm.com numBusyCycles = (notIdleFraction)*numCycles; 29214039Sstacze01@arm.com 29314039Sstacze01@arm.com numBranches 29414039Sstacze01@arm.com .name(name() + ".Branches") 29514039Sstacze01@arm.com .desc("Number of branches fetched") 29614039Sstacze01@arm.com .prereq(numBranches); 29714039Sstacze01@arm.com 29814039Sstacze01@arm.com numPredictedBranches 29914039Sstacze01@arm.com .name(name() + ".predictedBranches") 30014039Sstacze01@arm.com .desc("Number of branches predicted as taken") 30114039Sstacze01@arm.com .prereq(numPredictedBranches); 30214039Sstacze01@arm.com 30314039Sstacze01@arm.com numBranchMispred 30414039Sstacze01@arm.com .name(name() + ".BranchMispred") 30514039Sstacze01@arm.com .desc("Number of branch mispredictions") 30614039Sstacze01@arm.com .prereq(numBranchMispred); 30714039Sstacze01@arm.com} 30814039Sstacze01@arm.com 30914039Sstacze01@arm.comvoid 31014039Sstacze01@arm.comBaseSimpleCPU::resetStats() 31114039Sstacze01@arm.com{ 31214039Sstacze01@arm.com// startNumInst = numInst; 31314039Sstacze01@arm.com notIdleFraction = (_status != Idle); 31414039Sstacze01@arm.com} 31514039Sstacze01@arm.com 31614039Sstacze01@arm.comvoid 31714039Sstacze01@arm.comBaseSimpleCPU::serializeThread(ostream &os, ThreadID tid) 31814039Sstacze01@arm.com{ 31914039Sstacze01@arm.com assert(_status == Idle || _status == Running); 32014039Sstacze01@arm.com assert(tid == 0); 32114039Sstacze01@arm.com 32214039Sstacze01@arm.com thread->serialize(os); 32314039Sstacze01@arm.com} 32414039Sstacze01@arm.com 32514039Sstacze01@arm.comvoid 32614039Sstacze01@arm.comBaseSimpleCPU::unserializeThread(Checkpoint *cp, const string §ion, 32714039Sstacze01@arm.com ThreadID tid) 32814039Sstacze01@arm.com{ 32914039Sstacze01@arm.com if (tid != 0) 33014039Sstacze01@arm.com fatal("Trying to load more than one thread into a SimpleCPU\n"); 33114039Sstacze01@arm.com thread->unserialize(cp, section); 33214039Sstacze01@arm.com} 33314039Sstacze01@arm.com 33414039Sstacze01@arm.comvoid 33514039Sstacze01@arm.comchange_thread_state(ThreadID tid, int activate, int priority) 33614039Sstacze01@arm.com{ 33714039Sstacze01@arm.com} 33814039Sstacze01@arm.com 33914039Sstacze01@arm.comAddr 34014039Sstacze01@arm.comBaseSimpleCPU::dbg_vtophys(Addr addr) 34114039Sstacze01@arm.com{ 34214039Sstacze01@arm.com return vtophys(tc, addr); 34314039Sstacze01@arm.com} 34414039Sstacze01@arm.com 34514039Sstacze01@arm.comvoid 34614039Sstacze01@arm.comBaseSimpleCPU::wakeup() 34714039Sstacze01@arm.com{ 34814039Sstacze01@arm.com if (thread->status() != ThreadContext::Suspended) 34914039Sstacze01@arm.com return; 35014039Sstacze01@arm.com 35114039Sstacze01@arm.com DPRINTF(Quiesce,"Suspended Processor awoke\n"); 35214039Sstacze01@arm.com thread->activate(); 35314039Sstacze01@arm.com} 35414039Sstacze01@arm.com 35514039Sstacze01@arm.comvoid 35614039Sstacze01@arm.comBaseSimpleCPU::checkForInterrupts() 35714039Sstacze01@arm.com{ 35814039Sstacze01@arm.com if (checkInterrupts(tc)) { 35914039Sstacze01@arm.com Fault interrupt = interrupts->getInterrupt(tc); 36014039Sstacze01@arm.com 36114039Sstacze01@arm.com if (interrupt != NoFault) { 36214039Sstacze01@arm.com fetchOffset = 0; 36314039Sstacze01@arm.com interrupts->updateIntrInfo(tc); 36414039Sstacze01@arm.com interrupt->invoke(tc); 36514039Sstacze01@arm.com thread->decoder.reset(); 36614039Sstacze01@arm.com } 36714039Sstacze01@arm.com } 36814039Sstacze01@arm.com} 36914039Sstacze01@arm.com 37014039Sstacze01@arm.com 37114039Sstacze01@arm.comvoid 37214039Sstacze01@arm.comBaseSimpleCPU::setupFetchRequest(Request *req) 37314039Sstacze01@arm.com{ 37414039Sstacze01@arm.com Addr instAddr = thread->instAddr(); 37514039Sstacze01@arm.com 37614039Sstacze01@arm.com // set up memory request for instruction fetch 37714039Sstacze01@arm.com DPRINTF(Fetch, "Fetch: PC:%08p\n", instAddr); 37814039Sstacze01@arm.com 37914039Sstacze01@arm.com Addr fetchPC = (instAddr & PCMask) + fetchOffset; 38014039Sstacze01@arm.com req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH, instMasterId(), 38114039Sstacze01@arm.com instAddr); 38214039Sstacze01@arm.com} 38314039Sstacze01@arm.com 38414039Sstacze01@arm.com 38514039Sstacze01@arm.comvoid 38614039Sstacze01@arm.comBaseSimpleCPU::preExecute() 38714039Sstacze01@arm.com{ 38814039Sstacze01@arm.com // maintain $r0 semantics 38914039Sstacze01@arm.com thread->setIntReg(ZeroReg, 0); 39014039Sstacze01@arm.com#if THE_ISA == ALPHA_ISA 39114039Sstacze01@arm.com thread->setFloatReg(ZeroReg, 0.0); 39214039Sstacze01@arm.com#endif // ALPHA_ISA 39314039Sstacze01@arm.com 39414039Sstacze01@arm.com // check for instruction-count-based events 39514039Sstacze01@arm.com comInstEventQueue[0]->serviceEvents(numInst); 39614039Sstacze01@arm.com system->instEventQueue.serviceEvents(system->totalNumInsts); 39714039Sstacze01@arm.com 39814039Sstacze01@arm.com // decode the instruction 39914039Sstacze01@arm.com inst = gtoh(inst); 40014039Sstacze01@arm.com 40114039Sstacze01@arm.com TheISA::PCState pcState = thread->pcState(); 40214039Sstacze01@arm.com 40314039Sstacze01@arm.com if (isRomMicroPC(pcState.microPC())) { 40414039Sstacze01@arm.com stayAtPC = false; 40514039Sstacze01@arm.com curStaticInst = microcodeRom.fetchMicroop(pcState.microPC(), 40614039Sstacze01@arm.com curMacroStaticInst); 40714039Sstacze01@arm.com } else if (!curMacroStaticInst) { 40814039Sstacze01@arm.com //We're not in the middle of a macro instruction 40914039Sstacze01@arm.com StaticInstPtr instPtr = NULL; 41014039Sstacze01@arm.com 41114039Sstacze01@arm.com TheISA::Decoder *decoder = &(thread->decoder); 41214039Sstacze01@arm.com 41314039Sstacze01@arm.com //Predecode, ie bundle up an ExtMachInst 41414039Sstacze01@arm.com //If more fetch data is needed, pass it in. 41514039Sstacze01@arm.com Addr fetchPC = (pcState.instAddr() & PCMask) + fetchOffset; 41614039Sstacze01@arm.com //if(decoder->needMoreBytes()) 41714039Sstacze01@arm.com decoder->moreBytes(pcState, fetchPC, inst); 41814039Sstacze01@arm.com //else 41914039Sstacze01@arm.com // decoder->process(); 42014039Sstacze01@arm.com 42114039Sstacze01@arm.com //Decode an instruction if one is ready. Otherwise, we'll have to 42214039Sstacze01@arm.com //fetch beyond the MachInst at the current pc. 42314039Sstacze01@arm.com instPtr = decoder->decode(pcState); 42414039Sstacze01@arm.com if (instPtr) { 42514039Sstacze01@arm.com stayAtPC = false; 42614039Sstacze01@arm.com thread->pcState(pcState); 42714039Sstacze01@arm.com } else { 42814039Sstacze01@arm.com stayAtPC = true; 42914039Sstacze01@arm.com fetchOffset += sizeof(MachInst); 43014039Sstacze01@arm.com } 43114039Sstacze01@arm.com 43214039Sstacze01@arm.com //If we decoded an instruction and it's microcoded, start pulling 43314039Sstacze01@arm.com //out micro ops 43414039Sstacze01@arm.com if (instPtr && instPtr->isMacroop()) { 43514039Sstacze01@arm.com curMacroStaticInst = instPtr; 43614039Sstacze01@arm.com curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC()); 43714039Sstacze01@arm.com } else { 43814039Sstacze01@arm.com curStaticInst = instPtr; 43914039Sstacze01@arm.com } 44014039Sstacze01@arm.com } else { 44114039Sstacze01@arm.com //Read the next micro op from the macro op 44214039Sstacze01@arm.com curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC()); 44314039Sstacze01@arm.com } 44414039Sstacze01@arm.com 44514039Sstacze01@arm.com //If we decoded an instruction this "tick", record information about it. 44614039Sstacze01@arm.com if (curStaticInst) { 44714039Sstacze01@arm.com#if TRACING_ON 44814039Sstacze01@arm.com traceData = tracer->getInstRecord(curTick(), tc, 44914039Sstacze01@arm.com curStaticInst, thread->pcState(), curMacroStaticInst); 45014039Sstacze01@arm.com 45114039Sstacze01@arm.com DPRINTF(Decode,"Decode: Decoded %s instruction: %#x\n", 45214039Sstacze01@arm.com curStaticInst->getName(), curStaticInst->machInst); 45314039Sstacze01@arm.com#endif // TRACING_ON 45414039Sstacze01@arm.com } 45514039Sstacze01@arm.com 45614039Sstacze01@arm.com if (branchPred && curStaticInst && curStaticInst->isControl()) { 45714039Sstacze01@arm.com // Use a fake sequence number since we only have one 45814039Sstacze01@arm.com // instruction in flight at the same time. 45914039Sstacze01@arm.com const InstSeqNum cur_sn(0); 46014039Sstacze01@arm.com const ThreadID tid(0); 46114039Sstacze01@arm.com pred_pc = thread->pcState(); 46214039Sstacze01@arm.com const bool predict_taken( 46314039Sstacze01@arm.com branchPred->predict(curStaticInst, cur_sn, pred_pc, tid)); 46414039Sstacze01@arm.com 46514039Sstacze01@arm.com if (predict_taken) 46614039Sstacze01@arm.com ++numPredictedBranches; 46714039Sstacze01@arm.com } 46814039Sstacze01@arm.com} 46914039Sstacze01@arm.com 47014039Sstacze01@arm.comvoid 47114039Sstacze01@arm.comBaseSimpleCPU::postExecute() 47214039Sstacze01@arm.com{ 47314039Sstacze01@arm.com assert(curStaticInst); 47414039Sstacze01@arm.com 47514039Sstacze01@arm.com TheISA::PCState pc = tc->pcState(); 47614039Sstacze01@arm.com Addr instAddr = pc.instAddr(); 47714039Sstacze01@arm.com if (FullSystem && thread->profile) { 47814039Sstacze01@arm.com bool usermode = TheISA::inUserMode(tc); 47914039Sstacze01@arm.com thread->profilePC = usermode ? 1 : instAddr; 48014039Sstacze01@arm.com ProfileNode *node = thread->profile->consume(tc, curStaticInst); 48114039Sstacze01@arm.com if (node) 48214039Sstacze01@arm.com thread->profileNode = node; 48314039Sstacze01@arm.com } 48414039Sstacze01@arm.com 48514039Sstacze01@arm.com if (curStaticInst->isMemRef()) { 48614039Sstacze01@arm.com numMemRefs++; 48714039Sstacze01@arm.com } 48814039Sstacze01@arm.com 48914039Sstacze01@arm.com if (curStaticInst->isLoad()) { 49014039Sstacze01@arm.com ++numLoad; 49114039Sstacze01@arm.com comLoadEventQueue[0]->serviceEvents(numLoad); 49214039Sstacze01@arm.com } 49314039Sstacze01@arm.com 49414039Sstacze01@arm.com if (CPA::available()) { 49514039Sstacze01@arm.com CPA::cpa()->swAutoBegin(tc, pc.nextInstAddr()); 49614039Sstacze01@arm.com } 49714039Sstacze01@arm.com 49814039Sstacze01@arm.com if (curStaticInst->isControl()) { 49914039Sstacze01@arm.com ++numBranches; 50014039Sstacze01@arm.com } 50114039Sstacze01@arm.com 50214039Sstacze01@arm.com /* Power model statistics */ 50314039Sstacze01@arm.com //integer alu accesses 50414039Sstacze01@arm.com if (curStaticInst->isInteger()){ 50514039Sstacze01@arm.com numIntAluAccesses++; 50614039Sstacze01@arm.com numIntInsts++; 50714039Sstacze01@arm.com } 50814039Sstacze01@arm.com 50914039Sstacze01@arm.com //float alu accesses 51014039Sstacze01@arm.com if (curStaticInst->isFloating()){ 51114039Sstacze01@arm.com numFpAluAccesses++; 51214039Sstacze01@arm.com numFpInsts++; 51314039Sstacze01@arm.com } 51414039Sstacze01@arm.com 51514039Sstacze01@arm.com //number of function calls/returns to get window accesses 51614039Sstacze01@arm.com if (curStaticInst->isCall() || curStaticInst->isReturn()){ 51714039Sstacze01@arm.com numCallsReturns++; 51814039Sstacze01@arm.com } 51914039Sstacze01@arm.com 52014039Sstacze01@arm.com //the number of branch predictions that will be made 52114039Sstacze01@arm.com if (curStaticInst->isCondCtrl()){ 52214039Sstacze01@arm.com numCondCtrlInsts++; 52314039Sstacze01@arm.com } 52414039Sstacze01@arm.com 52514039Sstacze01@arm.com //result bus acceses 52614039Sstacze01@arm.com if (curStaticInst->isLoad()){ 52714039Sstacze01@arm.com numLoadInsts++; 52814039Sstacze01@arm.com } 52914039Sstacze01@arm.com 53014039Sstacze01@arm.com if (curStaticInst->isStore()){ 53114039Sstacze01@arm.com numStoreInsts++; 53214039Sstacze01@arm.com } 53314039Sstacze01@arm.com /* End power model statistics */ 53414039Sstacze01@arm.com 53514101Sgiacomo.travaglini@arm.com if (FullSystem) 53614101Sgiacomo.travaglini@arm.com traceFunctions(instAddr); 53714101Sgiacomo.travaglini@arm.com 53814039Sstacze01@arm.com if (traceData) { 53914039Sstacze01@arm.com traceData->dump(); 54014039Sstacze01@arm.com delete traceData; 54114039Sstacze01@arm.com traceData = NULL; 54214039Sstacze01@arm.com } 54314039Sstacze01@arm.com} 54414039Sstacze01@arm.com 54514039Sstacze01@arm.comvoid 54614039Sstacze01@arm.comBaseSimpleCPU::advancePC(Fault fault) 54714039Sstacze01@arm.com{ 54814039Sstacze01@arm.com const bool branching(thread->pcState().branching()); 54914039Sstacze01@arm.com 55014039Sstacze01@arm.com //Since we're moving to a new pc, zero out the offset 55114039Sstacze01@arm.com fetchOffset = 0; 55214039Sstacze01@arm.com if (fault != NoFault) { 55314039Sstacze01@arm.com curMacroStaticInst = StaticInst::nullStaticInstPtr; 55414039Sstacze01@arm.com fault->invoke(tc, curStaticInst); 55514039Sstacze01@arm.com thread->decoder.reset(); 55614039Sstacze01@arm.com } else { 55714039Sstacze01@arm.com if (curStaticInst) { 55814039Sstacze01@arm.com if (curStaticInst->isLastMicroop()) 55914039Sstacze01@arm.com curMacroStaticInst = StaticInst::nullStaticInstPtr; 56014039Sstacze01@arm.com TheISA::PCState pcState = thread->pcState(); 56114101Sgiacomo.travaglini@arm.com TheISA::advancePC(pcState, curStaticInst); 56214101Sgiacomo.travaglini@arm.com thread->pcState(pcState); 56314039Sstacze01@arm.com } 56414039Sstacze01@arm.com } 56514039Sstacze01@arm.com 56614039Sstacze01@arm.com if (branchPred && curStaticInst && curStaticInst->isControl()) { 56714039Sstacze01@arm.com // Use a fake sequence number since we only have one 56814039Sstacze01@arm.com // instruction in flight at the same time. 56914039Sstacze01@arm.com const InstSeqNum cur_sn(0); 57014039Sstacze01@arm.com const ThreadID tid(0); 57114039Sstacze01@arm.com 57214039Sstacze01@arm.com if (pred_pc == thread->pcState()) { 57314039Sstacze01@arm.com // Correctly predicted branch 57414039Sstacze01@arm.com branchPred->update(cur_sn, tid); 57514039Sstacze01@arm.com } else { 57614039Sstacze01@arm.com // Mis-predicted branch 57714039Sstacze01@arm.com branchPred->squash(cur_sn, pcState(), 57814039Sstacze01@arm.com branching, tid); 57914039Sstacze01@arm.com ++numBranchMispred; 58014039Sstacze01@arm.com } 58114039Sstacze01@arm.com } 58214039Sstacze01@arm.com} 58314039Sstacze01@arm.com 58414039Sstacze01@arm.comvoid 58514039Sstacze01@arm.comBaseSimpleCPU::startup() 58614039Sstacze01@arm.com{ 58714039Sstacze01@arm.com BaseCPU::startup(); 58814039Sstacze01@arm.com thread->startup(); 58914039Sstacze01@arm.com} 59014039Sstacze01@arm.com