gem5  v20.1.0.0
cpu.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2012, 2014, 2016, 2017, 2019-2020 ARM Limited
3  * Copyright (c) 2013 Advanced Micro Devices, Inc.
4  * All rights reserved
5  *
6  * The license below extends only to copyright in the software and shall
7  * not be construed as granting a license to any other intellectual
8  * property including but not limited to intellectual property relating
9  * to a hardware implementation of the functionality of the software
10  * licensed hereunder. You may use the software subject to the license
11  * terms below provided that you ensure that this notice is replicated
12  * unmodified and in its entirety in all distributions of the software,
13  * modified or unmodified, in source code or in binary form.
14  *
15  * Copyright (c) 2004-2006 The Regents of The University of Michigan
16  * Copyright (c) 2011 Regents of the University of California
17  * All rights reserved.
18  *
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions are
21  * met: redistributions of source code must retain the above copyright
22  * notice, this list of conditions and the following disclaimer;
23  * redistributions in binary form must reproduce the above copyright
24  * notice, this list of conditions and the following disclaimer in the
25  * documentation and/or other materials provided with the distribution;
26  * neither the name of the copyright holders nor the names of its
27  * contributors may be used to endorse or promote products derived from
28  * this software without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41  */
42 
43 #include "cpu/o3/cpu.hh"
44 
45 #include "arch/generic/traits.hh"
46 #include "config/the_isa.hh"
47 #include "cpu/activity.hh"
48 #include "cpu/checker/cpu.hh"
50 #include "cpu/o3/isa_specific.hh"
51 #include "cpu/o3/thread_context.hh"
52 #include "cpu/simple_thread.hh"
53 #include "cpu/thread_context.hh"
54 #include "debug/Activity.hh"
55 #include "debug/Drain.hh"
56 #include "debug/O3CPU.hh"
57 #include "debug/Quiesce.hh"
58 #include "enums/MemoryMode.hh"
59 #include "sim/core.hh"
60 #include "sim/full_system.hh"
61 #include "sim/process.hh"
62 #include "sim/stat_control.hh"
63 #include "sim/system.hh"
64 
65 struct BaseCPUParams;
66 
67 using namespace TheISA;
68 using namespace std;
69 
70 BaseO3CPU::BaseO3CPU(BaseCPUParams *params)
71  : BaseCPU(params)
72 {
73 }
74 
75 void
77 {
79 }
80 
81 template <class Impl>
82 FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
83  : BaseO3CPU(params),
84  itb(params->itb),
85  dtb(params->dtb),
86  tickEvent([this]{ tick(); }, "FullO3CPU tick",
87  false, Event::CPU_Tick_Pri),
88  threadExitEvent([this]{ exitThreads(); }, "FullO3CPU exit threads",
89  false, Event::CPU_Exit_Pri),
90 #ifndef NDEBUG
91  instcount(0),
92 #endif
93  removeInstsThisCycle(false),
94  fetch(this, params),
95  decode(this, params),
96  rename(this, params),
97  iew(this, params),
98  commit(this, params),
99 
100  /* It is mandatory that all SMT threads use the same renaming mode as
101  * they are sharing registers and rename */
102  vecMode(RenameMode<TheISA::ISA>::init(params->isa[0])),
103  regFile(params->numPhysIntRegs,
104  params->numPhysFloatRegs,
105  params->numPhysVecRegs,
106  params->numPhysVecPredRegs,
107  params->numPhysCCRegs,
108  vecMode),
109 
110  freeList(name() + ".freelist", &regFile),
111 
112  rob(this, params),
113 
114  scoreboard(name() + ".scoreboard",
115  regFile.totalNumPhysRegs()),
116 
117  isa(numThreads, NULL),
118 
119  timeBuffer(params->backComSize, params->forwardComSize),
120  fetchQueue(params->backComSize, params->forwardComSize),
121  decodeQueue(params->backComSize, params->forwardComSize),
122  renameQueue(params->backComSize, params->forwardComSize),
123  iewQueue(params->backComSize, params->forwardComSize),
124  activityRec(name(), NumStages,
125  params->backComSize + params->forwardComSize,
126  params->activity),
127 
128  globalSeqNum(1),
129  system(params->system),
130  lastRunningCycle(curCycle())
131 {
132  if (!params->switched_out) {
133  _status = Running;
134  } else {
135  _status = SwitchedOut;
136  }
137 
138  if (params->checker) {
139  BaseCPU *temp_checker = params->checker;
140  checker = dynamic_cast<Checker<Impl> *>(temp_checker);
141  checker->setIcachePort(&this->fetch.getInstPort());
142  checker->setSystem(params->system);
143  } else {
144  checker = NULL;
145  }
146 
147  if (!FullSystem) {
148  thread.resize(numThreads);
149  tids.resize(numThreads);
150  }
151 
152  // The stages also need their CPU pointer setup. However this
153  // must be done at the upper level CPU because they have pointers
154  // to the upper level CPU, and not this FullO3CPU.
155 
156  // Set up Pointers to the activeThreads list for each stage
157  fetch.setActiveThreads(&activeThreads);
158  decode.setActiveThreads(&activeThreads);
159  rename.setActiveThreads(&activeThreads);
160  iew.setActiveThreads(&activeThreads);
161  commit.setActiveThreads(&activeThreads);
162 
163  // Give each of the stages the time buffer they will use.
164  fetch.setTimeBuffer(&timeBuffer);
165  decode.setTimeBuffer(&timeBuffer);
166  rename.setTimeBuffer(&timeBuffer);
167  iew.setTimeBuffer(&timeBuffer);
168  commit.setTimeBuffer(&timeBuffer);
169 
170  // Also setup each of the stages' queues.
171  fetch.setFetchQueue(&fetchQueue);
172  decode.setFetchQueue(&fetchQueue);
173  commit.setFetchQueue(&fetchQueue);
174  decode.setDecodeQueue(&decodeQueue);
175  rename.setDecodeQueue(&decodeQueue);
176  rename.setRenameQueue(&renameQueue);
177  iew.setRenameQueue(&renameQueue);
178  iew.setIEWQueue(&iewQueue);
179  commit.setIEWQueue(&iewQueue);
180  commit.setRenameQueue(&renameQueue);
181 
182  commit.setIEWStage(&iew);
183  rename.setIEWStage(&iew);
184  rename.setCommitStage(&commit);
185 
186  ThreadID active_threads;
187  if (FullSystem) {
188  active_threads = 1;
189  } else {
190  active_threads = params->workload.size();
191 
192  if (active_threads > Impl::MaxThreads) {
193  panic("Workload Size too large. Increase the 'MaxThreads' "
194  "constant in your O3CPU impl. file (e.g. o3/alpha/impl.hh) "
195  "or edit your workload size.");
196  }
197  }
198 
199  //Make Sure That this a Valid Architeture
200  assert(params->numPhysIntRegs >= numThreads * TheISA::NumIntRegs);
201  assert(params->numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs);
202  assert(params->numPhysVecRegs >= numThreads * TheISA::NumVecRegs);
203  assert(params->numPhysVecPredRegs >= numThreads * TheISA::NumVecPredRegs);
204  assert(params->numPhysCCRegs >= numThreads * TheISA::NumCCRegs);
205 
206  rename.setScoreboard(&scoreboard);
207  iew.setScoreboard(&scoreboard);
208 
209  // Setup the rename map for whichever stages need it.
210  for (ThreadID tid = 0; tid < numThreads; tid++) {
211  isa[tid] = dynamic_cast<TheISA::ISA *>(params->isa[tid]);
212  assert(isa[tid]);
213  assert(RenameMode<TheISA::ISA>::equalsInit(isa[tid], isa[0]));
214 
215  // Only Alpha has an FP zero register, so for other ISAs we
216  // use an invalid FP register index to avoid special treatment
217  // of any valid FP reg.
218  RegIndex invalidFPReg = TheISA::NumFloatRegs + 1;
219 
220  commitRenameMap[tid].init(&regFile, TheISA::ZeroReg, invalidFPReg,
221  &freeList, vecMode);
222 
223  renameMap[tid].init(&regFile, TheISA::ZeroReg, invalidFPReg,
224  &freeList, vecMode);
225  }
226 
227  // Initialize rename map to assign physical registers to the
228  // architectural registers for active threads only.
229  for (ThreadID tid = 0; tid < active_threads; tid++) {
230  for (RegIndex ridx = 0; ridx < TheISA::NumIntRegs; ++ridx) {
231  // Note that we can't use the rename() method because we don't
232  // want special treatment for the zero register at this point
233  PhysRegIdPtr phys_reg = freeList.getIntReg();
234  renameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg);
235  commitRenameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg);
236  }
237 
238  for (RegIndex ridx = 0; ridx < TheISA::NumFloatRegs; ++ridx) {
239  PhysRegIdPtr phys_reg = freeList.getFloatReg();
240  renameMap[tid].setEntry(RegId(FloatRegClass, ridx), phys_reg);
241  commitRenameMap[tid].setEntry(
242  RegId(FloatRegClass, ridx), phys_reg);
243  }
244 
245  /* Here we need two 'interfaces' the 'whole register' and the
246  * 'register element'. At any point only one of them will be
247  * active. */
248  if (vecMode == Enums::Full) {
249  /* Initialize the full-vector interface */
250  for (RegIndex ridx = 0; ridx < TheISA::NumVecRegs; ++ridx) {
251  RegId rid = RegId(VecRegClass, ridx);
252  PhysRegIdPtr phys_reg = freeList.getVecReg();
253  renameMap[tid].setEntry(rid, phys_reg);
254  commitRenameMap[tid].setEntry(rid, phys_reg);
255  }
256  } else {
257  /* Initialize the vector-element interface */
258  for (RegIndex ridx = 0; ridx < TheISA::NumVecRegs; ++ridx) {
259  for (ElemIndex ldx = 0; ldx < TheISA::NumVecElemPerVecReg;
260  ++ldx) {
261  RegId lrid = RegId(VecElemClass, ridx, ldx);
262  PhysRegIdPtr phys_elem = freeList.getVecElem();
263  renameMap[tid].setEntry(lrid, phys_elem);
264  commitRenameMap[tid].setEntry(lrid, phys_elem);
265  }
266  }
267  }
268 
269  for (RegIndex ridx = 0; ridx < TheISA::NumVecPredRegs; ++ridx) {
270  PhysRegIdPtr phys_reg = freeList.getVecPredReg();
271  renameMap[tid].setEntry(RegId(VecPredRegClass, ridx), phys_reg);
272  commitRenameMap[tid].setEntry(
273  RegId(VecPredRegClass, ridx), phys_reg);
274  }
275 
276  for (RegIndex ridx = 0; ridx < TheISA::NumCCRegs; ++ridx) {
277  PhysRegIdPtr phys_reg = freeList.getCCReg();
278  renameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg);
279  commitRenameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg);
280  }
281  }
282 
283  rename.setRenameMap(renameMap);
284  commit.setRenameMap(commitRenameMap);
285  rename.setFreeList(&freeList);
286 
287  // Setup the ROB for whichever stages need it.
288  commit.setROB(&rob);
289 
290  lastActivatedCycle = 0;
291 
292  DPRINTF(O3CPU, "Creating O3CPU object.\n");
293 
294  // Setup any thread state.
295  this->thread.resize(this->numThreads);
296 
297  for (ThreadID tid = 0; tid < this->numThreads; ++tid) {
298  if (FullSystem) {
299  // SMT is not supported in FS mode yet.
300  assert(this->numThreads == 1);
301  this->thread[tid] = new Thread(this, 0, NULL);
302  } else {
303  if (tid < params->workload.size()) {
304  DPRINTF(O3CPU, "Workload[%i] process is %#x",
305  tid, this->thread[tid]);
306  this->thread[tid] = new typename FullO3CPU<Impl>::Thread(
307  (typename Impl::O3CPU *)(this),
308  tid, params->workload[tid]);
309 
310  //usedTids[tid] = true;
311  //threadMap[tid] = tid;
312  } else {
313  //Allocate Empty thread so M5 can use later
314  //when scheduling threads to CPU
315  Process* dummy_proc = NULL;
316 
317  this->thread[tid] = new typename FullO3CPU<Impl>::Thread(
318  (typename Impl::O3CPU *)(this),
319  tid, dummy_proc);
320  //usedTids[tid] = false;
321  }
322  }
323 
324  ThreadContext *tc;
325 
326  // Setup the TC that will serve as the interface to the threads/CPU.
328 
329  tc = o3_tc;
330 
331  // If we're using a checker, then the TC should be the
332  // CheckerThreadContext.
333  if (params->checker) {
335  o3_tc, this->checker);
336  }
337 
338  o3_tc->cpu = (typename Impl::O3CPU *)(this);
339  assert(o3_tc->cpu);
340  o3_tc->thread = this->thread[tid];
341 
342  // Give the thread the TC.
343  this->thread[tid]->tc = tc;
344 
345  // Add the TC to the CPU's list of TC's.
346  this->threadContexts.push_back(tc);
347  }
348 
349  // FullO3CPU always requires an interrupt controller.
350  if (!params->switched_out && interrupts.empty()) {
351  fatal("FullO3CPU %s has no interrupt controller.\n"
352  "Ensure createInterruptController() is called.\n", name());
353  }
354 
355  for (ThreadID tid = 0; tid < this->numThreads; tid++)
356  this->thread[tid]->setFuncExeInst(0);
357 }
358 
359 template <class Impl>
361 {
362 }
363 
364 template <class Impl>
365 void
367 {
369 
370  ppInstAccessComplete = new ProbePointArg<PacketPtr>(getProbeManager(), "InstAccessComplete");
371  ppDataAccessComplete = new ProbePointArg<std::pair<DynInstPtr, PacketPtr> >(getProbeManager(), "DataAccessComplete");
372 
373  fetch.regProbePoints();
374  rename.regProbePoints();
375  iew.regProbePoints();
376  commit.regProbePoints();
377 }
378 
379 template <class Impl>
380 void
382 {
384 
385  // Register any of the O3CPU's stats here.
386  timesIdled
387  .name(name() + ".timesIdled")
388  .desc("Number of times that the entire CPU went into an idle state and"
389  " unscheduled itself")
390  .prereq(timesIdled);
391 
392  idleCycles
393  .name(name() + ".idleCycles")
394  .desc("Total number of cycles that the CPU has spent unscheduled due "
395  "to idling")
396  .prereq(idleCycles);
397 
399  .name(name() + ".quiesceCycles")
400  .desc("Total number of cycles that CPU has spent quiesced or waiting "
401  "for an interrupt")
402  .prereq(quiesceCycles);
403 
404  // Number of Instructions simulated
405  // --------------------------------
406  // Should probably be in Base CPU but need templated
407  // MaxThreads so put in here instead
408  committedInsts
409  .init(numThreads)
410  .name(name() + ".committedInsts")
411  .desc("Number of Instructions Simulated")
412  .flags(Stats::total);
413 
414  committedOps
415  .init(numThreads)
416  .name(name() + ".committedOps")
417  .desc("Number of Ops (including micro ops) Simulated")
418  .flags(Stats::total);
419 
420  cpi
421  .name(name() + ".cpi")
422  .desc("CPI: Cycles Per Instruction")
423  .precision(6);
424  cpi = numCycles / committedInsts;
425 
426  totalCpi
427  .name(name() + ".cpi_total")
428  .desc("CPI: Total CPI of All Threads")
429  .precision(6);
430  totalCpi = numCycles / sum(committedInsts);
431 
432  ipc
433  .name(name() + ".ipc")
434  .desc("IPC: Instructions Per Cycle")
435  .precision(6);
436  ipc = committedInsts / numCycles;
437 
438  totalIpc
439  .name(name() + ".ipc_total")
440  .desc("IPC: Total IPC of All Threads")
441  .precision(6);
442  totalIpc = sum(committedInsts) / numCycles;
443 
444  this->iew.regStats();
445 
446  intRegfileReads
447  .name(name() + ".int_regfile_reads")
448  .desc("number of integer regfile reads")
449  .prereq(intRegfileReads);
450 
451  intRegfileWrites
452  .name(name() + ".int_regfile_writes")
453  .desc("number of integer regfile writes")
454  .prereq(intRegfileWrites);
455 
456  fpRegfileReads
457  .name(name() + ".fp_regfile_reads")
458  .desc("number of floating regfile reads")
459  .prereq(fpRegfileReads);
460 
461  fpRegfileWrites
462  .name(name() + ".fp_regfile_writes")
463  .desc("number of floating regfile writes")
464  .prereq(fpRegfileWrites);
465 
466  vecRegfileReads
467  .name(name() + ".vec_regfile_reads")
468  .desc("number of vector regfile reads")
469  .prereq(vecRegfileReads);
470 
471  vecRegfileWrites
472  .name(name() + ".vec_regfile_writes")
473  .desc("number of vector regfile writes")
474  .prereq(vecRegfileWrites);
475 
476  vecPredRegfileReads
477  .name(name() + ".pred_regfile_reads")
478  .desc("number of predicate regfile reads")
479  .prereq(vecPredRegfileReads);
480 
481  vecPredRegfileWrites
482  .name(name() + ".pred_regfile_writes")
483  .desc("number of predicate regfile writes")
484  .prereq(vecPredRegfileWrites);
485 
486  ccRegfileReads
487  .name(name() + ".cc_regfile_reads")
488  .desc("number of cc regfile reads")
489  .prereq(ccRegfileReads);
490 
491  ccRegfileWrites
492  .name(name() + ".cc_regfile_writes")
493  .desc("number of cc regfile writes")
494  .prereq(ccRegfileWrites);
495 
496  miscRegfileReads
497  .name(name() + ".misc_regfile_reads")
498  .desc("number of misc regfile reads")
499  .prereq(miscRegfileReads);
500 
501  miscRegfileWrites
502  .name(name() + ".misc_regfile_writes")
503  .desc("number of misc regfile writes")
504  .prereq(miscRegfileWrites);
505 }
506 
507 template <class Impl>
508 void
510 {
511  DPRINTF(O3CPU, "\n\nFullO3CPU: Ticking main, FullO3CPU.\n");
512  assert(!switchedOut());
513  assert(drainState() != DrainState::Drained);
514 
515  ++numCycles;
516  updateCycleCounters(BaseCPU::CPU_STATE_ON);
517 
518 // activity = false;
519 
520  //Tick each of the stages
521  fetch.tick();
522 
523  decode.tick();
524 
525  rename.tick();
526 
527  iew.tick();
528 
529  commit.tick();
530 
531  // Now advance the time buffers
532  timeBuffer.advance();
533 
534  fetchQueue.advance();
535  decodeQueue.advance();
536  renameQueue.advance();
537  iewQueue.advance();
538 
539  activityRec.advance();
540 
541  if (removeInstsThisCycle) {
542  cleanUpRemovedInsts();
543  }
544 
545  if (!tickEvent.scheduled()) {
546  if (_status == SwitchedOut) {
547  DPRINTF(O3CPU, "Switched out!\n");
548  // increment stat
549  lastRunningCycle = curCycle();
550  } else if (!activityRec.active() || _status == Idle) {
551  DPRINTF(O3CPU, "Idle!\n");
552  lastRunningCycle = curCycle();
553  timesIdled++;
554  } else {
555  schedule(tickEvent, clockEdge(Cycles(1)));
556  DPRINTF(O3CPU, "Scheduling next tick!\n");
557  }
558  }
559 
560  if (!FullSystem)
561  updateThreadPriority();
562 
563  tryDrain();
564 }
565 
566 template <class Impl>
567 void
569 {
570  BaseCPU::init();
571 
572  for (ThreadID tid = 0; tid < numThreads; ++tid) {
573  // Set noSquashFromTC so that the CPU doesn't squash when initially
574  // setting up registers.
575  thread[tid]->noSquashFromTC = true;
576  // Initialise the ThreadContext's memory proxies
577  thread[tid]->initMemProxies(thread[tid]->getTC());
578  }
579 
580  // Clear noSquashFromTC.
581  for (int tid = 0; tid < numThreads; ++tid)
582  thread[tid]->noSquashFromTC = false;
583 
584  commit.setThreads(thread);
585 }
586 
587 template <class Impl>
588 void
590 {
592 
593  fetch.startupStage();
594  decode.startupStage();
595  iew.startupStage();
596  rename.startupStage();
597  commit.startupStage();
598 }
599 
600 template <class Impl>
601 void
603 {
604  list<ThreadID>::iterator isActive =
605  std::find(activeThreads.begin(), activeThreads.end(), tid);
606 
607  DPRINTF(O3CPU, "[tid:%i] Calling activate thread.\n", tid);
608  assert(!switchedOut());
609 
610  if (isActive == activeThreads.end()) {
611  DPRINTF(O3CPU, "[tid:%i] Adding to active threads list\n",
612  tid);
613 
614  activeThreads.push_back(tid);
615  }
616 }
617 
618 template <class Impl>
619 void
621 {
622  // hardware transactional memory
623  // shouldn't deactivate thread in the middle of a transaction
624  assert(!commit.executingHtmTransaction(tid));
625 
626  //Remove From Active List, if Active
627  list<ThreadID>::iterator thread_it =
628  std::find(activeThreads.begin(), activeThreads.end(), tid);
629 
630  DPRINTF(O3CPU, "[tid:%i] Calling deactivate thread.\n", tid);
631  assert(!switchedOut());
632 
633  if (thread_it != activeThreads.end()) {
634  DPRINTF(O3CPU,"[tid:%i] Removing from active threads list\n",
635  tid);
636  activeThreads.erase(thread_it);
637  }
638 
639  fetch.deactivateThread(tid);
640  commit.deactivateThread(tid);
641 }
642 
643 template <class Impl>
644 Counter
646 {
647  Counter total(0);
648 
649  ThreadID size = thread.size();
650  for (ThreadID i = 0; i < size; i++)
651  total += thread[i]->numInst;
652 
653  return total;
654 }
655 
656 template <class Impl>
657 Counter
659 {
660  Counter total(0);
661 
662  ThreadID size = thread.size();
663  for (ThreadID i = 0; i < size; i++)
664  total += thread[i]->numOp;
665 
666  return total;
667 }
668 
669 template <class Impl>
670 void
672 {
673  assert(!switchedOut());
674 
675  // Needs to set each stage to running as well.
676  activateThread(tid);
677 
678  // We don't want to wake the CPU if it is drained. In that case,
679  // we just want to flag the thread as active and schedule the tick
680  // event from drainResume() instead.
681  if (drainState() == DrainState::Drained)
682  return;
683 
684  // If we are time 0 or if the last activation time is in the past,
685  // schedule the next tick and wake up the fetch unit
686  if (lastActivatedCycle == 0 || lastActivatedCycle < curTick()) {
687  scheduleTickEvent(Cycles(0));
688 
689  // Be sure to signal that there's some activity so the CPU doesn't
690  // deschedule itself.
691  activityRec.activity();
692  fetch.wakeFromQuiesce();
693 
694  Cycles cycles(curCycle() - lastRunningCycle);
695  // @todo: This is an oddity that is only here to match the stats
696  if (cycles != 0)
697  --cycles;
698  quiesceCycles += cycles;
699 
700  lastActivatedCycle = curTick();
701 
702  _status = Running;
703 
705  }
706 }
707 
708 template <class Impl>
709 void
711 {
712  DPRINTF(O3CPU,"[tid:%i] Suspending Thread Context.\n", tid);
713  assert(!switchedOut());
714 
715  deactivateThread(tid);
716 
717  // If this was the last thread then unschedule the tick event.
718  if (activeThreads.size() == 0) {
719  unscheduleTickEvent();
720  lastRunningCycle = curCycle();
721  _status = Idle;
722  }
723 
724  DPRINTF(Quiesce, "Suspending Context\n");
725 
727 }
728 
729 template <class Impl>
730 void
732 {
733  //For now, this is the same as deallocate
734  DPRINTF(O3CPU,"[tid:%i] Halt Context called. Deallocating\n", tid);
735  assert(!switchedOut());
736 
737  deactivateThread(tid);
738  removeThread(tid);
739 
740  updateCycleCounters(BaseCPU::CPU_STATE_SLEEP);
741 }
742 
743 template <class Impl>
744 void
746 {
747  DPRINTF(O3CPU,"[tid:%i] Initializing thread into CPU");
748  // Will change now that the PC and thread state is internal to the CPU
749  // and not in the ThreadContext.
750  ThreadContext *src_tc;
751  if (FullSystem)
752  src_tc = system->threads[tid];
753  else
754  src_tc = tcBase(tid);
755 
756  //Bind Int Regs to Rename Map
757 
758  for (RegId reg_id(IntRegClass, 0); reg_id.index() < TheISA::NumIntRegs;
759  reg_id.index()++) {
760  PhysRegIdPtr phys_reg = freeList.getIntReg();
761  renameMap[tid].setEntry(reg_id, phys_reg);
762  scoreboard.setReg(phys_reg);
763  }
764 
765  //Bind Float Regs to Rename Map
766  for (RegId reg_id(FloatRegClass, 0); reg_id.index() < TheISA::NumFloatRegs;
767  reg_id.index()++) {
768  PhysRegIdPtr phys_reg = freeList.getFloatReg();
769  renameMap[tid].setEntry(reg_id, phys_reg);
770  scoreboard.setReg(phys_reg);
771  }
772 
773  //Bind condition-code Regs to Rename Map
774  for (RegId reg_id(CCRegClass, 0); reg_id.index() < TheISA::NumCCRegs;
775  reg_id.index()++) {
776  PhysRegIdPtr phys_reg = freeList.getCCReg();
777  renameMap[tid].setEntry(reg_id, phys_reg);
778  scoreboard.setReg(phys_reg);
779  }
780 
781  //Copy Thread Data Into RegFile
782  //this->copyFromTC(tid);
783 
784  //Set PC/NPC/NNPC
785  pcState(src_tc->pcState(), tid);
786 
788 
789  activateContext(tid);
790 
791  //Reset ROB/IQ/LSQ Entries
792  commit.rob->resetEntries();
793 }
794 
795 template <class Impl>
796 void
798 {
799  DPRINTF(O3CPU,"[tid:%i] Removing thread context from CPU.\n", tid);
800 
801  // Copy Thread Data From RegFile
802  // If thread is suspended, it might be re-allocated
803  // this->copyToTC(tid);
804 
805 
806  // @todo: 2-27-2008: Fix how we free up rename mappings
807  // here to alleviate the case for double-freeing registers
808  // in SMT workloads.
809 
810  // clear all thread-specific states in each stage of the pipeline
811  // since this thread is going to be completely removed from the CPU
812  commit.clearStates(tid);
813  fetch.clearStates(tid);
814  decode.clearStates(tid);
815  rename.clearStates(tid);
816  iew.clearStates(tid);
817 
818  // at this step, all instructions in the pipeline should be already
819  // either committed successfully or squashed. All thread-specific
820  // queues in the pipeline must be empty.
821  assert(iew.instQueue.getCount(tid) == 0);
822  assert(iew.ldstQueue.getCount(tid) == 0);
823  assert(commit.rob->isEmpty(tid));
824 
825  // Reset ROB/IQ/LSQ Entries
826 
827  // Commented out for now. This should be possible to do by
828  // telling all the pipeline stages to drain first, and then
829  // checking until the drain completes. Once the pipeline is
830  // drained, call resetEntries(). - 10-09-06 ktlim
831 /*
832  if (activeThreads.size() >= 1) {
833  commit.rob->resetEntries();
834  iew.resetEntries();
835  }
836 */
837 }
838 
839 template <class Impl>
840 void
842 {
843  if (vecMode == Enums::Elem) {
844  for (auto v = 0; v < TheISA::NumVecRegs; v++)
845  for (auto e = 0; e < TheISA::NumVecElemPerVecReg; e++)
846  scoreboard.setReg(
847  commitRenameMap[tid].lookup(
848  RegId(VecElemClass, v, e)
849  )
850  );
851  } else if (vecMode == Enums::Full) {
852  for (auto v = 0; v < TheISA::NumVecRegs; v++)
853  scoreboard.setReg(
854  commitRenameMap[tid].lookup(
856  )
857  );
858  }
859 }
860 
861 template <class Impl>
862 void
864 {
865  auto pc = this->pcState(tid);
866 
867  // new_mode is the new vector renaming mode
868  auto new_mode = RenameMode<TheISA::ISA>::mode(pc);
869 
870  // We update vecMode only if there has been a change
871  if (new_mode != vecMode) {
872  vecMode = new_mode;
873 
874  renameMap[tid].switchMode(vecMode);
875  commitRenameMap[tid].switchMode(vecMode);
876  renameMap[tid].switchFreeList(freelist);
877  setVectorsAsReady(tid);
878  }
879 }
880 
881 template <class Impl>
882 Fault
884 {
885  // Check if there are any outstanding interrupts
886  return this->interrupts[0]->getInterrupt();
887 }
888 
889 template <class Impl>
890 void
892 {
893  // Check for interrupts here. For now can copy the code that
894  // exists within isa_fullsys_traits.hh. Also assume that thread 0
895  // is the one that handles the interrupts.
896  // @todo: Possibly consolidate the interrupt checking code.
897  // @todo: Allow other threads to handle interrupts.
898 
899  assert(interrupt != NoFault);
900  this->interrupts[0]->updateIntrInfo();
901 
902  DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
903  this->trap(interrupt, 0, nullptr);
904 }
905 
906 template <class Impl>
907 void
909  const StaticInstPtr &inst)
910 {
911  // Pass the thread's TC into the invoke method.
912  fault->invoke(this->threadContexts[tid], inst);
913 }
914 
915 template <class Impl>
916 void
918 {
919  DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
920 
921  DPRINTF(Activity,"Activity: syscall() called.\n");
922 
923  // Temporarily increase this by one to account for the syscall
924  // instruction.
925  ++(this->thread[tid]->funcExeInst);
926 
927  // Execute the actual syscall.
928  this->thread[tid]->syscall();
929 
930  // Decrease funcExeInst by one as the normal commit will handle
931  // incrementing it.
932  --(this->thread[tid]->funcExeInst);
933 }
934 
935 template <class Impl>
936 void
938 {
939  thread[tid]->serialize(cp);
940 }
941 
942 template <class Impl>
943 void
945 {
946  thread[tid]->unserialize(cp);
947 }
948 
949 template <class Impl>
952 {
953  // Deschedule any power gating event (if any)
954  deschedulePowerGatingEvent();
955 
956  // If the CPU isn't doing anything, then return immediately.
957  if (switchedOut())
958  return DrainState::Drained;
959 
960  DPRINTF(Drain, "Draining...\n");
961 
962  // We only need to signal a drain to the commit stage as this
963  // initiates squashing controls the draining. Once the commit
964  // stage commits an instruction where it is safe to stop, it'll
965  // squash the rest of the instructions in the pipeline and force
966  // the fetch stage to stall. The pipeline will be drained once all
967  // in-flight instructions have retired.
968  commit.drain();
969 
970  // Wake the CPU and record activity so everything can drain out if
971  // the CPU was not able to immediately drain.
972  if (!isCpuDrained()) {
973  // If a thread is suspended, wake it up so it can be drained
974  for (auto t : threadContexts) {
975  if (t->status() == ThreadContext::Suspended){
976  DPRINTF(Drain, "Currently suspended so activate %i \n",
977  t->threadId());
978  t->activate();
979  // As the thread is now active, change the power state as well
980  activateContext(t->threadId());
981  }
982  }
983 
984  wakeCPU();
985  activityRec.activity();
986 
987  DPRINTF(Drain, "CPU not drained\n");
988 
989  return DrainState::Draining;
990  } else {
991  DPRINTF(Drain, "CPU is already drained\n");
992  if (tickEvent.scheduled())
993  deschedule(tickEvent);
994 
995  // Flush out any old data from the time buffers. In
996  // particular, there might be some data in flight from the
997  // fetch stage that isn't visible in any of the CPU buffers we
998  // test in isCpuDrained().
999  for (int i = 0; i < timeBuffer.getSize(); ++i) {
1000  timeBuffer.advance();
1001  fetchQueue.advance();
1002  decodeQueue.advance();
1003  renameQueue.advance();
1004  iewQueue.advance();
1005  }
1006 
1007  drainSanityCheck();
1008  return DrainState::Drained;
1009  }
1010 }
1011 
1012 template <class Impl>
1013 bool
1015 {
1016  if (drainState() != DrainState::Draining || !isCpuDrained())
1017  return false;
1018 
1019  if (tickEvent.scheduled())
1020  deschedule(tickEvent);
1021 
1022  DPRINTF(Drain, "CPU done draining, processing drain event\n");
1023  signalDrainDone();
1024 
1025  return true;
1026 }
1027 
1028 template <class Impl>
1029 void
1031 {
1032  assert(isCpuDrained());
1033  fetch.drainSanityCheck();
1034  decode.drainSanityCheck();
1035  rename.drainSanityCheck();
1036  iew.drainSanityCheck();
1037  commit.drainSanityCheck();
1038 }
1039 
1040 template <class Impl>
1041 bool
1043 {
1044  bool drained(true);
1045 
1046  if (!instList.empty() || !removeList.empty()) {
1047  DPRINTF(Drain, "Main CPU structures not drained.\n");
1048  drained = false;
1049  }
1050 
1051  if (!fetch.isDrained()) {
1052  DPRINTF(Drain, "Fetch not drained.\n");
1053  drained = false;
1054  }
1055 
1056  if (!decode.isDrained()) {
1057  DPRINTF(Drain, "Decode not drained.\n");
1058  drained = false;
1059  }
1060 
1061  if (!rename.isDrained()) {
1062  DPRINTF(Drain, "Rename not drained.\n");
1063  drained = false;
1064  }
1065 
1066  if (!iew.isDrained()) {
1067  DPRINTF(Drain, "IEW not drained.\n");
1068  drained = false;
1069  }
1070 
1071  if (!commit.isDrained()) {
1072  DPRINTF(Drain, "Commit not drained.\n");
1073  drained = false;
1074  }
1075 
1076  return drained;
1077 }
1078 
1079 template <class Impl>
1080 void
1082 {
1083  fetch.drainStall(tid);
1084 }
1085 
1086 template <class Impl>
1087 void
1089 {
1090  if (switchedOut())
1091  return;
1092 
1093  DPRINTF(Drain, "Resuming...\n");
1094  verifyMemoryMode();
1095 
1096  fetch.drainResume();
1097  commit.drainResume();
1098 
1099  _status = Idle;
1100  for (ThreadID i = 0; i < thread.size(); i++) {
1101  if (thread[i]->status() == ThreadContext::Active) {
1102  DPRINTF(Drain, "Activating thread: %i\n", i);
1103  activateThread(i);
1104  _status = Running;
1105  }
1106  }
1107 
1108  assert(!tickEvent.scheduled());
1109  if (_status == Running)
1110  schedule(tickEvent, nextCycle());
1111 
1112  // Reschedule any power gating event (if any)
1113  schedulePowerGatingEvent();
1114 }
1115 
1116 template <class Impl>
1117 void
1119 {
1120  DPRINTF(O3CPU, "Switching out\n");
1122 
1123  activityRec.reset();
1124 
1125  _status = SwitchedOut;
1126 
1127  if (checker)
1128  checker->switchOut();
1129 }
1130 
1131 template <class Impl>
1132 void
1134 {
1135  BaseCPU::takeOverFrom(oldCPU);
1136 
1137  fetch.takeOverFrom();
1138  decode.takeOverFrom();
1139  rename.takeOverFrom();
1140  iew.takeOverFrom();
1141  commit.takeOverFrom();
1142 
1143  assert(!tickEvent.scheduled());
1144 
1145  FullO3CPU<Impl> *oldO3CPU = dynamic_cast<FullO3CPU<Impl>*>(oldCPU);
1146  if (oldO3CPU)
1147  globalSeqNum = oldO3CPU->globalSeqNum;
1148 
1149  lastRunningCycle = curCycle();
1150  _status = Idle;
1151 }
1152 
1153 template <class Impl>
1154 void
1156 {
1157  if (!system->isTimingMode()) {
1158  fatal("The O3 CPU requires the memory system to be in "
1159  "'timing' mode.\n");
1160  }
1161 }
1162 
1163 template <class Impl>
1164 RegVal
1166 {
1167  return this->isa[tid]->readMiscRegNoEffect(misc_reg);
1168 }
1169 
1170 template <class Impl>
1171 RegVal
1173 {
1174  miscRegfileReads++;
1175  return this->isa[tid]->readMiscReg(misc_reg);
1176 }
1177 
1178 template <class Impl>
1179 void
1181 {
1182  this->isa[tid]->setMiscRegNoEffect(misc_reg, val);
1183 }
1184 
1185 template <class Impl>
1186 void
1188 {
1189  miscRegfileWrites++;
1190  this->isa[tid]->setMiscReg(misc_reg, val);
1191 }
1192 
1193 template <class Impl>
1194 RegVal
1196 {
1197  intRegfileReads++;
1198  return regFile.readIntReg(phys_reg);
1199 }
1200 
1201 template <class Impl>
1202 RegVal
1204 {
1205  fpRegfileReads++;
1206  return regFile.readFloatReg(phys_reg);
1207 }
1208 
1209 template <class Impl>
1210 auto
1212  -> const VecRegContainer&
1213 {
1214  vecRegfileReads++;
1215  return regFile.readVecReg(phys_reg);
1216 }
1217 
1218 template <class Impl>
1219 auto
1221  -> VecRegContainer&
1222 {
1223  vecRegfileWrites++;
1224  return regFile.getWritableVecReg(phys_reg);
1225 }
1226 
1227 template <class Impl>
1228 auto
1230 {
1231  vecRegfileReads++;
1232  return regFile.readVecElem(phys_reg);
1233 }
1234 
1235 template <class Impl>
1236 auto
1238  -> const VecPredRegContainer&
1239 {
1240  vecPredRegfileReads++;
1241  return regFile.readVecPredReg(phys_reg);
1242 }
1243 
1244 template <class Impl>
1245 auto
1248 {
1249  vecPredRegfileWrites++;
1250  return regFile.getWritableVecPredReg(phys_reg);
1251 }
1252 
1253 template <class Impl>
1254 RegVal
1256 {
1257  ccRegfileReads++;
1258  return regFile.readCCReg(phys_reg);
1259 }
1260 
1261 template <class Impl>
1262 void
1264 {
1265  intRegfileWrites++;
1266  regFile.setIntReg(phys_reg, val);
1267 }
1268 
1269 template <class Impl>
1270 void
1272 {
1273  fpRegfileWrites++;
1274  regFile.setFloatReg(phys_reg, val);
1275 }
1276 
1277 template <class Impl>
1278 void
1280 {
1281  vecRegfileWrites++;
1282  regFile.setVecReg(phys_reg, val);
1283 }
1284 
1285 template <class Impl>
1286 void
1288 {
1289  vecRegfileWrites++;
1290  regFile.setVecElem(phys_reg, val);
1291 }
1292 
1293 template <class Impl>
1294 void
1296  const VecPredRegContainer& val)
1297 {
1298  vecPredRegfileWrites++;
1299  regFile.setVecPredReg(phys_reg, val);
1300 }
1301 
1302 template <class Impl>
1303 void
1305 {
1306  ccRegfileWrites++;
1307  regFile.setCCReg(phys_reg, val);
1308 }
1309 
1310 template <class Impl>
1311 RegVal
1313 {
1314  intRegfileReads++;
1315  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1316  RegId(IntRegClass, reg_idx));
1317 
1318  return regFile.readIntReg(phys_reg);
1319 }
1320 
1321 template <class Impl>
1322 RegVal
1324 {
1325  fpRegfileReads++;
1326  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1327  RegId(FloatRegClass, reg_idx));
1328 
1329  return regFile.readFloatReg(phys_reg);
1330 }
1331 
1332 template <class Impl>
1333 auto
1335  -> const VecRegContainer&
1336 {
1337  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1338  RegId(VecRegClass, reg_idx));
1339  return readVecReg(phys_reg);
1340 }
1341 
1342 template <class Impl>
1343 auto
1345  -> VecRegContainer&
1346 {
1347  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1348  RegId(VecRegClass, reg_idx));
1349  return getWritableVecReg(phys_reg);
1350 }
1351 
1352 template <class Impl>
1353 auto
1355  ThreadID tid) const -> const VecElem&
1356 {
1357  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1358  RegId(VecElemClass, reg_idx, ldx));
1359  return readVecElem(phys_reg);
1360 }
1361 
1362 template <class Impl>
1363 auto
1365  -> const VecPredRegContainer&
1366 {
1367  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1368  RegId(VecPredRegClass, reg_idx));
1369  return readVecPredReg(phys_reg);
1370 }
1371 
1372 template <class Impl>
1373 auto
1376 {
1377  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1378  RegId(VecPredRegClass, reg_idx));
1379  return getWritableVecPredReg(phys_reg);
1380 }
1381 
1382 template <class Impl>
1383 RegVal
1385 {
1386  ccRegfileReads++;
1387  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1388  RegId(CCRegClass, reg_idx));
1389 
1390  return regFile.readCCReg(phys_reg);
1391 }
1392 
1393 template <class Impl>
1394 void
1396 {
1397  intRegfileWrites++;
1398  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1399  RegId(IntRegClass, reg_idx));
1400 
1401  regFile.setIntReg(phys_reg, val);
1402 }
1403 
1404 template <class Impl>
1405 void
1407 {
1408  fpRegfileWrites++;
1409  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1410  RegId(FloatRegClass, reg_idx));
1411 
1412  regFile.setFloatReg(phys_reg, val);
1413 }
1414 
1415 template <class Impl>
1416 void
1418  ThreadID tid)
1419 {
1420  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1421  RegId(VecRegClass, reg_idx));
1422  setVecReg(phys_reg, val);
1423 }
1424 
1425 template <class Impl>
1426 void
1428  const VecElem& val, ThreadID tid)
1429 {
1430  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1431  RegId(VecElemClass, reg_idx, ldx));
1432  setVecElem(phys_reg, val);
1433 }
1434 
1435 template <class Impl>
1436 void
1438  ThreadID tid)
1439 {
1440  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1441  RegId(VecPredRegClass, reg_idx));
1442  setVecPredReg(phys_reg, val);
1443 }
1444 
1445 template <class Impl>
1446 void
1448 {
1449  ccRegfileWrites++;
1450  PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
1451  RegId(CCRegClass, reg_idx));
1452 
1453  regFile.setCCReg(phys_reg, val);
1454 }
1455 
1456 template <class Impl>
1459 {
1460  return commit.pcState(tid);
1461 }
1462 
1463 template <class Impl>
1464 void
1466 {
1467  commit.pcState(val, tid);
1468 }
1469 
1470 template <class Impl>
1471 Addr
1473 {
1474  return commit.instAddr(tid);
1475 }
1476 
1477 template <class Impl>
1478 Addr
1480 {
1481  return commit.nextInstAddr(tid);
1482 }
1483 
1484 template <class Impl>
1485 MicroPC
1487 {
1488  return commit.microPC(tid);
1489 }
1490 
1491 template <class Impl>
1492 void
1494 {
1495  this->thread[tid]->noSquashFromTC = true;
1496  this->commit.generateTCEvent(tid);
1497 }
1498 
1499 template <class Impl>
1500 typename FullO3CPU<Impl>::ListIt
1502 {
1503  instList.push_back(inst);
1504 
1505  return --(instList.end());
1506 }
1507 
1508 template <class Impl>
1509 void
1511 {
1512  // Keep an instruction count.
1513  if (!inst->isMicroop() || inst->isLastMicroop()) {
1514  thread[tid]->numInst++;
1515  thread[tid]->threadStats.numInsts++;
1516  committedInsts[tid]++;
1517  system->totalNumInsts++;
1518 
1519  // Check for instruction-count-based events.
1520  thread[tid]->comInstEventQueue.serviceEvents(thread[tid]->numInst);
1521  }
1522  thread[tid]->numOp++;
1523  thread[tid]->threadStats.numOps++;
1524  committedOps[tid]++;
1525 
1526  probeInstCommit(inst->staticInst, inst->instAddr());
1527 }
1528 
1529 template <class Impl>
1530 void
1532 {
1533  DPRINTF(O3CPU, "Removing committed instruction [tid:%i] PC %s "
1534  "[sn:%lli]\n",
1535  inst->threadNumber, inst->pcState(), inst->seqNum);
1536 
1537  removeInstsThisCycle = true;
1538 
1539  // Remove the front instruction.
1540  removeList.push(inst->getInstListIt());
1541 }
1542 
1543 template <class Impl>
1544 void
1546 {
1547  DPRINTF(O3CPU, "Thread %i: Deleting instructions from instruction"
1548  " list.\n", tid);
1549 
1550  ListIt end_it;
1551 
1552  bool rob_empty = false;
1553 
1554  if (instList.empty()) {
1555  return;
1556  } else if (rob.isEmpty(tid)) {
1557  DPRINTF(O3CPU, "ROB is empty, squashing all insts.\n");
1558  end_it = instList.begin();
1559  rob_empty = true;
1560  } else {
1561  end_it = (rob.readTailInst(tid))->getInstListIt();
1562  DPRINTF(O3CPU, "ROB is not empty, squashing insts not in ROB.\n");
1563  }
1564 
1565  removeInstsThisCycle = true;
1566 
1567  ListIt inst_it = instList.end();
1568 
1569  inst_it--;
1570 
1571  // Walk through the instruction list, removing any instructions
1572  // that were inserted after the given instruction iterator, end_it.
1573  while (inst_it != end_it) {
1574  assert(!instList.empty());
1575 
1576  squashInstIt(inst_it, tid);
1577 
1578  inst_it--;
1579  }
1580 
1581  // If the ROB was empty, then we actually need to remove the first
1582  // instruction as well.
1583  if (rob_empty) {
1584  squashInstIt(inst_it, tid);
1585  }
1586 }
1587 
1588 template <class Impl>
1589 void
1591 {
1592  assert(!instList.empty());
1593 
1594  removeInstsThisCycle = true;
1595 
1596  ListIt inst_iter = instList.end();
1597 
1598  inst_iter--;
1599 
1600  DPRINTF(O3CPU, "Deleting instructions from instruction "
1601  "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
1602  tid, seq_num, (*inst_iter)->seqNum);
1603 
1604  while ((*inst_iter)->seqNum > seq_num) {
1605 
1606  bool break_loop = (inst_iter == instList.begin());
1607 
1608  squashInstIt(inst_iter, tid);
1609 
1610  inst_iter--;
1611 
1612  if (break_loop)
1613  break;
1614  }
1615 }
1616 
1617 template <class Impl>
1618 inline void
1620 {
1621  if ((*instIt)->threadNumber == tid) {
1622  DPRINTF(O3CPU, "Squashing instruction, "
1623  "[tid:%i] [sn:%lli] PC %s\n",
1624  (*instIt)->threadNumber,
1625  (*instIt)->seqNum,
1626  (*instIt)->pcState());
1627 
1628  // Mark it as squashed.
1629  (*instIt)->setSquashed();
1630 
1631  // @todo: Formulate a consistent method for deleting
1632  // instructions from the instruction list
1633  // Remove the instruction from the list.
1634  removeList.push(instIt);
1635  }
1636 }
1637 
1638 template <class Impl>
1639 void
1641 {
1642  while (!removeList.empty()) {
1643  DPRINTF(O3CPU, "Removing instruction, "
1644  "[tid:%i] [sn:%lli] PC %s\n",
1645  (*removeList.front())->threadNumber,
1646  (*removeList.front())->seqNum,
1647  (*removeList.front())->pcState());
1648 
1649  instList.erase(removeList.front());
1650 
1651  removeList.pop();
1652  }
1653 
1654  removeInstsThisCycle = false;
1655 }
1656 /*
1657 template <class Impl>
1658 void
1659 FullO3CPU<Impl>::removeAllInsts()
1660 {
1661  instList.clear();
1662 }
1663 */
1664 template <class Impl>
1665 void
1667 {
1668  int num = 0;
1669 
1670  ListIt inst_list_it = instList.begin();
1671 
1672  cprintf("Dumping Instruction List\n");
1673 
1674  while (inst_list_it != instList.end()) {
1675  cprintf("Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n"
1676  "Squashed:%i\n\n",
1677  num, (*inst_list_it)->instAddr(), (*inst_list_it)->threadNumber,
1678  (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(),
1679  (*inst_list_it)->isSquashed());
1680  inst_list_it++;
1681  ++num;
1682  }
1683 }
1684 /*
1685 template <class Impl>
1686 void
1687 FullO3CPU<Impl>::wakeDependents(const DynInstPtr &inst)
1688 {
1689  iew.wakeDependents(inst);
1690 }
1691 */
1692 template <class Impl>
1693 void
1695 {
1696  if (activityRec.active() || tickEvent.scheduled()) {
1697  DPRINTF(Activity, "CPU already running.\n");
1698  return;
1699  }
1700 
1701  DPRINTF(Activity, "Waking up CPU\n");
1702 
1703  Cycles cycles(curCycle() - lastRunningCycle);
1704  // @todo: This is an oddity that is only here to match the stats
1705  if (cycles > 1) {
1706  --cycles;
1707  idleCycles += cycles;
1708  numCycles += cycles;
1709  }
1710 
1711  schedule(tickEvent, clockEdge());
1712 }
1713 
1714 template <class Impl>
1715 void
1717 {
1718  if (this->thread[tid]->status() != ThreadContext::Suspended)
1719  return;
1720 
1721  this->wakeCPU();
1722 
1723  DPRINTF(Quiesce, "Suspended Processor woken\n");
1724  this->threadContexts[tid]->activate();
1725 }
1726 
1727 template <class Impl>
1728 ThreadID
1730 {
1731  for (ThreadID tid = 0; tid < numThreads; tid++) {
1732  if (!tids[tid]) {
1733  tids[tid] = true;
1734  return tid;
1735  }
1736  }
1737 
1738  return InvalidThreadID;
1739 }
1740 
1741 template <class Impl>
1742 void
1744 {
1745  if (activeThreads.size() > 1) {
1746  //DEFAULT TO ROUND ROBIN SCHEME
1747  //e.g. Move highest priority to end of thread list
1748  list<ThreadID>::iterator list_begin = activeThreads.begin();
1749 
1750  unsigned high_thread = *list_begin;
1751 
1752  activeThreads.erase(list_begin);
1753 
1754  activeThreads.push_back(high_thread);
1755  }
1756 }
1757 
1758 template <class Impl>
1759 void
1761 {
1762  DPRINTF(O3CPU, "Thread %d is inserted to exitingThreads list\n", tid);
1763 
1764  // the thread trying to exit can't be already halted
1765  assert(tcBase(tid)->status() != ThreadContext::Halted);
1766 
1767  // make sure the thread has not been added to the list yet
1768  assert(exitingThreads.count(tid) == 0);
1769 
1770  // add the thread to exitingThreads list to mark that this thread is
1771  // trying to exit. The boolean value in the pair denotes if a thread is
1772  // ready to exit. The thread is not ready to exit until the corresponding
1773  // exit trap event is processed in the future. Until then, it'll be still
1774  // an active thread that is trying to exit.
1775  exitingThreads.emplace(std::make_pair(tid, false));
1776 }
1777 
1778 template <class Impl>
1779 bool
1781 {
1782  return exitingThreads.count(tid) == 1;
1783 }
1784 
1785 template <class Impl>
1786 void
1788 {
1789  assert(exitingThreads.count(tid) == 1);
1790 
1791  // exit trap event has been processed. Now, the thread is ready to exit
1792  // and be removed from the CPU.
1793  exitingThreads[tid] = true;
1794 
1795  // we schedule a threadExitEvent in the next cycle to properly clean
1796  // up the thread's states in the pipeline. threadExitEvent has lower
1797  // priority than tickEvent, so the cleanup will happen at the very end
1798  // of the next cycle after all pipeline stages complete their operations.
1799  // We want all stages to complete squashing instructions before doing
1800  // the cleanup.
1801  if (!threadExitEvent.scheduled()) {
1802  schedule(threadExitEvent, nextCycle());
1803  }
1804 }
1805 
1806 template <class Impl>
1807 void
1809 {
1810  // there must be at least one thread trying to exit
1811  assert(exitingThreads.size() > 0);
1812 
1813  // terminate all threads that are ready to exit
1814  auto it = exitingThreads.begin();
1815  while (it != exitingThreads.end()) {
1816  ThreadID thread_id = it->first;
1817  bool readyToExit = it->second;
1818 
1819  if (readyToExit) {
1820  DPRINTF(O3CPU, "Exiting thread %d\n", thread_id);
1821  haltContext(thread_id);
1822  tcBase(thread_id)->setStatus(ThreadContext::Halted);
1823  it = exitingThreads.erase(it);
1824  } else {
1825  it++;
1826  }
1827  }
1828 }
1829 
1830 template <class Impl>
1831 void
1833  HtmFailureFaultCause cause)
1834 {
1835  const Addr addr = 0x0ul;
1836  const int size = 8;
1837  const Request::Flags flags =
1839 
1840  // O3-specific actions
1841  this->iew.ldstQueue.resetHtmStartsStops(tid);
1842  this->commit.resetHtmStartsStops(tid);
1843 
1844  // notify l1 d-cache (ruby) that core has aborted transaction
1845  RequestPtr req =
1846  std::make_shared<Request>(addr, size, flags, _dataRequestorId);
1847 
1848  req->taskId(taskId());
1849  req->setContext(this->thread[tid]->contextId());
1850  req->setHtmAbortCause(cause);
1851 
1852  assert(req->isHTMAbort());
1853 
1854  PacketPtr abort_pkt = Packet::createRead(req);
1855  uint8_t *memData = new uint8_t[8];
1856  assert(memData);
1857  abort_pkt->dataStatic(memData);
1858  abort_pkt->setHtmTransactional(htm_uid);
1859 
1860  // TODO include correct error handling here
1861  if (!this->iew.ldstQueue.getDataPort().sendTimingReq(abort_pkt)) {
1862  panic("HTM abort signal was not sent to the memory subsystem.");
1863  }
1864 }
1865 
1866 // Forward declaration of FullO3CPU.
1867 template class FullO3CPU<O3CPUImpl>;
FullO3CPU::wakeup
virtual void wakeup(ThreadID tid) override
Definition: cpu.cc:1716
InvalidThreadID
const ThreadID InvalidThreadID
Definition: types.hh:228
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
ArmISA::status
Bitfield< 5, 0 > status
Definition: miscregs_types.hh:417
FullO3CPU::takeOverFrom
void takeOverFrom(BaseCPU *oldCPU) override
Takes over from another CPU.
Definition: cpu.cc:1133
FullO3CPU::setArchFloatReg
void setArchFloatReg(int reg_idx, RegVal val, ThreadID tid)
Definition: cpu.cc:1406
BaseCPU::regStats
void regStats() override
Definition: base.cc:369
FullO3CPU
FullO3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time ...
Definition: cpu.hh:93
FullO3CPU::deactivateThread
void deactivateThread(ThreadID tid)
Remove Thread from Active Threads List.
Definition: cpu.cc:620
FullO3CPU::getInterrupts
Fault getInterrupts()
Returns the Fault for any valid interrupt.
Definition: cpu.cc:883
FullO3CPU::readArchVecElem
const VecElem & readArchVecElem(const RegIndex &reg_idx, const ElemIndex &ldx, ThreadID tid) const
Definition: cpu.cc:1354
FullO3CPU::regProbePoints
void regProbePoints() override
Register probe points.
Definition: cpu.cc:366
FullO3CPU::updateThreadPriority
void updateThreadPriority()
Update The Order In Which We Process Threads.
Definition: cpu.cc:1743
system.hh
DrainState::Running
@ Running
Running normally.
VecPredRegContainer
Generic predicate register container.
Definition: vec_pred_reg.hh:47
EventBase::CPU_Tick_Pri
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
Definition: eventq.hh:199
FullO3CPU::microPC
MicroPC microPC(ThreadID tid)
Reads the commit micro PC of a specific thread.
Definition: cpu.cc:1486
VecElemClass
@ VecElemClass
Vector Register Native Elem lane.
Definition: reg_class.hh:58
FullO3CPU::addThreadToExitingList
void addThreadToExitingList(ThreadID tid)
Insert tid to the list of threads trying to exit.
Definition: cpu.cc:1760
FullO3CPU::setMiscRegNoEffect
void setMiscRegNoEffect(int misc_reg, RegVal val, ThreadID tid)
Sets a miscellaneous register.
Definition: cpu.cc:1180
FullO3CPU::startup
void startup() override
Definition: cpu.cc:589
FullO3CPU::totalInsts
Counter totalInsts() const override
Count the Total Instructions Committed in the CPU.
Definition: cpu.cc:645
RenameMode::mode
static Enums::VecRegRenameMode mode(const TheISA::PCState &)
Definition: traits.hh:58
BaseCPU::init
void init() override
Definition: base.cc:267
FullO3CPU::setVectorsAsReady
void setVectorsAsReady(ThreadID tid)
Mark vector fields in scoreboard as ready right after switching vector mode, since software may read ...
Definition: cpu.cc:841
FullO3CPU::activateThread
void activateThread(ThreadID tid)
Add Thread to Active Threads List.
Definition: cpu.cc:602
RiscvISA::sum
Bitfield< 18 > sum
Definition: registers.hh:609
FullO3CPU::setArchVecReg
void setArchVecReg(int reg_idx, const VecRegContainer &val, ThreadID tid)
Definition: cpu.cc:1417
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
FullO3CPU::serializeThread
void serializeThread(CheckpointOut &cp, ThreadID tid) const override
Serialize a single thread.
Definition: cpu.cc:937
FullO3CPU::readVecReg
const VecRegContainer & readVecReg(PhysRegIdPtr reg_idx) const
Definition: cpu.cc:1211
Process
Definition: process.hh:65
ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:227
FullO3CPU::setArchIntReg
void setArchIntReg(int reg_idx, RegVal val, ThreadID tid)
Architectural register accessors.
Definition: cpu.cc:1395
FullO3CPU::nextInstAddr
Addr nextInstAddr(ThreadID tid)
Reads the next PC of a specific thread.
Definition: cpu.cc:1479
Flags< FlagsType >
FullO3CPU::isThreadExiting
bool isThreadExiting(ThreadID tid) const
Is the thread trying to exit?
Definition: cpu.cc:1780
FullO3CPU::switchRenameMode
void switchRenameMode(ThreadID tid, UnifiedFreeList *freelist)
Check if a change in renaming is needed for vector registers.
Definition: cpu.cc:863
FullO3CPU::getWritableVecReg
VecRegContainer & getWritableVecReg(PhysRegIdPtr reg_idx)
Read physical vector register for modification.
Definition: cpu.cc:1220
FullO3CPU::readArchVecReg
const VecRegContainer & readArchVecReg(int reg_idx, ThreadID tid) const
Definition: cpu.cc:1334
TheISA
Definition: decode_cache.hh:37
FullO3CPU::setArchCCReg
void setArchCCReg(int reg_idx, RegVal val, ThreadID tid)
Definition: cpu.cc:1447
ProbePointArg
ProbePointArg generates a point for the class of Arg.
Definition: thermal_domain.hh:50
Checker
Templated Checker class.
Definition: cpu.hh:653
FullO3CPU::drainResume
void drainResume() override
Resumes execution after a drain.
Definition: cpu.cc:1088
FullO3CPU::removeThread
void removeThread(ThreadID tid)
Remove all of a thread's context from CPU.
Definition: cpu.cc:797
RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:82
FullO3CPU::addInst
ListIt addInst(const DynInstPtr &inst)
Function to add instruction onto the head of the list of the instructions.
Definition: cpu.cc:1501
FullO3CPU::instAddr
Addr instAddr(ThreadID tid)
Reads the commit PC of a specific thread.
Definition: cpu.cc:1472
FullO3CPU::setVecPredReg
void setVecPredReg(PhysRegIdPtr reg_idx, const VecPredRegContainer &val)
Definition: cpu.cc:1295
FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:132
HtmFailureFaultCause
HtmFailureFaultCause
Definition: htm.hh:44
GuestABI::setVecReg
tc setVecReg(id, reg)
FullO3CPU::removeFrontInst
void removeFrontInst(const DynInstPtr &inst)
Remove an instruction from the front end of the list.
Definition: cpu.cc:1531
FullO3CPU< O3CPUImpl >::VecElem
TheISA::VecElem VecElem
Definition: cpu.hh:101
RenameMode
Helper structure to get the vector register mode for a given ISA.
Definition: traits.hh:53
FullO3CPU::globalSeqNum
InstSeqNum globalSeqNum
The global sequence number counter.
Definition: cpu.hh:685
FullO3CPU::squashFromTC
void squashFromTC(ThreadID tid)
Initiates a squash of all in-flight instructions for a given thread.
Definition: cpu.cc:1493
FullO3CPU::switchOut
void switchOut() override
Switches out this CPU.
Definition: cpu.cc:1118
RegId
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:75
FullO3CPU::cleanUpRemovedInsts
void cleanUpRemovedInsts()
Cleans up all instructions on the remove list.
Definition: cpu.cc:1640
FullO3CPU::readVecElem
const VecElem & readVecElem(PhysRegIdPtr reg_idx) const
Definition: cpu.cc:1229
DrainState::Drained
@ Drained
Buffers drained, ready for serialization/handover.
FullO3CPU::commitDrained
void commitDrained(ThreadID tid)
Commit has reached a safe point to drain a thread.
Definition: cpu.cc:1081
DrainState
DrainState
Object drain/handover states.
Definition: drain.hh:71
FullO3CPU::readVecPredReg
const VecPredRegContainer & readVecPredReg(PhysRegIdPtr reg_idx) const
Definition: cpu.cc:1237
EventBase::CPU_Exit_Pri
static const Priority CPU_Exit_Pri
If we want to exit a thread in a CPU, it comes after CPU_Tick_Pri.
Definition: eventq.hh:206
X86ISA::system
Bitfield< 15 > system
Definition: misc.hh:997
Counter
int64_t Counter
Statistics counter type.
Definition: types.hh:58
Request::STRICT_ORDER
@ STRICT_ORDER
The request is required to be strictly ordered by CPU models and is non-speculative.
Definition: request.hh:124
FullO3CPU::suspendContext
void suspendContext(ThreadID tid) override
Remove Thread from Active Threads List.
Definition: cpu.cc:710
FullO3CPU::regStats
void regStats() override
Registers statistics.
Definition: cpu.cc:381
Request::PHYSICAL
@ PHYSICAL
The virtual address is also the physical address.
Definition: request.hh:106
FullO3CPU::removeInstsNotInROB
void removeInstsNotInROB(ThreadID tid)
Remove all instructions that are not currently in the ROB.
Definition: cpu.cc:1545
cp
Definition: cprintf.cc:40
FullO3CPU::setCCReg
void setCCReg(PhysRegIdPtr phys_reg, RegVal val)
Definition: cpu.cc:1304
FullO3CPU::setIntReg
void setIntReg(PhysRegIdPtr phys_reg, RegVal val)
Definition: cpu.cc:1263
FullO3CPU< O3CPUImpl >::DynInstPtr
O3CPUImpl ::DynInstPtr DynInstPtr
Definition: cpu.hh:98
FloatRegClass
@ FloatRegClass
Floating-point register.
Definition: reg_class.hh:54
FullO3CPU::ListIt
std::list< DynInstPtr >::iterator ListIt
Definition: cpu.hh:109
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
FullO3CPU::wakeCPU
void wakeCPU()
Wakes the CPU, rescheduling the CPU if it's not already active.
Definition: cpu.cc:1694
isa_specific.hh
FullO3CPU::activateContext
void activateContext(ThreadID tid) override
Add Thread to Active Threads List.
Definition: cpu.cc:671
FullO3CPU::verifyMemoryMode
void verifyMemoryMode() const override
Verify that the system is in a memory mode supported by the CPU.
Definition: cpu.cc:1155
BaseO3CPU
Definition: cpu.hh:78
FullO3CPU::readMiscRegNoEffect
RegVal readMiscRegNoEffect(int misc_reg, ThreadID tid) const
Register accessors.
Definition: cpu.cc:1165
cprintf
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:152
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
ThreadContext::Halted
@ Halted
Permanently shut down.
Definition: thread_context.hh:115
FullO3CPU::getWritableArchVecPredReg
VecPredRegContainer & getWritableArchVecPredReg(int reg_idx, ThreadID tid)
Definition: cpu.cc:1374
Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
FullO3CPU::Thread
O3ThreadState< Impl > Thread
Definition: cpu.hh:107
MipsISA::pc
Bitfield< 4 > pc
Definition: pra_constants.hh:240
FullO3CPU::getWritableArchVecReg
VecRegContainer & getWritableArchVecReg(int reg_idx, ThreadID tid)
Read architectural vector register for modification.
Definition: cpu.cc:1344
Packet::createRead
static PacketPtr createRead(const RequestPtr &req)
Constructor-like methods that return Packets based on Request objects.
Definition: packet.hh:980
FullO3CPU::readArchVecPredReg
const VecPredRegContainer & readArchVecPredReg(int reg_idx, ThreadID tid) const
Definition: cpu.cc:1364
traits.hh
cpu.hh
ArmISA::ZeroReg
const int ZeroReg
Definition: registers.hh:118
ArmISA::NumVecElemPerVecReg
constexpr unsigned NumVecElemPerVecReg
Definition: registers.hh:66
process.hh
CheckerCPU::setIcachePort
void setIcachePort(RequestPort *icache_port)
Definition: cpu.cc:116
UnifiedFreeList
FreeList class that simply holds the list of free integer and floating point registers.
Definition: free_list.hh:115
activity.hh
FullO3CPU::~FullO3CPU
~FullO3CPU()
Destructor.
Definition: cpu.cc:360
BaseCPU::activateContext
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
Definition: base.cc:480
Packet::setHtmTransactional
void setHtmTransactional(uint64_t val)
Stipulates that this packet/request originates in the CPU executing in transactional mode,...
Definition: packet.cc:537
ArmISA::NumVecPredRegs
const int NumVecPredRegs
Definition: registers.hh:98
FullO3CPU::getFreeTid
ThreadID getFreeTid()
Gets a free thread id.
Definition: cpu.cc:1729
FullO3CPU::readIntReg
RegVal readIntReg(PhysRegIdPtr phys_reg)
Definition: cpu.cc:1195
BaseO3CPU::BaseO3CPU
BaseO3CPU(BaseCPUParams *params)
Definition: cpu.cc:70
FullO3CPU::instDone
void instDone(ThreadID tid, const DynInstPtr &inst)
Function to tell the CPU that an instruction has completed.
Definition: cpu.cc:1510
FullO3CPU::removeInstsUntil
void removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
Remove all instructions younger than the given sequence number.
Definition: cpu.cc:1590
ArmISA::NumFloatRegs
const int NumFloatRegs
Definition: registers.hh:83
VecPredRegClass
@ VecPredRegClass
Definition: reg_class.hh:59
FullO3CPU::FullO3CPU
FullO3CPU(DerivO3CPUParams *params)
Constructs a CPU with the given parameters.
Definition: cpu.cc:82
X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:769
InstSeqNum
uint64_t InstSeqNum
Definition: inst_seq.hh:37
NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:245
core.hh
ArmISA::NumIntRegs
const int NumIntRegs
Definition: registers.hh:82
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
ThreadContext::setStatus
virtual void setStatus(Status new_status)=0
FullO3CPU::readFloatReg
RegVal readFloatReg(PhysRegIdPtr phys_reg)
Definition: cpu.cc:1203
name
const std::string & name()
Definition: trace.cc:50
FullO3CPU::insertThread
void insertThread(ThreadID tid)
Setup CPU to insert a thread's context.
Definition: cpu.cc:745
FullO3CPU::processInterrupts
void processInterrupts(const Fault &interrupt)
Processes any an interrupt fault.
Definition: cpu.cc:891
IntRegClass
@ IntRegClass
Integer register.
Definition: reg_class.hh:53
FullO3CPU::isCpuDrained
bool isCpuDrained() const
Check if a system is in a drained state.
Definition: cpu.cc:1042
FullO3CPU::syscall
void syscall(ThreadID tid)
Executes a syscall.
Definition: cpu.cc:917
FullO3CPU::drainSanityCheck
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: cpu.cc:1030
full_system.hh
CCRegClass
@ CCRegClass
Condition-code register.
Definition: reg_class.hh:60
ArmISA::e
Bitfield< 9 > e
Definition: miscregs_types.hh:61
ThreadContext::pcState
virtual TheISA::PCState pcState() const =0
FullO3CPU::dumpInsts
void dumpInsts()
Debug function to print all instructions on the list.
Definition: cpu.cc:1666
BaseCPU
Definition: cpu_dummy.hh:43
FullO3CPU::tryDrain
bool tryDrain()
Check if the pipeline has drained and signal drain done.
Definition: cpu.cc:1014
stat_control.hh
VecRegClass
@ VecRegClass
Vector Register.
Definition: reg_class.hh:56
ThreadContext::Suspended
@ Suspended
Temporarily inactive.
Definition: thread_context.hh:106
simple_thread.hh
FullO3CPU::readCCReg
RegVal readCCReg(PhysRegIdPtr phys_reg)
Definition: cpu.cc:1255
FullO3CPU::setVecElem
void setVecElem(PhysRegIdPtr reg_idx, const VecElem &val)
Definition: cpu.cc:1287
ArmISA::NumCCRegs
const int NumCCRegs
Definition: registers.hh:84
PseudoInst::quiesceCycles
void quiesceCycles(ThreadContext *tc, uint64_t cycles)
Definition: pseudo_inst.cc:143
FullO3CPU::readArchIntReg
RegVal readArchIntReg(int reg_idx, ThreadID tid)
Definition: cpu.cc:1312
Request::HTM_ABORT
@ HTM_ABORT
The request aborts a HTM transaction.
Definition: request.hh:203
std
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
MipsISA::PCState
GenericISA::DelaySlotPCState< MachInst > PCState
Definition: types.hh:41
RegIndex
uint16_t RegIndex
Definition: types.hh:52
ArmISA::t
Bitfield< 5 > t
Definition: miscregs_types.hh:67
Packet::dataStatic
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Definition: packet.hh:1107
BaseCPU::takeOverFrom
virtual void takeOverFrom(BaseCPU *cpu)
Load the state of a CPU from the previous CPU object, invoked on all new CPUs that are about to be sw...
Definition: base.cc:546
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
BaseCPU::switchOut
virtual void switchOut()
Prepare for another CPU to take over execution.
Definition: base.cc:532
FullO3CPU::squashInstIt
void squashInstIt(const ListIt &instIt, ThreadID tid)
Removes the instruction pointed to by the iterator.
Definition: cpu.cc:1619
FullO3CPU::haltContext
void haltContext(ThreadID tid) override
Remove Thread from Active Threads List && Remove Thread Context from CPU.
Definition: cpu.cc:731
ArmISA::readVecElem
XReg readVecElem(VReg src, int index, int eSize)
Read a single NEON vector element.
Definition: neon64_mem.hh:91
FullO3CPU::htmSendAbortSignal
void htmSendAbortSignal(ThreadID tid, uint64_t htm_uid, HtmFailureFaultCause cause)
Definition: cpu.cc:1832
ElemIndex
uint16_t ElemIndex
Logical vector register elem index type.
Definition: types.hh:55
addr
ip6_addr_t addr
Definition: inet.hh:423
O3ThreadContext::thread
O3ThreadState< Impl > * thread
Pointer to the thread state that this TC corrseponds to.
Definition: thread_context.hh:99
PseudoInst::wakeCPU
void wakeCPU(ThreadContext *tc, uint64_t cpuid)
Definition: pseudo_inst.cc:166
FullO3CPU::tick
void tick()
Ticks CPU, calling tick() on each stage, and checking the overall activity to see if the CPU should d...
Definition: cpu.cc:509
Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:83
ThreadContext::Active
@ Active
Running.
Definition: thread_context.hh:102
CheckerThreadContext
Derived ThreadContext class for use with the Checker.
Definition: thread_context.hh:66
FullO3CPU::init
void init() override
Initialize the CPU.
Definition: cpu.cc:568
thread_context.hh
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:63
BaseCPU::startup
void startup() override
Definition: base.cc:310
PhysRegId
Physical register ID.
Definition: reg_class.hh:223
BaseCPU::regProbePoints
void regProbePoints() override
Definition: base.cc:335
BaseCPU::CPU_STATE_ON
@ CPU_STATE_ON
Definition: base.hh:508
FullO3CPU::setVecReg
void setVecReg(PhysRegIdPtr reg_idx, const VecRegContainer &val)
Definition: cpu.cc:1279
BaseCPU::suspendContext
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
Definition: base.cc:494
RefCountingPtr< StaticInst >
FullO3CPU::pcState
void pcState(const TheISA::PCState &newPCState, ThreadID tid)
Sets the commit PC state of a specific thread.
Definition: cpu.cc:1465
BaseO3CPU::regStats
void regStats()
Definition: cpu.cc:76
RegId::index
const RegIndex & index() const
Index accessors.
Definition: reg_class.hh:173
BaseCPU::CPU_STATE_SLEEP
@ CPU_STATE_SLEEP
Definition: base.hh:509
FullO3CPU::exitThreads
void exitThreads()
Terminate all threads that are ready to exit.
Definition: cpu.cc:1808
ArmISA::NumVecRegs
const int NumVecRegs
Definition: registers.hh:97
FullO3CPU::trap
void trap(const Fault &fault, ThreadID tid, const StaticInstPtr &inst)
Traps to handle given fault.
Definition: cpu.cc:908
FullO3CPU::setMiscReg
void setMiscReg(int misc_reg, RegVal val, ThreadID tid)
Sets a misc.
Definition: cpu.cc:1187
cpu.hh
std::list
STL list class.
Definition: stl.hh:51
FullO3CPU< O3CPUImpl >::O3CPU
O3CPUImpl ::O3CPU O3CPU
Definition: cpu.hh:99
MicroPC
uint16_t MicroPC
Definition: types.hh:144
FullO3CPU::totalOps
Counter totalOps() const override
Count the Total Ops (including micro ops) committed in the CPU.
Definition: cpu.cc:658
FullO3CPU::setFloatReg
void setFloatReg(PhysRegIdPtr phys_reg, RegVal val)
Definition: cpu.cc:1271
Stats::total
const FlagsType total
Print the total.
Definition: info.hh:49
CheckpointIn
Definition: serialize.hh:67
thread_context.hh
GuestABI::readVecReg
struct IsAapcs64Hfa< E[N], typename std::enable_if< std::is_floating_point< E >::value &&N<=4 >::type > :public std::true_type{};template< typename T, typename Enabled=void >struct IsAapcs64Hva :public std::false_type {};template< typename E, size_t N >struct IsAapcs64Hva< E[N], typename std::enable_if< IsAapcs64ShortVector< E >::value &&N<=4 >::type > :public std::true_type{};template< typename T, typename Enabled=void >struct IsAapcs64Hxa :public std::false_type {};template< typename T >struct IsAapcs64Hxa< T, typename std::enable_if< IsAapcs64Hfa< T >::value||IsAapcs64Hva< T >::value >::type > :public std::true_type{};struct Aapcs64ArgumentBase{ template< typename T > static T loadFromStack(ThreadContext *tc, Aapcs64::State &state) { size_t align=std::max< size_t >(8, alignof(T));size_t size=roundUp(sizeof(T), 8);state.nsaa=roundUp(state.nsaa, align);ConstVPtr< T > val(state.nsaa, tc);state.nsaa+=size;return gtoh(*val, ArmISA::byteOrder(tc));}};template< typename Float >struct Argument< Aapcs64, Float, typename std::enable_if< std::is_floating_point< Float >::value||IsAapcs64ShortVector< Float >::value >::type > :public Aapcs64ArgumentBase{ static Float get(ThreadContext *tc, Aapcs64::State &state) { if(state.nsrn<=state.MAX_SRN) { RegId id(VecRegClass, state.nsrn++);return tc->readVecReg(id).laneView< Float, 0 >();} return loadFromStack< Float >(tc, state);}};template< typename Float >struct Result< Aapcs64, Float, typename std::enable_if< std::is_floating_point< Float >::value||IsAapcs64ShortVector< Float >::value >::type >{ static void store(ThreadContext *tc, const Float &f) { RegId id(VecRegClass, 0);auto reg=tc-> readVecReg(id)
Definition: aapcs64.hh:203
FullO3CPU::drain
DrainState drain() override
Starts draining the CPU's pipeline of all instructions in order to stop all memory accesses.
Definition: cpu.cc:951
FullO3CPU::readArchCCReg
RegVal readArchCCReg(int reg_idx, ThreadID tid)
Definition: cpu.cc:1384
FullO3CPU::setArchVecElem
void setArchVecElem(const RegIndex &reg_idx, const ElemIndex &ldx, const VecElem &val, ThreadID tid)
Definition: cpu.cc:1427
FullO3CPU::unserializeThread
void unserializeThread(CheckpointIn &cp, ThreadID tid) override
Unserialize one thread.
Definition: cpu.cc:944
ArmISA::v
Bitfield< 28 > v
Definition: miscregs_types.hh:51
thread_context.hh
FullO3CPU::readMiscReg
RegVal readMiscReg(int misc_reg, ThreadID tid)
Reads a misc.
Definition: cpu.cc:1172
O3ThreadContext::cpu
O3CPU * cpu
Pointer to the CPU.
Definition: thread_context.hh:69
RegVal
uint64_t RegVal
Definition: types.hh:168
FullO3CPU::setArchVecPredReg
void setArchVecPredReg(int reg_idx, const VecPredRegContainer &val, ThreadID tid)
Definition: cpu.cc:1437
FullO3CPU::scheduleThreadExitEvent
void scheduleThreadExitEvent(ThreadID tid)
If a thread is trying to exit and its corresponding trap event has been completed,...
Definition: cpu.cc:1787
VecRegContainer
Vector Register Abstraction This generic class is the model in a particularization of MVC,...
Definition: vec_reg.hh:156
DrainState::Draining
@ Draining
Draining buffers pending serialization/handover.
FullO3CPU::readArchFloatReg
RegVal readArchFloatReg(int reg_idx, ThreadID tid)
Definition: cpu.cc:1323
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
FullO3CPU::getWritableVecPredReg
VecPredRegContainer & getWritableVecPredReg(PhysRegIdPtr reg_idx)
Definition: cpu.cc:1246
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
O3ThreadContext
Derived ThreadContext class for use with the O3CPU.
Definition: cpu.hh:71

Generated on Wed Sep 30 2020 14:01:58 for gem5 by doxygen 1.8.17