12SN/A/* 213954Sgiacomo.gabrielli@arm.com * Copyright (c) 2010-2012, 2015, 2017, 2018 ARM Limited 39920Syasuko.eckert@amd.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 47338SAli.Saidi@ARM.com * All rights reserved 57338SAli.Saidi@ARM.com * 67338SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall 77338SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual 87338SAli.Saidi@ARM.com * property including but not limited to intellectual property relating 97338SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software 107338SAli.Saidi@ARM.com * licensed hereunder. You may use the software subject to the license 117338SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated 127338SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software, 137338SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form. 147338SAli.Saidi@ARM.com * 151762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 162SN/A * All rights reserved. 172SN/A * 182SN/A * Redistribution and use in source and binary forms, with or without 192SN/A * modification, are permitted provided that the following conditions are 202SN/A * met: redistributions of source code must retain the above copyright 212SN/A * notice, this list of conditions and the following disclaimer; 222SN/A * redistributions in binary form must reproduce the above copyright 232SN/A * notice, this list of conditions and the following disclaimer in the 242SN/A * documentation and/or other materials provided with the distribution; 252SN/A * neither the name of the copyright holders nor the names of its 262SN/A * contributors may be used to endorse or promote products derived from 272SN/A * this software without specific prior written permission. 282SN/A * 292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 332SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 342SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 352SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 362SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 372SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 382SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402665Ssaidi@eecs.umich.edu * 412665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt 422SN/A */ 432SN/A 4411793Sbrandon.potter@amd.com#include "cpu/simple/base.hh" 4511793Sbrandon.potter@amd.com 468779Sgblack@eecs.umich.edu#include "arch/stacktrace.hh" 472439SN/A#include "arch/utility.hh" 488779Sgblack@eecs.umich.edu#include "arch/vtophys.hh" 496216Snate@binkert.org#include "base/cp_annotate.hh" 50146SN/A#include "base/cprintf.hh" 51146SN/A#include "base/inifile.hh" 5211793Sbrandon.potter@amd.com#include "base/loader/symtab.hh" 5312334Sgabeblack@google.com#include "base/logging.hh" 54146SN/A#include "base/pollevent.hh" 55146SN/A#include "base/trace.hh" 566216Snate@binkert.org#include "base/types.hh" 576658Snate@binkert.org#include "config/the_isa.hh" 581717SN/A#include "cpu/base.hh" 598887Sgeoffrey.blake@arm.com#include "cpu/checker/cpu.hh" 608887Sgeoffrey.blake@arm.com#include "cpu/checker/thread_context.hh" 61146SN/A#include "cpu/exetrace.hh" 6210061Sandreas@sandberg.pp.se#include "cpu/pred/bpred_unit.hh" 631977SN/A#include "cpu/profile.hh" 6411147Smitch.hayenga@arm.com#include "cpu/simple/exec_context.hh" 652683Sktlim@umich.edu#include "cpu/simple_thread.hh" 661717SN/A#include "cpu/smt.hh" 67146SN/A#include "cpu/static_inst.hh" 682683Sktlim@umich.edu#include "cpu/thread_context.hh" 698232Snate@binkert.org#include "debug/Decode.hh" 708232Snate@binkert.org#include "debug/Fetch.hh" 718232Snate@binkert.org#include "debug/Quiesce.hh" 723348Sbinkertn@umich.edu#include "mem/packet.hh" 736105Ssteve.reinhardt@amd.com#include "mem/request.hh" 746216Snate@binkert.org#include "params/BaseSimpleCPU.hh" 752036SN/A#include "sim/byteswap.hh" 76146SN/A#include "sim/debug.hh" 778817Sgblack@eecs.umich.edu#include "sim/faults.hh" 788793Sgblack@eecs.umich.edu#include "sim/full_system.hh" 7956SN/A#include "sim/sim_events.hh" 8056SN/A#include "sim/sim_object.hh" 81695SN/A#include "sim/stats.hh" 822901Ssaidi@eecs.umich.edu#include "sim/system.hh" 832SN/A 842SN/Ausing namespace std; 852449SN/Ausing namespace TheISA; 861355SN/A 875529Snate@binkert.orgBaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p) 8810061Sandreas@sandberg.pp.se : BaseCPU(p), 8911147Smitch.hayenga@arm.com curThread(0), 9010061Sandreas@sandberg.pp.se branchPred(p->branchPred), 9111147Smitch.hayenga@arm.com traceData(NULL), 9211147Smitch.hayenga@arm.com inst(), 9311147Smitch.hayenga@arm.com _status(Idle) 94224SN/A{ 9511147Smitch.hayenga@arm.com SimpleThread *thread; 962SN/A 9711147Smitch.hayenga@arm.com for (unsigned i = 0; i < numThreads; i++) { 9811147Smitch.hayenga@arm.com if (FullSystem) { 9911147Smitch.hayenga@arm.com thread = new SimpleThread(this, i, p->system, 10011147Smitch.hayenga@arm.com p->itb, p->dtb, p->isa[i]); 10111147Smitch.hayenga@arm.com } else { 10211147Smitch.hayenga@arm.com thread = new SimpleThread(this, i, p->system, p->workload[i], 10311147Smitch.hayenga@arm.com p->itb, p->dtb, p->isa[i]); 10411147Smitch.hayenga@arm.com } 10511147Smitch.hayenga@arm.com threadInfo.push_back(new SimpleExecContext(this, thread)); 10611147Smitch.hayenga@arm.com ThreadContext *tc = thread->getTC(); 10711147Smitch.hayenga@arm.com threadContexts.push_back(tc); 10811147Smitch.hayenga@arm.com } 1092SN/A 1108733Sgeoffrey.blake@arm.com if (p->checker) { 11111147Smitch.hayenga@arm.com if (numThreads != 1) 11211147Smitch.hayenga@arm.com fatal("Checker currently does not support SMT"); 11311147Smitch.hayenga@arm.com 1148733Sgeoffrey.blake@arm.com BaseCPU *temp_checker = p->checker; 1158733Sgeoffrey.blake@arm.com checker = dynamic_cast<CheckerCPU *>(temp_checker); 1168733Sgeoffrey.blake@arm.com checker->setSystem(p->system); 1178733Sgeoffrey.blake@arm.com // Manipulate thread context 11811147Smitch.hayenga@arm.com ThreadContext *cpu_tc = threadContexts[0]; 11911147Smitch.hayenga@arm.com threadContexts[0] = new CheckerThreadContext<ThreadContext>(cpu_tc, this->checker); 1208733Sgeoffrey.blake@arm.com } else { 1218733Sgeoffrey.blake@arm.com checker = NULL; 1228733Sgeoffrey.blake@arm.com } 12311147Smitch.hayenga@arm.com} 1248733Sgeoffrey.blake@arm.com 12511147Smitch.hayenga@arm.comvoid 12611147Smitch.hayenga@arm.comBaseSimpleCPU::init() 12711147Smitch.hayenga@arm.com{ 12811147Smitch.hayenga@arm.com BaseCPU::init(); 1292SN/A 13011147Smitch.hayenga@arm.com for (auto tc : threadContexts) { 13111147Smitch.hayenga@arm.com // Initialise the ThreadContext's memory proxies 13211147Smitch.hayenga@arm.com tc->initMemProxies(tc); 1334377Sgblack@eecs.umich.edu 13411147Smitch.hayenga@arm.com if (FullSystem && !params()->switched_out) { 13511147Smitch.hayenga@arm.com // initialize CPU, including PC 13611147Smitch.hayenga@arm.com TheISA::initCPU(tc, tc->contextId()); 13711147Smitch.hayenga@arm.com } 13811147Smitch.hayenga@arm.com } 13911147Smitch.hayenga@arm.com} 1405169Ssaidi@eecs.umich.edu 14111147Smitch.hayenga@arm.comvoid 14211147Smitch.hayenga@arm.comBaseSimpleCPU::checkPcEventQueue() 14311147Smitch.hayenga@arm.com{ 14411147Smitch.hayenga@arm.com Addr oldpc, pc = threadInfo[curThread]->thread->instAddr(); 14511147Smitch.hayenga@arm.com do { 14611147Smitch.hayenga@arm.com oldpc = pc; 14711147Smitch.hayenga@arm.com system->pcEventQueue.service(threadContexts[curThread]); 14811147Smitch.hayenga@arm.com pc = threadInfo[curThread]->thread->instAddr(); 14911147Smitch.hayenga@arm.com } while (oldpc != pc); 15011147Smitch.hayenga@arm.com} 15111147Smitch.hayenga@arm.com 15211147Smitch.hayenga@arm.comvoid 15311147Smitch.hayenga@arm.comBaseSimpleCPU::swapActiveThread() 15411147Smitch.hayenga@arm.com{ 15511147Smitch.hayenga@arm.com if (numThreads > 1) { 15611147Smitch.hayenga@arm.com if ((!curStaticInst || !curStaticInst->isDelayedCommit()) && 15711147Smitch.hayenga@arm.com !threadInfo[curThread]->stayAtPC) { 15811147Smitch.hayenga@arm.com // Swap active threads 15911147Smitch.hayenga@arm.com if (!activeThreads.empty()) { 16011147Smitch.hayenga@arm.com curThread = activeThreads.front(); 16111147Smitch.hayenga@arm.com activeThreads.pop_front(); 16211147Smitch.hayenga@arm.com activeThreads.push_back(curThread); 16311147Smitch.hayenga@arm.com } 16411147Smitch.hayenga@arm.com } 16511147Smitch.hayenga@arm.com } 16611147Smitch.hayenga@arm.com} 16711147Smitch.hayenga@arm.com 16811147Smitch.hayenga@arm.comvoid 16911147Smitch.hayenga@arm.comBaseSimpleCPU::countInst() 17011147Smitch.hayenga@arm.com{ 17111147Smitch.hayenga@arm.com SimpleExecContext& t_info = *threadInfo[curThread]; 17211147Smitch.hayenga@arm.com 17311147Smitch.hayenga@arm.com if (!curStaticInst->isMicroop() || curStaticInst->isLastMicroop()) { 17411147Smitch.hayenga@arm.com t_info.numInst++; 17511147Smitch.hayenga@arm.com t_info.numInsts++; 17613836Snikos.nikoleris@arm.com 17713836Snikos.nikoleris@arm.com system->totalNumInsts++; 17813836Snikos.nikoleris@arm.com t_info.thread->funcExeInst++; 17911147Smitch.hayenga@arm.com } 18011147Smitch.hayenga@arm.com t_info.numOp++; 18111147Smitch.hayenga@arm.com t_info.numOps++; 18211147Smitch.hayenga@arm.com} 18311147Smitch.hayenga@arm.com 18411147Smitch.hayenga@arm.comCounter 18511147Smitch.hayenga@arm.comBaseSimpleCPU::totalInsts() const 18611147Smitch.hayenga@arm.com{ 18711147Smitch.hayenga@arm.com Counter total_inst = 0; 18811147Smitch.hayenga@arm.com for (auto& t_info : threadInfo) { 18911147Smitch.hayenga@arm.com total_inst += t_info->numInst; 19011147Smitch.hayenga@arm.com } 19111147Smitch.hayenga@arm.com 19211147Smitch.hayenga@arm.com return total_inst; 19311147Smitch.hayenga@arm.com} 19411147Smitch.hayenga@arm.com 19511147Smitch.hayenga@arm.comCounter 19611147Smitch.hayenga@arm.comBaseSimpleCPU::totalOps() const 19711147Smitch.hayenga@arm.com{ 19811147Smitch.hayenga@arm.com Counter total_op = 0; 19911147Smitch.hayenga@arm.com for (auto& t_info : threadInfo) { 20011147Smitch.hayenga@arm.com total_op += t_info->numOp; 20111147Smitch.hayenga@arm.com } 20211147Smitch.hayenga@arm.com 20311147Smitch.hayenga@arm.com return total_op; 2042SN/A} 2052SN/A 2062623SN/ABaseSimpleCPU::~BaseSimpleCPU() 2072SN/A{ 2082SN/A} 2092SN/A 210180SN/Avoid 2118737Skoansin.tan@gmail.comBaseSimpleCPU::haltContext(ThreadID thread_num) 212393SN/A{ 213393SN/A // for now, these are equivalent 214393SN/A suspendContext(thread_num); 21512284Sjose.marinho@arm.com updateCycleCounters(BaseCPU::CPU_STATE_SLEEP); 216393SN/A} 217384SN/A 218189SN/A 219189SN/Avoid 2202623SN/ABaseSimpleCPU::regStats() 2212SN/A{ 222729SN/A using namespace Stats; 223334SN/A 2242SN/A BaseCPU::regStats(); 2252SN/A 22611147Smitch.hayenga@arm.com for (ThreadID tid = 0; tid < numThreads; tid++) { 22711147Smitch.hayenga@arm.com SimpleExecContext& t_info = *threadInfo[tid]; 2288834Satgutier@umich.edu 22911147Smitch.hayenga@arm.com std::string thread_str = name(); 23011147Smitch.hayenga@arm.com if (numThreads > 1) 23111147Smitch.hayenga@arm.com thread_str += ".thread" + std::to_string(tid); 2322SN/A 23311147Smitch.hayenga@arm.com t_info.numInsts 23411147Smitch.hayenga@arm.com .name(thread_str + ".committedInsts") 23511147Smitch.hayenga@arm.com .desc("Number of instructions committed") 23611147Smitch.hayenga@arm.com ; 2377897Shestness@cs.utexas.edu 23811147Smitch.hayenga@arm.com t_info.numOps 23911147Smitch.hayenga@arm.com .name(thread_str + ".committedOps") 24011147Smitch.hayenga@arm.com .desc("Number of ops (including micro ops) committed") 24111147Smitch.hayenga@arm.com ; 2427897Shestness@cs.utexas.edu 24311147Smitch.hayenga@arm.com t_info.numIntAluAccesses 24411147Smitch.hayenga@arm.com .name(thread_str + ".num_int_alu_accesses") 24511147Smitch.hayenga@arm.com .desc("Number of integer alu accesses") 24611147Smitch.hayenga@arm.com ; 2477897Shestness@cs.utexas.edu 24811147Smitch.hayenga@arm.com t_info.numFpAluAccesses 24911147Smitch.hayenga@arm.com .name(thread_str + ".num_fp_alu_accesses") 25011147Smitch.hayenga@arm.com .desc("Number of float alu accesses") 25111147Smitch.hayenga@arm.com ; 2527897Shestness@cs.utexas.edu 25312110SRekai.GonzalezAlberquilla@arm.com t_info.numVecAluAccesses 25412110SRekai.GonzalezAlberquilla@arm.com .name(thread_str + ".num_vec_alu_accesses") 25512110SRekai.GonzalezAlberquilla@arm.com .desc("Number of vector alu accesses") 25612110SRekai.GonzalezAlberquilla@arm.com ; 25712110SRekai.GonzalezAlberquilla@arm.com 25811147Smitch.hayenga@arm.com t_info.numCallsReturns 25911147Smitch.hayenga@arm.com .name(thread_str + ".num_func_calls") 26011147Smitch.hayenga@arm.com .desc("number of times a function call or return occured") 26111147Smitch.hayenga@arm.com ; 2627897Shestness@cs.utexas.edu 26311147Smitch.hayenga@arm.com t_info.numCondCtrlInsts 26411147Smitch.hayenga@arm.com .name(thread_str + ".num_conditional_control_insts") 26511147Smitch.hayenga@arm.com .desc("number of instructions that are conditional controls") 26611147Smitch.hayenga@arm.com ; 2677897Shestness@cs.utexas.edu 26811147Smitch.hayenga@arm.com t_info.numIntInsts 26911147Smitch.hayenga@arm.com .name(thread_str + ".num_int_insts") 27011147Smitch.hayenga@arm.com .desc("number of integer instructions") 27111147Smitch.hayenga@arm.com ; 2727897Shestness@cs.utexas.edu 27311147Smitch.hayenga@arm.com t_info.numFpInsts 27411147Smitch.hayenga@arm.com .name(thread_str + ".num_fp_insts") 27511147Smitch.hayenga@arm.com .desc("number of float instructions") 27611147Smitch.hayenga@arm.com ; 2777897Shestness@cs.utexas.edu 27812110SRekai.GonzalezAlberquilla@arm.com t_info.numVecInsts 27912110SRekai.GonzalezAlberquilla@arm.com .name(thread_str + ".num_vec_insts") 28012110SRekai.GonzalezAlberquilla@arm.com .desc("number of vector instructions") 28112110SRekai.GonzalezAlberquilla@arm.com ; 28212110SRekai.GonzalezAlberquilla@arm.com 28311147Smitch.hayenga@arm.com t_info.numIntRegReads 28411147Smitch.hayenga@arm.com .name(thread_str + ".num_int_register_reads") 28511147Smitch.hayenga@arm.com .desc("number of times the integer registers were read") 28611147Smitch.hayenga@arm.com ; 2877897Shestness@cs.utexas.edu 28811147Smitch.hayenga@arm.com t_info.numIntRegWrites 28911147Smitch.hayenga@arm.com .name(thread_str + ".num_int_register_writes") 29011147Smitch.hayenga@arm.com .desc("number of times the integer registers were written") 29111147Smitch.hayenga@arm.com ; 2927897Shestness@cs.utexas.edu 29311147Smitch.hayenga@arm.com t_info.numFpRegReads 29411147Smitch.hayenga@arm.com .name(thread_str + ".num_fp_register_reads") 29511147Smitch.hayenga@arm.com .desc("number of times the floating registers were read") 29611147Smitch.hayenga@arm.com ; 2979920Syasuko.eckert@amd.com 29811147Smitch.hayenga@arm.com t_info.numFpRegWrites 29911147Smitch.hayenga@arm.com .name(thread_str + ".num_fp_register_writes") 30011147Smitch.hayenga@arm.com .desc("number of times the floating registers were written") 30111147Smitch.hayenga@arm.com ; 3029920Syasuko.eckert@amd.com 30312109SRekai.GonzalezAlberquilla@arm.com t_info.numVecRegReads 30412109SRekai.GonzalezAlberquilla@arm.com .name(thread_str + ".num_vec_register_reads") 30512109SRekai.GonzalezAlberquilla@arm.com .desc("number of times the vector registers were read") 30612109SRekai.GonzalezAlberquilla@arm.com ; 30712109SRekai.GonzalezAlberquilla@arm.com 30812109SRekai.GonzalezAlberquilla@arm.com t_info.numVecRegWrites 30912109SRekai.GonzalezAlberquilla@arm.com .name(thread_str + ".num_vec_register_writes") 31012109SRekai.GonzalezAlberquilla@arm.com .desc("number of times the vector registers were written") 31112109SRekai.GonzalezAlberquilla@arm.com ; 31212109SRekai.GonzalezAlberquilla@arm.com 31311147Smitch.hayenga@arm.com t_info.numCCRegReads 31411147Smitch.hayenga@arm.com .name(thread_str + ".num_cc_register_reads") 31511147Smitch.hayenga@arm.com .desc("number of times the CC registers were read") 31611147Smitch.hayenga@arm.com .flags(nozero) 31711147Smitch.hayenga@arm.com ; 3187897Shestness@cs.utexas.edu 31911147Smitch.hayenga@arm.com t_info.numCCRegWrites 32011147Smitch.hayenga@arm.com .name(thread_str + ".num_cc_register_writes") 32111147Smitch.hayenga@arm.com .desc("number of times the CC registers were written") 32211147Smitch.hayenga@arm.com .flags(nozero) 32311147Smitch.hayenga@arm.com ; 3247897Shestness@cs.utexas.edu 32511147Smitch.hayenga@arm.com t_info.numMemRefs 32611147Smitch.hayenga@arm.com .name(thread_str + ".num_mem_refs") 32711147Smitch.hayenga@arm.com .desc("number of memory refs") 32811147Smitch.hayenga@arm.com ; 3292SN/A 33011147Smitch.hayenga@arm.com t_info.numStoreInsts 33111147Smitch.hayenga@arm.com .name(thread_str + ".num_store_insts") 33211147Smitch.hayenga@arm.com .desc("Number of store instructions") 33311147Smitch.hayenga@arm.com ; 3341001SN/A 33511147Smitch.hayenga@arm.com t_info.numLoadInsts 33611147Smitch.hayenga@arm.com .name(thread_str + ".num_load_insts") 33711147Smitch.hayenga@arm.com .desc("Number of load instructions") 33811147Smitch.hayenga@arm.com ; 3392SN/A 34011147Smitch.hayenga@arm.com t_info.notIdleFraction 34111147Smitch.hayenga@arm.com .name(thread_str + ".not_idle_fraction") 34211147Smitch.hayenga@arm.com .desc("Percentage of non-idle cycles") 34311147Smitch.hayenga@arm.com ; 3447897Shestness@cs.utexas.edu 34511147Smitch.hayenga@arm.com t_info.idleFraction 34611147Smitch.hayenga@arm.com .name(thread_str + ".idle_fraction") 34711147Smitch.hayenga@arm.com .desc("Percentage of idle cycles") 34811147Smitch.hayenga@arm.com ; 3497897Shestness@cs.utexas.edu 35011147Smitch.hayenga@arm.com t_info.numBusyCycles 35111147Smitch.hayenga@arm.com .name(thread_str + ".num_busy_cycles") 35211147Smitch.hayenga@arm.com .desc("Number of busy cycles") 35311147Smitch.hayenga@arm.com ; 3542SN/A 35511147Smitch.hayenga@arm.com t_info.numIdleCycles 35611147Smitch.hayenga@arm.com .name(thread_str + ".num_idle_cycles") 35711147Smitch.hayenga@arm.com .desc("Number of idle cycles") 35811147Smitch.hayenga@arm.com ; 3592SN/A 36011147Smitch.hayenga@arm.com t_info.icacheStallCycles 36111147Smitch.hayenga@arm.com .name(thread_str + ".icache_stall_cycles") 36211147Smitch.hayenga@arm.com .desc("ICache total stall cycles") 36311147Smitch.hayenga@arm.com .prereq(t_info.icacheStallCycles) 36411147Smitch.hayenga@arm.com ; 36511147Smitch.hayenga@arm.com 36611147Smitch.hayenga@arm.com t_info.dcacheStallCycles 36711147Smitch.hayenga@arm.com .name(thread_str + ".dcache_stall_cycles") 36811147Smitch.hayenga@arm.com .desc("DCache total stall cycles") 36911147Smitch.hayenga@arm.com .prereq(t_info.dcacheStallCycles) 37011147Smitch.hayenga@arm.com ; 37111147Smitch.hayenga@arm.com 37211147Smitch.hayenga@arm.com t_info.statExecutedInstType 37311147Smitch.hayenga@arm.com .init(Enums::Num_OpClass) 37411147Smitch.hayenga@arm.com .name(thread_str + ".op_class") 37511147Smitch.hayenga@arm.com .desc("Class of executed instruction") 37611147Smitch.hayenga@arm.com .flags(total | pdf | dist) 37711147Smitch.hayenga@arm.com ; 37811147Smitch.hayenga@arm.com 37911147Smitch.hayenga@arm.com for (unsigned i = 0; i < Num_OpClasses; ++i) { 38011147Smitch.hayenga@arm.com t_info.statExecutedInstType.subname(i, Enums::OpClassStrings[i]); 38111147Smitch.hayenga@arm.com } 38211147Smitch.hayenga@arm.com 38311147Smitch.hayenga@arm.com t_info.idleFraction = constant(1.0) - t_info.notIdleFraction; 38411147Smitch.hayenga@arm.com t_info.numIdleCycles = t_info.idleFraction * numCycles; 38511147Smitch.hayenga@arm.com t_info.numBusyCycles = t_info.notIdleFraction * numCycles; 38611147Smitch.hayenga@arm.com 38711147Smitch.hayenga@arm.com t_info.numBranches 38811147Smitch.hayenga@arm.com .name(thread_str + ".Branches") 38911147Smitch.hayenga@arm.com .desc("Number of branches fetched") 39011147Smitch.hayenga@arm.com .prereq(t_info.numBranches); 39111147Smitch.hayenga@arm.com 39211147Smitch.hayenga@arm.com t_info.numPredictedBranches 39311147Smitch.hayenga@arm.com .name(thread_str + ".predictedBranches") 39411147Smitch.hayenga@arm.com .desc("Number of branches predicted as taken") 39511147Smitch.hayenga@arm.com .prereq(t_info.numPredictedBranches); 39611147Smitch.hayenga@arm.com 39711147Smitch.hayenga@arm.com t_info.numBranchMispred 39811147Smitch.hayenga@arm.com .name(thread_str + ".BranchMispred") 39911147Smitch.hayenga@arm.com .desc("Number of branch mispredictions") 40011147Smitch.hayenga@arm.com .prereq(t_info.numBranchMispred); 40110193SCurtis.Dunham@arm.com } 4022SN/A} 4032SN/A 4042SN/Avoid 4052623SN/ABaseSimpleCPU::resetStats() 406334SN/A{ 40711147Smitch.hayenga@arm.com for (auto &thread_info : threadInfo) { 40811147Smitch.hayenga@arm.com thread_info->notIdleFraction = (_status != Idle); 40911147Smitch.hayenga@arm.com } 410334SN/A} 411334SN/A 412334SN/Avoid 41310905Sandreas.sandberg@arm.comBaseSimpleCPU::serializeThread(CheckpointOut &cp, ThreadID tid) const 4142SN/A{ 4159448SAndreas.Sandberg@ARM.com assert(_status == Idle || _status == Running); 4169448SAndreas.Sandberg@ARM.com 41711147Smitch.hayenga@arm.com threadInfo[tid]->thread->serialize(cp); 4182SN/A} 4192SN/A 4202SN/Avoid 42110905Sandreas.sandberg@arm.comBaseSimpleCPU::unserializeThread(CheckpointIn &cp, ThreadID tid) 4222SN/A{ 42311147Smitch.hayenga@arm.com threadInfo[tid]->thread->unserialize(cp); 4242SN/A} 4252SN/A 4262SN/Avoid 4276221Snate@binkert.orgchange_thread_state(ThreadID tid, int activate, int priority) 4282SN/A{ 4292SN/A} 4302SN/A 4312SN/AAddr 4322623SN/ABaseSimpleCPU::dbg_vtophys(Addr addr) 4332SN/A{ 43411147Smitch.hayenga@arm.com return vtophys(threadContexts[curThread], addr); 4352SN/A} 4362SN/A 4372SN/Avoid 43811151Smitch.hayenga@arm.comBaseSimpleCPU::wakeup(ThreadID tid) 4392SN/A{ 44011151Smitch.hayenga@arm.com getCpuAddrMonitor(tid)->gotWakeup = true; 44111151Smitch.hayenga@arm.com 44211151Smitch.hayenga@arm.com if (threadInfo[tid]->thread->status() == ThreadContext::Suspended) { 44311151Smitch.hayenga@arm.com DPRINTF(Quiesce,"[tid:%d] Suspended Processor awoke\n", tid); 44411151Smitch.hayenga@arm.com threadInfo[tid]->thread->activate(); 44511147Smitch.hayenga@arm.com } 4462SN/A} 4472SN/A 4482SN/Avoid 4492623SN/ABaseSimpleCPU::checkForInterrupts() 4502SN/A{ 45111147Smitch.hayenga@arm.com SimpleExecContext&t_info = *threadInfo[curThread]; 45211147Smitch.hayenga@arm.com SimpleThread* thread = t_info.thread; 45311147Smitch.hayenga@arm.com ThreadContext* tc = thread->getTC(); 45411147Smitch.hayenga@arm.com 4555704Snate@binkert.org if (checkInterrupts(tc)) { 45611150Smitch.hayenga@arm.com Fault interrupt = interrupts[curThread]->getInterrupt(tc); 4572SN/A 4583520Sgblack@eecs.umich.edu if (interrupt != NoFault) { 45911147Smitch.hayenga@arm.com t_info.fetchOffset = 0; 46011150Smitch.hayenga@arm.com interrupts[curThread]->updateIntrInfo(tc); 4613520Sgblack@eecs.umich.edu interrupt->invoke(tc); 4629023Sgblack@eecs.umich.edu thread->decoder.reset(); 4632SN/A } 4642SN/A } 4652623SN/A} 4662SN/A 4672623SN/A 4685894Sgblack@eecs.umich.eduvoid 46912749Sgiacomo.travaglini@arm.comBaseSimpleCPU::setupFetchRequest(const RequestPtr &req) 4702623SN/A{ 47111147Smitch.hayenga@arm.com SimpleExecContext &t_info = *threadInfo[curThread]; 47211147Smitch.hayenga@arm.com SimpleThread* thread = t_info.thread; 47311147Smitch.hayenga@arm.com 4747720Sgblack@eecs.umich.edu Addr instAddr = thread->instAddr(); 47512372Smattdsinclair@gmail.com Addr fetchPC = (instAddr & PCMask) + t_info.fetchOffset; 4764495Sacolyte@umich.edu 4772623SN/A // set up memory request for instruction fetch 47812372Smattdsinclair@gmail.com DPRINTF(Fetch, "Fetch: Inst PC:%08p, Fetch PC:%08p\n", instAddr, fetchPC); 4792623SN/A 48012372Smattdsinclair@gmail.com req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH, 48112372Smattdsinclair@gmail.com instMasterId(), instAddr); 4822623SN/A} 4832623SN/A 4842623SN/A 4852623SN/Avoid 4862623SN/ABaseSimpleCPU::preExecute() 4872623SN/A{ 48811147Smitch.hayenga@arm.com SimpleExecContext &t_info = *threadInfo[curThread]; 48911147Smitch.hayenga@arm.com SimpleThread* thread = t_info.thread; 49011147Smitch.hayenga@arm.com 4912SN/A // maintain $r0 semantics 4922683Sktlim@umich.edu thread->setIntReg(ZeroReg, 0); 4932427SN/A#if THE_ISA == ALPHA_ISA 49413611Sgabeblack@google.com thread->setFloatReg(ZeroReg, 0); 4952427SN/A#endif // ALPHA_ISA 4962SN/A 49713954Sgiacomo.gabrielli@arm.com // resets predicates 49813954Sgiacomo.gabrielli@arm.com t_info.setPredicate(true); 49913954Sgiacomo.gabrielli@arm.com t_info.setMemAccPredicate(true); 50013954Sgiacomo.gabrielli@arm.com 5012623SN/A // check for instruction-count-based events 50211147Smitch.hayenga@arm.com comInstEventQueue[curThread]->serviceEvents(t_info.numInst); 5037897Shestness@cs.utexas.edu system->instEventQueue.serviceEvents(system->totalNumInsts); 5042SN/A 5052623SN/A // decode the instruction 5062623SN/A inst = gtoh(inst); 5074377Sgblack@eecs.umich.edu 5087720Sgblack@eecs.umich.edu TheISA::PCState pcState = thread->pcState(); 5094377Sgblack@eecs.umich.edu 5107720Sgblack@eecs.umich.edu if (isRomMicroPC(pcState.microPC())) { 51111147Smitch.hayenga@arm.com t_info.stayAtPC = false; 5127720Sgblack@eecs.umich.edu curStaticInst = microcodeRom.fetchMicroop(pcState.microPC(), 5137720Sgblack@eecs.umich.edu curMacroStaticInst); 5145665Sgblack@eecs.umich.edu } else if (!curMacroStaticInst) { 5155665Sgblack@eecs.umich.edu //We're not in the middle of a macro instruction 5164181Sgblack@eecs.umich.edu StaticInstPtr instPtr = NULL; 5174181Sgblack@eecs.umich.edu 5189023Sgblack@eecs.umich.edu TheISA::Decoder *decoder = &(thread->decoder); 5199023Sgblack@eecs.umich.edu 5204181Sgblack@eecs.umich.edu //Predecode, ie bundle up an ExtMachInst 5214182Sgblack@eecs.umich.edu //If more fetch data is needed, pass it in. 52211147Smitch.hayenga@arm.com Addr fetchPC = (pcState.instAddr() & PCMask) + t_info.fetchOffset; 52311321Ssteve.reinhardt@amd.com //if (decoder->needMoreBytes()) 5249023Sgblack@eecs.umich.edu decoder->moreBytes(pcState, fetchPC, inst); 5254593Sgblack@eecs.umich.edu //else 5269023Sgblack@eecs.umich.edu // decoder->process(); 5274377Sgblack@eecs.umich.edu 5289023Sgblack@eecs.umich.edu //Decode an instruction if one is ready. Otherwise, we'll have to 5294377Sgblack@eecs.umich.edu //fetch beyond the MachInst at the current pc. 5309023Sgblack@eecs.umich.edu instPtr = decoder->decode(pcState); 5319023Sgblack@eecs.umich.edu if (instPtr) { 53211147Smitch.hayenga@arm.com t_info.stayAtPC = false; 5337720Sgblack@eecs.umich.edu thread->pcState(pcState); 5344377Sgblack@eecs.umich.edu } else { 53511147Smitch.hayenga@arm.com t_info.stayAtPC = true; 53611147Smitch.hayenga@arm.com t_info.fetchOffset += sizeof(MachInst); 5374377Sgblack@eecs.umich.edu } 5384181Sgblack@eecs.umich.edu 5394181Sgblack@eecs.umich.edu //If we decoded an instruction and it's microcoded, start pulling 5404181Sgblack@eecs.umich.edu //out micro ops 5414539Sgblack@eecs.umich.edu if (instPtr && instPtr->isMacroop()) { 5423276Sgblack@eecs.umich.edu curMacroStaticInst = instPtr; 54311147Smitch.hayenga@arm.com curStaticInst = 54411147Smitch.hayenga@arm.com curMacroStaticInst->fetchMicroop(pcState.microPC()); 5453280Sgblack@eecs.umich.edu } else { 5463280Sgblack@eecs.umich.edu curStaticInst = instPtr; 5473276Sgblack@eecs.umich.edu } 5483276Sgblack@eecs.umich.edu } else { 5493276Sgblack@eecs.umich.edu //Read the next micro op from the macro op 5507720Sgblack@eecs.umich.edu curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC()); 5513276Sgblack@eecs.umich.edu } 5523276Sgblack@eecs.umich.edu 5534181Sgblack@eecs.umich.edu //If we decoded an instruction this "tick", record information about it. 5548955Sgblack@eecs.umich.edu if (curStaticInst) { 5554522Ssaidi@eecs.umich.edu#if TRACING_ON 55611147Smitch.hayenga@arm.com traceData = tracer->getInstRecord(curTick(), thread->getTC(), 5577720Sgblack@eecs.umich.edu curStaticInst, thread->pcState(), curMacroStaticInst); 5582470SN/A 5598955Sgblack@eecs.umich.edu DPRINTF(Decode,"Decode: Decoded %s instruction: %#x\n", 5604181Sgblack@eecs.umich.edu curStaticInst->getName(), curStaticInst->machInst); 5614522Ssaidi@eecs.umich.edu#endif // TRACING_ON 5624181Sgblack@eecs.umich.edu } 56310061Sandreas@sandberg.pp.se 56411147Smitch.hayenga@arm.com if (branchPred && curStaticInst && 56511147Smitch.hayenga@arm.com curStaticInst->isControl()) { 56610061Sandreas@sandberg.pp.se // Use a fake sequence number since we only have one 56710061Sandreas@sandberg.pp.se // instruction in flight at the same time. 56810061Sandreas@sandberg.pp.se const InstSeqNum cur_sn(0); 56911147Smitch.hayenga@arm.com t_info.predPC = thread->pcState(); 57010061Sandreas@sandberg.pp.se const bool predict_taken( 57111147Smitch.hayenga@arm.com branchPred->predict(curStaticInst, cur_sn, t_info.predPC, 57211147Smitch.hayenga@arm.com curThread)); 57310061Sandreas@sandberg.pp.se 57410061Sandreas@sandberg.pp.se if (predict_taken) 57511147Smitch.hayenga@arm.com ++t_info.numPredictedBranches; 57610061Sandreas@sandberg.pp.se } 5772623SN/A} 5782623SN/A 5792623SN/Avoid 5802623SN/ABaseSimpleCPU::postExecute() 5812623SN/A{ 58211147Smitch.hayenga@arm.com SimpleExecContext &t_info = *threadInfo[curThread]; 58311147Smitch.hayenga@arm.com SimpleThread* thread = t_info.thread; 58411147Smitch.hayenga@arm.com 5857720Sgblack@eecs.umich.edu assert(curStaticInst); 5867720Sgblack@eecs.umich.edu 58711147Smitch.hayenga@arm.com TheISA::PCState pc = threadContexts[curThread]->pcState(); 5887720Sgblack@eecs.umich.edu Addr instAddr = pc.instAddr(); 5898780Sgblack@eecs.umich.edu if (FullSystem && thread->profile) { 59011147Smitch.hayenga@arm.com bool usermode = TheISA::inUserMode(threadContexts[curThread]); 5917720Sgblack@eecs.umich.edu thread->profilePC = usermode ? 1 : instAddr; 59211147Smitch.hayenga@arm.com ProfileNode *node = thread->profile->consume(threadContexts[curThread], 59311147Smitch.hayenga@arm.com curStaticInst); 5942623SN/A if (node) 5952683Sktlim@umich.edu thread->profileNode = node; 5962623SN/A } 5972SN/A 5982623SN/A if (curStaticInst->isMemRef()) { 59911147Smitch.hayenga@arm.com t_info.numMemRefs++; 6002SN/A } 6012SN/A 6022623SN/A if (curStaticInst->isLoad()) { 60311147Smitch.hayenga@arm.com ++t_info.numLoad; 60411147Smitch.hayenga@arm.com comLoadEventQueue[curThread]->serviceEvents(t_info.numLoad); 6052623SN/A } 6062SN/A 6075953Ssaidi@eecs.umich.edu if (CPA::available()) { 60811147Smitch.hayenga@arm.com CPA::cpa()->swAutoBegin(threadContexts[curThread], pc.nextInstAddr()); 6095953Ssaidi@eecs.umich.edu } 6105953Ssaidi@eecs.umich.edu 61110061Sandreas@sandberg.pp.se if (curStaticInst->isControl()) { 61211147Smitch.hayenga@arm.com ++t_info.numBranches; 61310061Sandreas@sandberg.pp.se } 61410061Sandreas@sandberg.pp.se 6157897Shestness@cs.utexas.edu /* Power model statistics */ 6167897Shestness@cs.utexas.edu //integer alu accesses 6177897Shestness@cs.utexas.edu if (curStaticInst->isInteger()){ 61811147Smitch.hayenga@arm.com t_info.numIntAluAccesses++; 61911147Smitch.hayenga@arm.com t_info.numIntInsts++; 6207897Shestness@cs.utexas.edu } 6217897Shestness@cs.utexas.edu 6227897Shestness@cs.utexas.edu //float alu accesses 6237897Shestness@cs.utexas.edu if (curStaticInst->isFloating()){ 62411147Smitch.hayenga@arm.com t_info.numFpAluAccesses++; 62511147Smitch.hayenga@arm.com t_info.numFpInsts++; 6267897Shestness@cs.utexas.edu } 62711147Smitch.hayenga@arm.com 62812110SRekai.GonzalezAlberquilla@arm.com //vector alu accesses 62912110SRekai.GonzalezAlberquilla@arm.com if (curStaticInst->isVector()){ 63012110SRekai.GonzalezAlberquilla@arm.com t_info.numVecAluAccesses++; 63112110SRekai.GonzalezAlberquilla@arm.com t_info.numVecInsts++; 63212110SRekai.GonzalezAlberquilla@arm.com } 63312110SRekai.GonzalezAlberquilla@arm.com 6347897Shestness@cs.utexas.edu //number of function calls/returns to get window accesses 6357897Shestness@cs.utexas.edu if (curStaticInst->isCall() || curStaticInst->isReturn()){ 63611147Smitch.hayenga@arm.com t_info.numCallsReturns++; 6377897Shestness@cs.utexas.edu } 63811147Smitch.hayenga@arm.com 6397897Shestness@cs.utexas.edu //the number of branch predictions that will be made 6407897Shestness@cs.utexas.edu if (curStaticInst->isCondCtrl()){ 64111147Smitch.hayenga@arm.com t_info.numCondCtrlInsts++; 6427897Shestness@cs.utexas.edu } 64311147Smitch.hayenga@arm.com 6447897Shestness@cs.utexas.edu //result bus acceses 6457897Shestness@cs.utexas.edu if (curStaticInst->isLoad()){ 64611147Smitch.hayenga@arm.com t_info.numLoadInsts++; 6477897Shestness@cs.utexas.edu } 64811147Smitch.hayenga@arm.com 64913652Sqtt2@cornell.edu if (curStaticInst->isStore() || curStaticInst->isAtomic()){ 65011147Smitch.hayenga@arm.com t_info.numStoreInsts++; 6517897Shestness@cs.utexas.edu } 6527897Shestness@cs.utexas.edu /* End power model statistics */ 6537897Shestness@cs.utexas.edu 65411147Smitch.hayenga@arm.com t_info.statExecutedInstType[curStaticInst->opClass()]++; 65510193SCurtis.Dunham@arm.com 6568780Sgblack@eecs.umich.edu if (FullSystem) 6578780Sgblack@eecs.umich.edu traceFunctions(instAddr); 6582644Sstever@eecs.umich.edu 6592644Sstever@eecs.umich.edu if (traceData) { 6604046Sbinkertn@umich.edu traceData->dump(); 6614046Sbinkertn@umich.edu delete traceData; 6624046Sbinkertn@umich.edu traceData = NULL; 6632644Sstever@eecs.umich.edu } 66410464SAndreas.Sandberg@ARM.com 66510464SAndreas.Sandberg@ARM.com // Call CPU instruction commit probes 66613818Sjavier.bueno@metempsy.com probeInstCommit(curStaticInst, instAddr); 6672623SN/A} 6682SN/A 6692623SN/Avoid 67010379Sandreas.hansson@arm.comBaseSimpleCPU::advancePC(const Fault &fault) 6712623SN/A{ 67211147Smitch.hayenga@arm.com SimpleExecContext &t_info = *threadInfo[curThread]; 67311147Smitch.hayenga@arm.com SimpleThread* thread = t_info.thread; 67411147Smitch.hayenga@arm.com 67510061Sandreas@sandberg.pp.se const bool branching(thread->pcState().branching()); 67610061Sandreas@sandberg.pp.se 6774377Sgblack@eecs.umich.edu //Since we're moving to a new pc, zero out the offset 67811147Smitch.hayenga@arm.com t_info.fetchOffset = 0; 6792090SN/A if (fault != NoFault) { 6803905Ssaidi@eecs.umich.edu curMacroStaticInst = StaticInst::nullStaticInstPtr; 68111147Smitch.hayenga@arm.com fault->invoke(threadContexts[curThread], curStaticInst); 6829023Sgblack@eecs.umich.edu thread->decoder.reset(); 6834377Sgblack@eecs.umich.edu } else { 6847720Sgblack@eecs.umich.edu if (curStaticInst) { 6857720Sgblack@eecs.umich.edu if (curStaticInst->isLastMicroop()) 6867720Sgblack@eecs.umich.edu curMacroStaticInst = StaticInst::nullStaticInstPtr; 6877720Sgblack@eecs.umich.edu TheISA::PCState pcState = thread->pcState(); 6887720Sgblack@eecs.umich.edu TheISA::advancePC(pcState, curStaticInst); 6897720Sgblack@eecs.umich.edu thread->pcState(pcState); 6903276Sgblack@eecs.umich.edu } 6912SN/A } 69210061Sandreas@sandberg.pp.se 69310061Sandreas@sandberg.pp.se if (branchPred && curStaticInst && curStaticInst->isControl()) { 69410061Sandreas@sandberg.pp.se // Use a fake sequence number since we only have one 69510061Sandreas@sandberg.pp.se // instruction in flight at the same time. 69610061Sandreas@sandberg.pp.se const InstSeqNum cur_sn(0); 69710061Sandreas@sandberg.pp.se 69811147Smitch.hayenga@arm.com if (t_info.predPC == thread->pcState()) { 69910061Sandreas@sandberg.pp.se // Correctly predicted branch 70011147Smitch.hayenga@arm.com branchPred->update(cur_sn, curThread); 70110061Sandreas@sandberg.pp.se } else { 70210061Sandreas@sandberg.pp.se // Mis-predicted branch 70311147Smitch.hayenga@arm.com branchPred->squash(cur_sn, thread->pcState(), branching, curThread); 70411147Smitch.hayenga@arm.com ++t_info.numBranchMispred; 70510061Sandreas@sandberg.pp.se } 70610061Sandreas@sandberg.pp.se } 7072SN/A} 7082SN/A 7099461Snilay@cs.wisc.eduvoid 7109461Snilay@cs.wisc.eduBaseSimpleCPU::startup() 7119461Snilay@cs.wisc.edu{ 7129461Snilay@cs.wisc.edu BaseCPU::startup(); 71311147Smitch.hayenga@arm.com for (auto& t_info : threadInfo) 71411147Smitch.hayenga@arm.com t_info->thread->startup(); 7159461Snilay@cs.wisc.edu} 716