2c2
< * Copyright (c) 2010-2012 ARM Limited
---
> * Copyright (c) 2010-2012,2015 ARM Limited
64a65
> #include "cpu/simple/exec_context.hh"
89a91
> curThread(0),
91,92c93,95
< traceData(NULL), thread(NULL), _status(Idle), interval_stats(false),
< inst()
---
> traceData(NULL),
> inst(),
> _status(Idle)
94,99c97
< if (FullSystem)
< thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb,
< p->isa[0]);
< else
< thread = new SimpleThread(this, /* thread_num */ 0, p->system,
< p->workload[0], p->itb, p->dtb, p->isa[0]);
---
> SimpleThread *thread;
101c99,110
< thread->setStatus(ThreadContext::Halted);
---
> for (unsigned i = 0; i < numThreads; i++) {
> if (FullSystem) {
> thread = new SimpleThread(this, i, p->system,
> p->itb, p->dtb, p->isa[i]);
> } else {
> thread = new SimpleThread(this, i, p->system, p->workload[i],
> p->itb, p->dtb, p->isa[i]);
> }
> threadInfo.push_back(new SimpleExecContext(this, thread));
> ThreadContext *tc = thread->getTC();
> threadContexts.push_back(tc);
> }
103,104d111
< tc = thread->getTC();
<
105a113,115
> if (numThreads != 1)
> fatal("Checker currently does not support SMT");
>
110,111c120,121
< ThreadContext *cpu_tc = tc;
< tc = new CheckerThreadContext<ThreadContext>(cpu_tc, this->checker);
---
> ThreadContext *cpu_tc = threadContexts[0];
> threadContexts[0] = new CheckerThreadContext<ThreadContext>(cpu_tc, this->checker);
114a125
> }
116,123c127,130
< numInst = 0;
< startNumInst = 0;
< numOp = 0;
< startNumOp = 0;
< numLoad = 0;
< startNumLoad = 0;
< lastIcacheStall = 0;
< lastDcacheStall = 0;
---
> void
> BaseSimpleCPU::init()
> {
> BaseCPU::init();
125c132,134
< threadContexts.push_back(tc);
---
> for (auto tc : threadContexts) {
> // Initialise the ThreadContext's memory proxies
> tc->initMemProxies(tc);
126a136,141
> if (FullSystem && !params()->switched_out) {
> // initialize CPU, including PC
> TheISA::initCPU(tc, tc->contextId());
> }
> }
> }
128,129c143,151
< fetchOffset = 0;
< stayAtPC = false;
---
> void
> BaseSimpleCPU::checkPcEventQueue()
> {
> Addr oldpc, pc = threadInfo[curThread]->thread->instAddr();
> do {
> oldpc = pc;
> system->pcEventQueue.service(threadContexts[curThread]);
> pc = threadInfo[curThread]->thread->instAddr();
> } while (oldpc != pc);
131a154,207
> void
> BaseSimpleCPU::swapActiveThread()
> {
> if (numThreads > 1) {
> if ((!curStaticInst || !curStaticInst->isDelayedCommit()) &&
> !threadInfo[curThread]->stayAtPC) {
> // Swap active threads
> if (!activeThreads.empty()) {
> curThread = activeThreads.front();
> activeThreads.pop_front();
> activeThreads.push_back(curThread);
> }
> }
> }
> }
>
> void
> BaseSimpleCPU::countInst()
> {
> SimpleExecContext& t_info = *threadInfo[curThread];
>
> if (!curStaticInst->isMicroop() || curStaticInst->isLastMicroop()) {
> t_info.numInst++;
> t_info.numInsts++;
> }
> t_info.numOp++;
> t_info.numOps++;
>
> system->totalNumInsts++;
> t_info.thread->funcExeInst++;
> }
>
> Counter
> BaseSimpleCPU::totalInsts() const
> {
> Counter total_inst = 0;
> for (auto& t_info : threadInfo) {
> total_inst += t_info->numInst;
> }
>
> return total_inst;
> }
>
> Counter
> BaseSimpleCPU::totalOps() const
> {
> Counter total_op = 0;
> for (auto& t_info : threadInfo) {
> total_op += t_info->numOp;
> }
>
> return total_op;
> }
>
151,154c227,228
< numInsts
< .name(name() + ".committedInsts")
< .desc("Number of instructions committed")
< ;
---
> for (ThreadID tid = 0; tid < numThreads; tid++) {
> SimpleExecContext& t_info = *threadInfo[tid];
156,159c230,232
< numOps
< .name(name() + ".committedOps")
< .desc("Number of ops (including micro ops) committed")
< ;
---
> std::string thread_str = name();
> if (numThreads > 1)
> thread_str += ".thread" + std::to_string(tid);
161,164c234,237
< numIntAluAccesses
< .name(name() + ".num_int_alu_accesses")
< .desc("Number of integer alu accesses")
< ;
---
> t_info.numInsts
> .name(thread_str + ".committedInsts")
> .desc("Number of instructions committed")
> ;
166,169c239,242
< numFpAluAccesses
< .name(name() + ".num_fp_alu_accesses")
< .desc("Number of float alu accesses")
< ;
---
> t_info.numOps
> .name(thread_str + ".committedOps")
> .desc("Number of ops (including micro ops) committed")
> ;
171,174c244,247
< numCallsReturns
< .name(name() + ".num_func_calls")
< .desc("number of times a function call or return occured")
< ;
---
> t_info.numIntAluAccesses
> .name(thread_str + ".num_int_alu_accesses")
> .desc("Number of integer alu accesses")
> ;
176,179c249,252
< numCondCtrlInsts
< .name(name() + ".num_conditional_control_insts")
< .desc("number of instructions that are conditional controls")
< ;
---
> t_info.numFpAluAccesses
> .name(thread_str + ".num_fp_alu_accesses")
> .desc("Number of float alu accesses")
> ;
181,184c254,257
< numIntInsts
< .name(name() + ".num_int_insts")
< .desc("number of integer instructions")
< ;
---
> t_info.numCallsReturns
> .name(thread_str + ".num_func_calls")
> .desc("number of times a function call or return occured")
> ;
186,189c259,262
< numFpInsts
< .name(name() + ".num_fp_insts")
< .desc("number of float instructions")
< ;
---
> t_info.numCondCtrlInsts
> .name(thread_str + ".num_conditional_control_insts")
> .desc("number of instructions that are conditional controls")
> ;
191,194c264,267
< numIntRegReads
< .name(name() + ".num_int_register_reads")
< .desc("number of times the integer registers were read")
< ;
---
> t_info.numIntInsts
> .name(thread_str + ".num_int_insts")
> .desc("number of integer instructions")
> ;
196,199c269,272
< numIntRegWrites
< .name(name() + ".num_int_register_writes")
< .desc("number of times the integer registers were written")
< ;
---
> t_info.numFpInsts
> .name(thread_str + ".num_fp_insts")
> .desc("number of float instructions")
> ;
201,204c274,277
< numFpRegReads
< .name(name() + ".num_fp_register_reads")
< .desc("number of times the floating registers were read")
< ;
---
> t_info.numIntRegReads
> .name(thread_str + ".num_int_register_reads")
> .desc("number of times the integer registers were read")
> ;
206,209c279,282
< numFpRegWrites
< .name(name() + ".num_fp_register_writes")
< .desc("number of times the floating registers were written")
< ;
---
> t_info.numIntRegWrites
> .name(thread_str + ".num_int_register_writes")
> .desc("number of times the integer registers were written")
> ;
211,215c284,287
< numCCRegReads
< .name(name() + ".num_cc_register_reads")
< .desc("number of times the CC registers were read")
< .flags(nozero)
< ;
---
> t_info.numFpRegReads
> .name(thread_str + ".num_fp_register_reads")
> .desc("number of times the floating registers were read")
> ;
217,221c289,292
< numCCRegWrites
< .name(name() + ".num_cc_register_writes")
< .desc("number of times the CC registers were written")
< .flags(nozero)
< ;
---
> t_info.numFpRegWrites
> .name(thread_str + ".num_fp_register_writes")
> .desc("number of times the floating registers were written")
> ;
223,226c294,298
< numMemRefs
< .name(name()+".num_mem_refs")
< .desc("number of memory refs")
< ;
---
> t_info.numCCRegReads
> .name(thread_str + ".num_cc_register_reads")
> .desc("number of times the CC registers were read")
> .flags(nozero)
> ;
228,231c300,304
< numStoreInsts
< .name(name() + ".num_store_insts")
< .desc("Number of store instructions")
< ;
---
> t_info.numCCRegWrites
> .name(thread_str + ".num_cc_register_writes")
> .desc("number of times the CC registers were written")
> .flags(nozero)
> ;
233,236c306,309
< numLoadInsts
< .name(name() + ".num_load_insts")
< .desc("Number of load instructions")
< ;
---
> t_info.numMemRefs
> .name(thread_str + ".num_mem_refs")
> .desc("number of memory refs")
> ;
238,241c311,314
< notIdleFraction
< .name(name() + ".not_idle_fraction")
< .desc("Percentage of non-idle cycles")
< ;
---
> t_info.numStoreInsts
> .name(thread_str + ".num_store_insts")
> .desc("Number of store instructions")
> ;
243,246c316,319
< idleFraction
< .name(name() + ".idle_fraction")
< .desc("Percentage of idle cycles")
< ;
---
> t_info.numLoadInsts
> .name(thread_str + ".num_load_insts")
> .desc("Number of load instructions")
> ;
248,251c321,324
< numBusyCycles
< .name(name() + ".num_busy_cycles")
< .desc("Number of busy cycles")
< ;
---
> t_info.notIdleFraction
> .name(thread_str + ".not_idle_fraction")
> .desc("Percentage of non-idle cycles")
> ;
253,256c326,329
< numIdleCycles
< .name(name()+".num_idle_cycles")
< .desc("Number of idle cycles")
< ;
---
> t_info.idleFraction
> .name(thread_str + ".idle_fraction")
> .desc("Percentage of idle cycles")
> ;
258,262c331,334
< icacheStallCycles
< .name(name() + ".icache_stall_cycles")
< .desc("ICache total stall cycles")
< .prereq(icacheStallCycles)
< ;
---
> t_info.numBusyCycles
> .name(thread_str + ".num_busy_cycles")
> .desc("Number of busy cycles")
> ;
264,268c336,339
< dcacheStallCycles
< .name(name() + ".dcache_stall_cycles")
< .desc("DCache total stall cycles")
< .prereq(dcacheStallCycles)
< ;
---
> t_info.numIdleCycles
> .name(thread_str + ".num_idle_cycles")
> .desc("Number of idle cycles")
> ;
270,278c341,345
< statExecutedInstType
< .init(Enums::Num_OpClass)
< .name(name() + ".op_class")
< .desc("Class of executed instruction")
< .flags(total | pdf | dist)
< ;
< for (unsigned i = 0; i < Num_OpClasses; ++i) {
< statExecutedInstType.subname(i, Enums::OpClassStrings[i]);
< }
---
> t_info.icacheStallCycles
> .name(thread_str + ".icache_stall_cycles")
> .desc("ICache total stall cycles")
> .prereq(t_info.icacheStallCycles)
> ;
280,282c347,351
< idleFraction = constant(1.0) - notIdleFraction;
< numIdleCycles = idleFraction * numCycles;
< numBusyCycles = (notIdleFraction)*numCycles;
---
> t_info.dcacheStallCycles
> .name(thread_str + ".dcache_stall_cycles")
> .desc("DCache total stall cycles")
> .prereq(t_info.dcacheStallCycles)
> ;
284,287c353,358
< numBranches
< .name(name() + ".Branches")
< .desc("Number of branches fetched")
< .prereq(numBranches);
---
> t_info.statExecutedInstType
> .init(Enums::Num_OpClass)
> .name(thread_str + ".op_class")
> .desc("Class of executed instruction")
> .flags(total | pdf | dist)
> ;
289,292c360,362
< numPredictedBranches
< .name(name() + ".predictedBranches")
< .desc("Number of branches predicted as taken")
< .prereq(numPredictedBranches);
---
> for (unsigned i = 0; i < Num_OpClasses; ++i) {
> t_info.statExecutedInstType.subname(i, Enums::OpClassStrings[i]);
> }
294,297c364,382
< numBranchMispred
< .name(name() + ".BranchMispred")
< .desc("Number of branch mispredictions")
< .prereq(numBranchMispred);
---
> t_info.idleFraction = constant(1.0) - t_info.notIdleFraction;
> t_info.numIdleCycles = t_info.idleFraction * numCycles;
> t_info.numBusyCycles = t_info.notIdleFraction * numCycles;
>
> t_info.numBranches
> .name(thread_str + ".Branches")
> .desc("Number of branches fetched")
> .prereq(t_info.numBranches);
>
> t_info.numPredictedBranches
> .name(thread_str + ".predictedBranches")
> .desc("Number of branches predicted as taken")
> .prereq(t_info.numPredictedBranches);
>
> t_info.numBranchMispred
> .name(thread_str + ".BranchMispred")
> .desc("Number of branch mispredictions")
> .prereq(t_info.numBranchMispred);
> }
303,304c388,390
< // startNumInst = numInst;
< notIdleFraction = (_status != Idle);
---
> for (auto &thread_info : threadInfo) {
> thread_info->notIdleFraction = (_status != Idle);
> }
311d396
< assert(tid == 0);
313c398
< thread->serialize(cp);
---
> threadInfo[tid]->thread->serialize(cp);
319,321c404
< if (tid != 0)
< fatal("Trying to load more than one thread into a SimpleCPU\n");
< thread->unserialize(cp);
---
> threadInfo[tid]->thread->unserialize(cp);
332c415
< return vtophys(tc, addr);
---
> return vtophys(threadContexts[curThread], addr);
338c421
< getAddrMonitor()->gotWakeup = true;
---
> getCpuAddrMonitor()->gotWakeup = true;
340,344c423,428
< if (thread->status() != ThreadContext::Suspended)
< return;
<
< DPRINTF(Quiesce,"Suspended Processor awoke\n");
< thread->activate();
---
> for (ThreadID tid = 0; tid < numThreads; tid++) {
> if (threadInfo[tid]->thread->status() == ThreadContext::Suspended) {
> DPRINTF(Quiesce,"Suspended Processor awoke\n");
> threadInfo[tid]->thread->activate();
> }
> }
349a434,437
> SimpleExecContext&t_info = *threadInfo[curThread];
> SimpleThread* thread = t_info.thread;
> ThreadContext* tc = thread->getTC();
>
354c442
< fetchOffset = 0;
---
> t_info.fetchOffset = 0;
365a454,456
> SimpleExecContext &t_info = *threadInfo[curThread];
> SimpleThread* thread = t_info.thread;
>
371c462
< Addr fetchPC = (instAddr & PCMask) + fetchOffset;
---
> Addr fetchPC = (instAddr & PCMask) + t_info.fetchOffset;
379a471,473
> SimpleExecContext &t_info = *threadInfo[curThread];
> SimpleThread* thread = t_info.thread;
>
387c481
< comInstEventQueue[0]->serviceEvents(numInst);
---
> comInstEventQueue[curThread]->serviceEvents(t_info.numInst);
396c490
< stayAtPC = false;
---
> t_info.stayAtPC = false;
407c501
< Addr fetchPC = (pcState.instAddr() & PCMask) + fetchOffset;
---
> Addr fetchPC = (pcState.instAddr() & PCMask) + t_info.fetchOffset;
417c511
< stayAtPC = false;
---
> t_info.stayAtPC = false;
420,421c514,515
< stayAtPC = true;
< fetchOffset += sizeof(MachInst);
---
> t_info.stayAtPC = true;
> t_info.fetchOffset += sizeof(MachInst);
428c522,523
< curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
---
> curStaticInst =
> curMacroStaticInst->fetchMicroop(pcState.microPC());
440c535
< traceData = tracer->getInstRecord(curTick(), tc,
---
> traceData = tracer->getInstRecord(curTick(), thread->getTC(),
448c543,544
< if (branchPred && curStaticInst && curStaticInst->isControl()) {
---
> if (branchPred && curStaticInst &&
> curStaticInst->isControl()) {
452,453c548
< const ThreadID tid(0);
< pred_pc = thread->pcState();
---
> t_info.predPC = thread->pcState();
455c550,551
< branchPred->predict(curStaticInst, cur_sn, pred_pc, tid));
---
> branchPred->predict(curStaticInst, cur_sn, t_info.predPC,
> curThread));
458c554
< ++numPredictedBranches;
---
> ++t_info.numPredictedBranches;
464a561,563
> SimpleExecContext &t_info = *threadInfo[curThread];
> SimpleThread* thread = t_info.thread;
>
467c566
< TheISA::PCState pc = tc->pcState();
---
> TheISA::PCState pc = threadContexts[curThread]->pcState();
470c569
< bool usermode = TheISA::inUserMode(tc);
---
> bool usermode = TheISA::inUserMode(threadContexts[curThread]);
472c571,572
< ProfileNode *node = thread->profile->consume(tc, curStaticInst);
---
> ProfileNode *node = thread->profile->consume(threadContexts[curThread],
> curStaticInst);
478c578
< numMemRefs++;
---
> t_info.numMemRefs++;
482,483c582,583
< ++numLoad;
< comLoadEventQueue[0]->serviceEvents(numLoad);
---
> ++t_info.numLoad;
> comLoadEventQueue[curThread]->serviceEvents(t_info.numLoad);
487c587
< CPA::cpa()->swAutoBegin(tc, pc.nextInstAddr());
---
> CPA::cpa()->swAutoBegin(threadContexts[curThread], pc.nextInstAddr());
491c591
< ++numBranches;
---
> ++t_info.numBranches;
497,498c597,598
< numIntAluAccesses++;
< numIntInsts++;
---
> t_info.numIntAluAccesses++;
> t_info.numIntInsts++;
503,504c603,604
< numFpAluAccesses++;
< numFpInsts++;
---
> t_info.numFpAluAccesses++;
> t_info.numFpInsts++;
506c606
<
---
>
509c609
< numCallsReturns++;
---
> t_info.numCallsReturns++;
511c611
<
---
>
514c614
< numCondCtrlInsts++;
---
> t_info.numCondCtrlInsts++;
516c616
<
---
>
519c619
< numLoadInsts++;
---
> t_info.numLoadInsts++;
521c621
<
---
>
523c623
< numStoreInsts++;
---
> t_info.numStoreInsts++;
527c627
< statExecutedInstType[curStaticInst->opClass()]++;
---
> t_info.statExecutedInstType[curStaticInst->opClass()]++;
544a645,647
> SimpleExecContext &t_info = *threadInfo[curThread];
> SimpleThread* thread = t_info.thread;
>
548c651
< fetchOffset = 0;
---
> t_info.fetchOffset = 0;
551c654
< fault->invoke(tc, curStaticInst);
---
> fault->invoke(threadContexts[curThread], curStaticInst);
567d669
< const ThreadID tid(0);
569c671
< if (pred_pc == thread->pcState()) {
---
> if (t_info.predPC == thread->pcState()) {
571c673
< branchPred->update(cur_sn, tid);
---
> branchPred->update(cur_sn, curThread);
574,576c676,677
< branchPred->squash(cur_sn, pcState(),
< branching, tid);
< ++numBranchMispred;
---
> branchPred->squash(cur_sn, thread->pcState(), branching, curThread);
> ++t_info.numBranchMispred;
585c686,687
< thread->startup();
---
> for (auto& t_info : threadInfo)
> t_info->thread->startup();