inorder cpu: add missing DPRINTF argument
[gem5.git] / src / cpu / ozone / cpu_impl.hh
1 /*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Kevin Lim
29 * Nathan Binkert
30 */
31
32 #include "arch/alpha/osfpal.hh"
33 #include "arch/isa_traits.hh" // For MachInst
34 #include "arch/kernel_stats.hh"
35 #include "arch/tlb.hh"
36 #include "arch/types.hh"
37 #include "arch/vtophys.hh"
38 #include "base/callback.hh"
39 #include "base/trace.hh"
40 #include "config/the_isa.hh"
41 #include "cpu/checker/thread_context.hh"
42 #include "cpu/ozone/cpu.hh"
43 #include "cpu/base.hh"
44 #include "cpu/exetrace.hh"
45 #include "cpu/profile.hh"
46 #include "cpu/quiesce_event.hh"
47 #include "cpu/simple_thread.hh"
48 #include "cpu/static_inst.hh"
49 #include "cpu/thread_context.hh"
50 #include "sim/faults.hh"
51 #include "sim/full_system.hh"
52 #include "sim/process.hh"
53 #include "sim/sim_events.hh"
54 #include "sim/sim_exit.hh"
55 #include "sim/sim_object.hh"
56 #include "sim/stats.hh"
57 #include "sim/system.hh"
58
59 using namespace TheISA;
60
61 template <class Impl>
62 OzoneCPU<Impl>::TickEvent::TickEvent(OzoneCPU *c, int w)
63 : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c), width(w)
64 {
65 }
66
67 template <class Impl>
68 void
69 OzoneCPU<Impl>::TickEvent::process()
70 {
71 cpu->tick();
72 }
73
74 template <class Impl>
75 const char *
76 OzoneCPU<Impl>::TickEvent::description() const
77 {
78 return "OzoneCPU tick";
79 }
80
81 template <class Impl>
82 OzoneCPU<Impl>::OzoneCPU(Params *p)
83 : BaseCPU(p), thread(this, 0, p->workload[0], 0), tickEvent(this,
84 p->width),
85 #ifndef NDEBUG
86 instcount(0),
87 #endif
88 comm(5, 5)
89 {
90 frontEnd = new FrontEnd(p);
91 backEnd = new BackEnd(p);
92
93 _status = Idle;
94
95 if (p->checker) {
96 BaseCPU *temp_checker = p->checker;
97 checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
98 checker->setSystem(p->system);
99 checkerTC = new CheckerThreadContext<OzoneTC>(&ozoneTC, checker);
100 thread.tc = checkerTC;
101 tc = checkerTC;
102 } else {
103 // If checker is not being used, then the xcProxy points
104 // directly to the CPU's ExecContext.
105 checker = NULL;
106 thread.tc = &ozoneTC;
107 tc = &ozoneTC;
108 }
109
110 ozoneTC.cpu = this;
111 ozoneTC.thread = &thread;
112
113 thread.inSyscall = false;
114
115 itb = p->itb;
116 dtb = p->dtb;
117
118 if (FullSystem) {
119 // Setup thread state stuff.
120 thread.cpu = this;
121 thread.setTid(0);
122
123 thread.quiesceEvent = new EndQuiesceEvent(tc);
124
125 system = p->system;
126 physmem = p->system->physmem;
127
128 if (p->profile) {
129 thread.profile = new FunctionProfile(p->system->kernelSymtab);
130 // @todo: This might be better as an ThreadContext instead of
131 // OzoneTC
132 Callback *cb =
133 new MakeCallback<OzoneTC,
134 &OzoneTC::dumpFuncProfile>(&ozoneTC);
135 registerExitCallback(cb);
136 }
137
138 // let's fill with a dummy node for now so we don't get a segfault
139 // on the first cycle when there's no node available.
140 static ProfileNode dummyNode;
141 thread.profileNode = &dummyNode;
142 thread.profilePC = 3;
143 } else {
144 thread.cpu = this;
145 }
146
147 numInst = 0;
148 startNumInst = 0;
149
150 threadContexts.push_back(tc);
151
152 frontEnd->setCPU(this);
153 backEnd->setCPU(this);
154
155 frontEnd->setTC(tc);
156 backEnd->setTC(tc);
157
158 frontEnd->setThreadState(&thread);
159 backEnd->setThreadState(&thread);
160
161 frontEnd->setCommBuffer(&comm);
162 backEnd->setCommBuffer(&comm);
163
164 frontEnd->setBackEnd(backEnd);
165 backEnd->setFrontEnd(frontEnd);
166
167 globalSeqNum = 1;
168
169 lockFlag = 0;
170
171 // Setup rename table, initializing all values to ready.
172 for (int i = 0; i < TheISA::TotalNumRegs; ++i) {
173 thread.renameTable[i] = new DynInst(this);
174 thread.renameTable[i]->setResultReady();
175 }
176
177 frontEnd->renameTable.copyFrom(thread.renameTable);
178 backEnd->renameTable.copyFrom(thread.renameTable);
179
180 thread.connectMemPorts(tc);
181
182 DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n");
183 }
184
185 template <class Impl>
186 OzoneCPU<Impl>::~OzoneCPU()
187 {
188 }
189
190 template <class Impl>
191 void
192 OzoneCPU<Impl>::switchOut()
193 {
194 BaseCPU::switchOut();
195 switchCount = 0;
196 // Front end needs state from back end, so switch out the back end first.
197 backEnd->switchOut();
198 frontEnd->switchOut();
199 }
200
201 template <class Impl>
202 void
203 OzoneCPU<Impl>::signalSwitched()
204 {
205 // Only complete the switchout when both the front end and back
206 // end have signalled they are ready to switch.
207 if (++switchCount == 2) {
208 backEnd->doSwitchOut();
209 frontEnd->doSwitchOut();
210
211 if (checker)
212 checker->switchOut();
213
214 _status = SwitchedOut;
215 #ifndef NDEBUG
216 // Loop through all registers
217 for (int i = 0; i < AlphaISA::TotalNumRegs; ++i) {
218 assert(thread.renameTable[i] == frontEnd->renameTable[i]);
219
220 assert(thread.renameTable[i] == backEnd->renameTable[i]);
221
222 DPRINTF(OzoneCPU, "Checking if register %i matches.\n", i);
223 }
224 #endif
225
226 if (tickEvent.scheduled())
227 tickEvent.squash();
228 }
229 assert(switchCount <= 2);
230 }
231
232 template <class Impl>
233 void
234 OzoneCPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
235 {
236 BaseCPU::takeOverFrom(oldCPU);
237
238 thread.trapPending = false;
239 thread.inSyscall = false;
240
241 backEnd->takeOverFrom();
242 frontEnd->takeOverFrom();
243 frontEnd->renameTable.copyFrom(thread.renameTable);
244 backEnd->renameTable.copyFrom(thread.renameTable);
245 assert(!tickEvent.scheduled());
246
247 #ifndef NDEBUG
248 // Check rename table.
249 for (int i = 0; i < TheISA::TotalNumRegs; ++i) {
250 assert(thread.renameTable[i]->isResultReady());
251 }
252 #endif
253
254 // @todo: Fix hardcoded number
255 // Clear out any old information in time buffer.
256 for (int i = 0; i < 15; ++i) {
257 comm.advance();
258 }
259
260 // if any of this CPU's ThreadContexts are active, mark the CPU as
261 // running and schedule its tick event.
262 for (int i = 0; i < threadContexts.size(); ++i) {
263 ThreadContext *tc = threadContexts[i];
264 if (tc->status() == ThreadContext::Active &&
265 _status != Running) {
266 _status = Running;
267 tickEvent.schedule(curTick());
268 }
269 }
270 // Nothing running, change status to reflect that we're no longer
271 // switched out.
272 if (_status == SwitchedOut) {
273 _status = Idle;
274 }
275 }
276
277 template <class Impl>
278 void
279 OzoneCPU<Impl>::activateContext(int thread_num, int delay)
280 {
281 // Eventually change this in SMT.
282 assert(thread_num == 0);
283
284 assert(_status == Idle);
285 notIdleFraction++;
286 scheduleTickEvent(delay);
287 _status = Running;
288 if (thread.quiesceEvent && thread.quiesceEvent->scheduled())
289 thread.quiesceEvent->deschedule();
290 thread.setStatus(ThreadContext::Active);
291 frontEnd->wakeFromQuiesce();
292 }
293
294 template <class Impl>
295 void
296 OzoneCPU<Impl>::suspendContext(int thread_num)
297 {
298 // Eventually change this in SMT.
299 assert(thread_num == 0);
300 // @todo: Figure out how to initially set the status properly so
301 // this is running.
302 // assert(_status == Running);
303 notIdleFraction--;
304 unscheduleTickEvent();
305 _status = Idle;
306 }
307
308 template <class Impl>
309 void
310 OzoneCPU<Impl>::deallocateContext(int thread_num, int delay)
311 {
312 // for now, these are equivalent
313 suspendContext(thread_num);
314 }
315
316 template <class Impl>
317 void
318 OzoneCPU<Impl>::haltContext(int thread_num)
319 {
320 // for now, these are equivalent
321 suspendContext(thread_num);
322 }
323
324 template <class Impl>
325 void
326 OzoneCPU<Impl>::regStats()
327 {
328 using namespace Stats;
329
330 BaseCPU::regStats();
331
332 thread.numInsts
333 .name(name() + ".num_insts")
334 .desc("Number of instructions executed")
335 ;
336
337 thread.numMemRefs
338 .name(name() + ".num_refs")
339 .desc("Number of memory references")
340 ;
341
342 notIdleFraction
343 .name(name() + ".not_idle_fraction")
344 .desc("Percentage of non-idle cycles")
345 ;
346
347 idleFraction
348 .name(name() + ".idle_fraction")
349 .desc("Percentage of idle cycles")
350 ;
351
352 quiesceCycles
353 .name(name() + ".quiesce_cycles")
354 .desc("Number of cycles spent in quiesce")
355 ;
356
357 idleFraction = constant(1.0) - notIdleFraction;
358
359 frontEnd->regStats();
360 backEnd->regStats();
361 }
362
363 template <class Impl>
364 void
365 OzoneCPU<Impl>::resetStats()
366 {
367 // startNumInst = numInst;
368 notIdleFraction = (_status != Idle);
369 }
370
371 template <class Impl>
372 void
373 OzoneCPU<Impl>::init()
374 {
375 BaseCPU::init();
376
377 // Mark this as in syscall so it won't need to squash
378 thread.inSyscall = true;
379 if (FullSystem) {
380 for (int i = 0; i < threadContexts.size(); ++i) {
381 ThreadContext *tc = threadContexts[i];
382
383 // initialize CPU, including PC
384 TheISA::initCPU(tc, tc->contextId());
385 }
386 }
387 frontEnd->renameTable.copyFrom(thread.renameTable);
388 backEnd->renameTable.copyFrom(thread.renameTable);
389
390 thread.inSyscall = false;
391 }
392
393 template <class Impl>
394 void
395 OzoneCPU<Impl>::serialize(std::ostream &os)
396 {
397 BaseCPU::serialize(os);
398 SERIALIZE_ENUM(_status);
399 nameOut(os, csprintf("%s.tc", name()));
400 ozoneTC.serialize(os);
401 nameOut(os, csprintf("%s.tickEvent", name()));
402 tickEvent.serialize(os);
403
404 // Use SimpleThread's ability to checkpoint to make it easier to
405 // write out the registers. Also make this static so it doesn't
406 // get instantiated multiple times (causes a panic in statistics).
407 static SimpleThread temp;
408
409 nameOut(os, csprintf("%s.xc.0", name()));
410 temp.copyTC(thread.getTC());
411 temp.serialize(os);
412 }
413
414 template <class Impl>
415 void
416 OzoneCPU<Impl>::unserialize(Checkpoint *cp, const std::string &section)
417 {
418 BaseCPU::unserialize(cp, section);
419 UNSERIALIZE_ENUM(_status);
420 ozoneTC.unserialize(cp, csprintf("%s.tc", section));
421 tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
422
423 // Use SimpleThread's ability to checkpoint to make it easier to
424 // read in the registers. Also make this static so it doesn't
425 // get instantiated multiple times (causes a panic in statistics).
426 static SimpleThread temp;
427
428 temp.copyTC(thread.getTC());
429 temp.unserialize(cp, csprintf("%s.xc.0", section));
430 thread.getTC()->copyArchRegs(temp.getTC());
431 }
432
433 template <class Impl>
434 Addr
435 OzoneCPU<Impl>::dbg_vtophys(Addr addr)
436 {
437 return vtophys(tc, addr);
438 }
439
440 template <class Impl>
441 void
442 OzoneCPU<Impl>::wakeup()
443 {
444 if (_status == Idle) {
445 DPRINTF(IPI,"Suspended Processor awoke\n");
446 // Hack for now. Otherwise might have to go through the tc, or
447 // I need to figure out what's the right thing to call.
448 activateContext(thread.threadId(), 1);
449 }
450 }
451
452 /* start simulation, program loaded, processor precise state initialized */
453 template <class Impl>
454 void
455 OzoneCPU<Impl>::tick()
456 {
457 DPRINTF(OzoneCPU, "\n\nOzoneCPU: Ticking cpu.\n");
458
459 _status = Running;
460 thread.renameTable[ZeroReg]->setIntResult(0);
461 thread.renameTable[ZeroReg+TheISA::FP_Base_DepTag]->
462 setDoubleResult(0.0);
463
464 comm.advance();
465 frontEnd->tick();
466 backEnd->tick();
467
468 // check for instruction-count-based events
469 comInstEventQueue[0]->serviceEvents(numInst);
470
471 if (!tickEvent.scheduled() && _status == Running)
472 tickEvent.schedule(curTick() + ticks(1));
473 }
474
475 template <class Impl>
476 void
477 OzoneCPU<Impl>::squashFromTC()
478 {
479 thread.inSyscall = true;
480 backEnd->generateTCEvent();
481 }
482
483 template <class Impl>
484 void
485 OzoneCPU<Impl>::syscall(uint64_t &callnum)
486 {
487 // Not sure this copy is needed, depending on how the TC proxy is made.
488 thread.renameTable.copyFrom(backEnd->renameTable);
489
490 thread.inSyscall = true;
491
492 thread.funcExeInst++;
493
494 DPRINTF(OzoneCPU, "FuncExeInst: %i\n", thread.funcExeInst);
495
496 thread.process->syscall(callnum, tc);
497
498 thread.funcExeInst--;
499
500 thread.inSyscall = false;
501
502 frontEnd->renameTable.copyFrom(thread.renameTable);
503 backEnd->renameTable.copyFrom(thread.renameTable);
504 }
505
506 template <class Impl>
507 Fault
508 OzoneCPU<Impl>::hwrei()
509 {
510 // Need to move this to ISA code
511 // May also need to make this per thread
512
513 lockFlag = false;
514 lockAddrList.clear();
515 thread.kernelStats->hwrei();
516
517 // FIXME: XXX check for interrupts? XXX
518 return NoFault;
519 }
520
521 template <class Impl>
522 void
523 OzoneCPU<Impl>::processInterrupts()
524 {
525 // Check for interrupts here. For now can copy the code that
526 // exists within isa_fullsys_traits.hh. Also assume that thread 0
527 // is the one that handles the interrupts.
528
529 // Check if there are any outstanding interrupts
530 //Handle the interrupts
531 Fault interrupt = this->interrupts->getInterrupt(thread.getTC());
532
533 if (interrupt != NoFault) {
534 this->interrupts->updateIntrInfo(thread.getTC());
535 interrupt->invoke(thread.getTC());
536 }
537 }
538
539 template <class Impl>
540 bool
541 OzoneCPU<Impl>::simPalCheck(int palFunc)
542 {
543 // Need to move this to ISA code
544 // May also need to make this per thread
545 thread.kernelStats->callpal(palFunc, tc);
546
547 switch (palFunc) {
548 case PAL::halt:
549 haltContext(thread.threadId());
550 if (--System::numSystemsRunning == 0)
551 exitSimLoop("all cpus halted");
552 break;
553
554 case PAL::bpt:
555 case PAL::bugchk:
556 if (system->breakpoint())
557 return false;
558 break;
559 }
560
561 return true;
562 }
563
564 template <class Impl>
565 BaseCPU *
566 OzoneCPU<Impl>::OzoneTC::getCpuPtr()
567 {
568 return cpu;
569 }
570
571 template <class Impl>
572 void
573 OzoneCPU<Impl>::OzoneTC::setStatus(Status new_status)
574 {
575 thread->setStatus(new_status);
576 }
577
578 template <class Impl>
579 void
580 OzoneCPU<Impl>::OzoneTC::activate(int delay)
581 {
582 cpu->activateContext(thread->threadId(), delay);
583 }
584
585 /// Set the status to Suspended.
586 template <class Impl>
587 void
588 OzoneCPU<Impl>::OzoneTC::suspend()
589 {
590 cpu->suspendContext(thread->threadId());
591 }
592
593 /// Set the status to Halted.
594 template <class Impl>
595 void
596 OzoneCPU<Impl>::OzoneTC::halt()
597 {
598 cpu->haltContext(thread->threadId());
599 }
600
601 template <class Impl>
602 void
603 OzoneCPU<Impl>::OzoneTC::dumpFuncProfile()
604 {
605 thread->dumpFuncProfile();
606 }
607
608 template <class Impl>
609 void
610 OzoneCPU<Impl>::OzoneTC::takeOverFrom(ThreadContext *old_context)
611 {
612 // some things should already be set up
613 assert(getSystemPtr() == old_context->getSystemPtr());
614 assert(getProcessPtr() == old_context->getProcessPtr());
615
616 // copy over functional state
617 setStatus(old_context->status());
618 copyArchRegs(old_context);
619 setCpuId(old_context->cpuId());
620 setContextId(old_context->contextId());
621
622 setFuncExeInst(old_context->readFuncExeInst());
623 EndQuiesceEvent *other_quiesce = old_context->getQuiesceEvent();
624 if (other_quiesce) {
625 // Point the quiesce event's TC at this TC so that it wakes up
626 // the proper CPU.
627 other_quiesce->tc = this;
628 }
629 if (thread->quiesceEvent) {
630 thread->quiesceEvent->tc = this;
631 }
632
633 // Copy kernel stats pointer from old context.
634 thread->kernelStats = old_context->getKernelStats();
635 // storeCondFailures = 0;
636 cpu->lockFlag = false;
637 #endif
638
639 old_context->setStatus(ThreadContext::Halted);
640 }
641
642 template <class Impl>
643 void
644 OzoneCPU<Impl>::OzoneTC::regStats(const std::string &name)
645 {
646 if (FullSystem) {
647 thread->kernelStats = new TheISA::Kernel::Statistics(cpu->system);
648 thread->kernelStats->regStats(name + ".kern");
649 }
650 }
651
652 template <class Impl>
653 void
654 OzoneCPU<Impl>::OzoneTC::serialize(std::ostream &os)
655 {
656 // Once serialization is added, serialize the quiesce event and
657 // kernel stats. Will need to make sure there aren't multiple
658 // things that serialize them.
659 }
660
661 template <class Impl>
662 void
663 OzoneCPU<Impl>::OzoneTC::unserialize(Checkpoint *cp, const std::string &section)
664 { }
665
666 template <class Impl>
667 EndQuiesceEvent *
668 OzoneCPU<Impl>::OzoneTC::getQuiesceEvent()
669 {
670 return thread->quiesceEvent;
671 }
672
673 template <class Impl>
674 Tick
675 OzoneCPU<Impl>::OzoneTC::readLastActivate()
676 {
677 return thread->lastActivate;
678 }
679
680 template <class Impl>
681 Tick
682 OzoneCPU<Impl>::OzoneTC::readLastSuspend()
683 {
684 return thread->lastSuspend;
685 }
686
687 template <class Impl>
688 void
689 OzoneCPU<Impl>::OzoneTC::profileClear()
690 {
691 thread->profileClear();
692 }
693
694 template <class Impl>
695 void
696 OzoneCPU<Impl>::OzoneTC::profileSample()
697 {
698 thread->profileSample();
699 }
700
701 template <class Impl>
702 int
703 OzoneCPU<Impl>::OzoneTC::threadId()
704 {
705 return thread->threadId();
706 }
707
708 template <class Impl>
709 void
710 OzoneCPU<Impl>::OzoneTC::copyArchRegs(ThreadContext *tc)
711 {
712 thread->PC = tc->readPC();
713 thread->nextPC = tc->readNextPC();
714
715 cpu->frontEnd->setPC(thread->PC);
716 cpu->frontEnd->setNextPC(thread->nextPC);
717
718 // First loop through the integer registers.
719 for (int i = 0; i < TheISA::NumIntRegs; ++i) {
720 /* DPRINTF(OzoneCPU, "Copying over register %i, had data %lli, "
721 "now has data %lli.\n",
722 i, thread->renameTable[i]->readIntResult(),
723 tc->readIntReg(i));
724 */
725 thread->renameTable[i]->setIntResult(tc->readIntReg(i));
726 }
727
728 // Then loop through the floating point registers.
729 for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
730 int fp_idx = i + TheISA::FP_Base_DepTag;
731 thread->renameTable[fp_idx]->setIntResult(tc->readFloatRegBits(i));
732 }
733
734 thread->funcExeInst = tc->readFuncExeInst();
735
736 // Need to copy the TC values into the current rename table,
737 // copy the misc regs.
738 copyMiscRegs(tc, this);
739 }
740
741 template <class Impl>
742 void
743 OzoneCPU<Impl>::OzoneTC::clearArchRegs()
744 {
745 panic("Unimplemented!");
746 }
747
748 template <class Impl>
749 uint64_t
750 OzoneCPU<Impl>::OzoneTC::readIntReg(int reg_idx)
751 {
752 return thread->renameTable[reg_idx]->readIntResult();
753 }
754
755 template <class Impl>
756 double
757 OzoneCPU<Impl>::OzoneTC::readFloatReg(int reg_idx)
758 {
759 int idx = reg_idx + TheISA::FP_Base_DepTag;
760 return thread->renameTable[idx]->readFloatResult();
761 }
762
763 template <class Impl>
764 uint64_t
765 OzoneCPU<Impl>::OzoneTC::readFloatRegBits(int reg_idx)
766 {
767 int idx = reg_idx + TheISA::FP_Base_DepTag;
768 return thread->renameTable[idx]->readIntResult();
769 }
770
771 template <class Impl>
772 void
773 OzoneCPU<Impl>::OzoneTC::setIntReg(int reg_idx, uint64_t val)
774 {
775 thread->renameTable[reg_idx]->setIntResult(val);
776
777 if (!thread->inSyscall) {
778 cpu->squashFromTC();
779 }
780 }
781
782 template <class Impl>
783 void
784 OzoneCPU<Impl>::OzoneTC::setFloatReg(int reg_idx, FloatReg val)
785 {
786 int idx = reg_idx + TheISA::FP_Base_DepTag;
787
788 thread->renameTable[idx]->setDoubleResult(val);
789
790 if (!thread->inSyscall) {
791 cpu->squashFromTC();
792 }
793 }
794
795 template <class Impl>
796 void
797 OzoneCPU<Impl>::OzoneTC::setFloatRegBits(int reg_idx, FloatRegBits val)
798 {
799 panic("Unimplemented!");
800 }
801
802 template <class Impl>
803 void
804 OzoneCPU<Impl>::OzoneTC::setPC(Addr val)
805 {
806 thread->PC = val;
807 cpu->frontEnd->setPC(val);
808
809 if (!thread->inSyscall) {
810 cpu->squashFromTC();
811 }
812 }
813
814 template <class Impl>
815 void
816 OzoneCPU<Impl>::OzoneTC::setNextPC(Addr val)
817 {
818 thread->nextPC = val;
819 cpu->frontEnd->setNextPC(val);
820
821 if (!thread->inSyscall) {
822 cpu->squashFromTC();
823 }
824 }
825
826 template <class Impl>
827 TheISA::MiscReg
828 OzoneCPU<Impl>::OzoneTC::readMiscRegNoEffect(int misc_reg)
829 {
830 return thread->miscRegFile.readRegNoEffect(misc_reg);
831 }
832
833 template <class Impl>
834 TheISA::MiscReg
835 OzoneCPU<Impl>::OzoneTC::readMiscReg(int misc_reg)
836 {
837 return thread->miscRegFile.readReg(misc_reg, this);
838 }
839
840 template <class Impl>
841 void
842 OzoneCPU<Impl>::OzoneTC::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
843 {
844 // Needs to setup a squash event unless we're in syscall mode
845 thread->miscRegFile.setRegNoEffect(misc_reg, val);
846
847 if (!thread->inSyscall) {
848 cpu->squashFromTC();
849 }
850 }
851
852 template <class Impl>
853 void
854 OzoneCPU<Impl>::OzoneTC::setMiscReg(int misc_reg, const MiscReg &val)
855 {
856 // Needs to setup a squash event unless we're in syscall mode
857 thread->miscRegFile.setReg(misc_reg, val, this);
858
859 if (!thread->inSyscall) {
860 cpu->squashFromTC();
861 }
862 }