2 * Copyright (c) 2006 The Regents of The University of Michigan
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.
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.
32 #include "config/full_system.hh"
33 #include "config/use_checker.hh"
35 #include "arch/isa_traits.hh" // For MachInst
36 #include "base/trace.hh"
37 #include "cpu/base.hh"
38 #include "cpu/thread_context.hh"
39 #include "cpu/exetrace.hh"
40 #include "cpu/ozone/cpu.hh"
41 #include "cpu/quiesce_event.hh"
42 #include "cpu/static_inst.hh"
43 #include "sim/sim_object.hh"
44 #include "sim/stats.hh"
47 #include "arch/faults.hh"
48 #include "arch/alpha/osfpal.hh"
49 #include "arch/alpha/tlb.hh"
50 #include "arch/vtophys.hh"
51 #include "base/callback.hh"
52 //#include "base/remote_gdb.hh"
53 #include "cpu/profile.hh"
54 #include "kern/kernel_stats.hh"
55 #include "sim/faults.hh"
56 #include "sim/sim_events.hh"
57 #include "sim/sim_exit.hh"
58 #include "sim/system.hh"
60 #include "sim/process.hh"
64 #include "cpu/checker/thread_context.hh"
67 using namespace TheISA;
72 OzoneCPU<Impl>::trace_data(T data) {
74 traceData->setData(data);
79 OzoneCPU<Impl>::TickEvent::TickEvent(OzoneCPU *c, int w)
80 : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c), width(w)
86 OzoneCPU<Impl>::TickEvent::process()
93 OzoneCPU<Impl>::TickEvent::description()
95 return "OzoneCPU tick event";
99 OzoneCPU<Impl>::OzoneCPU(Params *p)
101 : BaseCPU(p), thread(this, 0), tickEvent(this, p->width),
103 : BaseCPU(p), thread(this, 0, p->workload[0], 0, p->mem),
104 tickEvent(this, p->width),
106 mem(p->mem), comm(5, 5)
108 frontEnd = new FrontEnd(p);
109 backEnd = new BackEnd(p);
115 BaseCPU *temp_checker = p->checker;
116 checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
117 checker->setMemory(mem);
119 checker->setSystem(p->system);
121 checkerTC = new CheckerThreadContext<OzoneTC>(&ozoneTC, checker);
122 thread.tc = checkerTC;
125 panic("Checker enabled but not compiled in!");
129 thread.tc = &ozoneTC;
134 ozoneTC.thread = &thread;
136 thread.inSyscall = false;
138 thread.setStatus(ThreadContext::Suspended);
140 /***** All thread state stuff *****/
144 thread.quiesceEvent = new EndQuiesceEvent(tc);
149 physmem = p->system->physmem;
152 thread.profile = new FunctionProfile(p->system->kernelSymtab);
153 // @todo: This might be better as an ThreadContext instead of OzoneTC
155 new MakeCallback<OzoneTC,
156 &OzoneTC::dumpFuncProfile>(&ozoneTC);
157 registerExitCallback(cb);
160 // let's fill with a dummy node for now so we don't get a segfault
161 // on the first cycle when there's no node available.
162 static ProfileNode dummyNode;
163 thread.profileNode = &dummyNode;
164 thread.profilePC = 3;
167 #endif // !FULL_SYSTEM
172 threadContexts.push_back(tc);
174 frontEnd->setCPU(this);
175 backEnd->setCPU(this);
180 frontEnd->setThreadState(&thread);
181 backEnd->setThreadState(&thread);
183 frontEnd->setCommBuffer(&comm);
184 backEnd->setCommBuffer(&comm);
186 frontEnd->setBackEnd(backEnd);
187 backEnd->setFrontEnd(frontEnd);
189 decoupledFrontEnd = p->decoupledFrontEnd;
193 checkInterrupts = false;
195 for (int i = 0; i < TheISA::TotalNumRegs; ++i) {
196 thread.renameTable[i] = new DynInst(this);
197 thread.renameTable[i]->setResultReady();
200 frontEnd->renameTable.copyFrom(thread.renameTable);
201 backEnd->renameTable.copyFrom(thread.renameTable);
204 /* Use this port to for syscall emulation writes to memory. */
206 TranslatingPort *trans_port;
207 trans_port = new TranslatingPort(csprintf("%s-%d-funcport",
209 p->workload[0]->pTable,
211 mem_port = p->mem->getPort("functional");
212 mem_port->setPeer(trans_port);
213 trans_port->setPeer(mem_port);
214 thread.setMemPort(trans_port);
217 FunctionalPort *phys_port;
218 VirtualPort *virt_port;
219 phys_port = new FunctionalPort(csprintf("%s-%d-funcport",
221 mem_port = system->physmem->getPort("functional");
222 mem_port->setPeer(phys_port);
223 phys_port->setPeer(mem_port);
225 virt_port = new VirtualPort(csprintf("%s-%d-vport",
227 mem_port = system->physmem->getPort("functional");
228 mem_port->setPeer(virt_port);
229 virt_port->setPeer(mem_port);
231 thread.setPhysPort(phys_port);
232 thread.setVirtPort(virt_port);
237 DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n");
240 template <class Impl>
241 OzoneCPU<Impl>::~OzoneCPU()
245 template <class Impl>
247 OzoneCPU<Impl>::switchOut()
250 // Front end needs state from back end, so switch out the back end first.
251 backEnd->switchOut();
252 frontEnd->switchOut();
255 template <class Impl>
257 OzoneCPU<Impl>::signalSwitched()
259 if (++switchCount == 2) {
260 backEnd->doSwitchOut();
261 frontEnd->doSwitchOut();
264 checker->switchOut();
267 _status = SwitchedOut;
268 if (tickEvent.scheduled())
271 assert(switchCount <= 2);
274 template <class Impl>
276 OzoneCPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
278 BaseCPU::takeOverFrom(oldCPU);
280 backEnd->takeOverFrom();
281 frontEnd->takeOverFrom();
282 assert(!tickEvent.scheduled());
284 // @todo: Fix hardcoded number
285 // Clear out any old information in time buffer.
286 for (int i = 0; i < 6; ++i) {
290 // if any of this CPU's ThreadContexts are active, mark the CPU as
291 // running and schedule its tick event.
292 for (int i = 0; i < threadContexts.size(); ++i) {
293 ThreadContext *tc = threadContexts[i];
294 if (tc->status() == ThreadContext::Active &&
295 _status != Running) {
297 tickEvent.schedule(curTick);
300 // Nothing running, change status to reflect that we're no longer
302 if (_status == SwitchedOut) {
307 template <class Impl>
309 OzoneCPU<Impl>::activateContext(int thread_num, int delay)
311 // Eventually change this in SMT.
312 assert(thread_num == 0);
314 assert(_status == Idle);
316 scheduleTickEvent(delay);
318 thread.setStatus(ThreadContext::Active);
319 frontEnd->wakeFromQuiesce();
322 template <class Impl>
324 OzoneCPU<Impl>::suspendContext(int thread_num)
326 // Eventually change this in SMT.
327 assert(thread_num == 0);
328 // @todo: Figure out how to initially set the status properly so
330 // assert(_status == Running);
332 unscheduleTickEvent();
336 template <class Impl>
338 OzoneCPU<Impl>::deallocateContext(int thread_num, int delay)
340 // for now, these are equivalent
341 suspendContext(thread_num);
344 template <class Impl>
346 OzoneCPU<Impl>::haltContext(int thread_num)
348 // for now, these are equivalent
349 suspendContext(thread_num);
352 template <class Impl>
354 OzoneCPU<Impl>::regStats()
356 using namespace Stats;
361 .name(name() + ".num_insts")
362 .desc("Number of instructions executed")
366 .name(name() + ".num_refs")
367 .desc("Number of memory references")
371 .name(name() + ".not_idle_fraction")
372 .desc("Percentage of non-idle cycles")
376 .name(name() + ".idle_fraction")
377 .desc("Percentage of idle cycles")
381 .name(name() + ".quiesce_cycles")
382 .desc("Number of cycles spent in quiesce")
385 idleFraction = constant(1.0) - notIdleFraction;
387 frontEnd->regStats();
391 template <class Impl>
393 OzoneCPU<Impl>::resetStats()
395 startNumInst = numInst;
396 notIdleFraction = (_status != Idle);
399 template <class Impl>
401 OzoneCPU<Impl>::init()
405 // Mark this as in syscall so it won't need to squash
406 thread.inSyscall = true;
408 for (int i = 0; i < threadContexts.size(); ++i) {
409 ThreadContext *tc = threadContexts[i];
411 // initialize CPU, including PC
412 TheISA::initCPU(tc, tc->readCpuId());
415 frontEnd->renameTable.copyFrom(thread.renameTable);
416 backEnd->renameTable.copyFrom(thread.renameTable);
418 thread.inSyscall = false;
421 template <class Impl>
423 OzoneCPU<Impl>::getPort(const std::string &if_name, int idx)
425 if (if_name == "dcache_port")
426 return backEnd->getDcachePort();
427 else if (if_name == "icache_port")
428 return frontEnd->getIcachePort();
430 panic("No Such Port\n");
433 template <class Impl>
435 OzoneCPU<Impl>::serialize(std::ostream &os)
437 BaseCPU::serialize(os);
438 SERIALIZE_ENUM(_status);
439 nameOut(os, csprintf("%s.tc", name()));
440 ozoneTC.serialize(os);
441 nameOut(os, csprintf("%s.tickEvent", name()));
442 tickEvent.serialize(os);
445 template <class Impl>
447 OzoneCPU<Impl>::unserialize(Checkpoint *cp, const std::string §ion)
449 BaseCPU::unserialize(cp, section);
450 UNSERIALIZE_ENUM(_status);
451 ozoneTC.unserialize(cp, csprintf("%s.tc", section));
452 tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
455 template <class Impl>
457 OzoneCPU<Impl>::copySrcTranslate(Addr src)
459 panic("Copy not implemented!\n");
462 static bool no_warn = true;
463 int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
464 // Only support block sizes of 64 atm.
465 assert(blk_size == 64);
466 int offset = src & (blk_size - 1);
468 // Make sure block doesn't span page
470 (src & TheISA::PageMask) != ((src + blk_size) & TheISA::PageMask) &&
471 (src >> 40) != 0xfffffc) {
472 warn("Copied block source spans pages %x.", src);
476 memReq->reset(src & ~(blk_size - 1), blk_size);
478 // translate to physical address
479 Fault fault = tc->translateDataReadReq(memReq);
481 assert(fault != Alignment_Fault);
483 if (fault == NoFault) {
484 tc->copySrcAddr = src;
485 tc->copySrcPhysAddr = memReq->paddr + offset;
488 tc->copySrcPhysAddr = 0;
494 template <class Impl>
496 OzoneCPU<Impl>::copy(Addr dest)
498 panic("Copy not implemented!\n");
501 static bool no_warn = true;
502 int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
503 // Only support block sizes of 64 atm.
504 assert(blk_size == 64);
505 uint8_t data[blk_size];
506 //assert(tc->copySrcAddr);
507 int offset = dest & (blk_size - 1);
509 // Make sure block doesn't span page
511 (dest & TheISA::PageMask) != ((dest + blk_size) & TheISA::PageMask) &&
512 (dest >> 40) != 0xfffffc) {
514 warn("Copied block destination spans pages %x. ", dest);
517 memReq->reset(dest & ~(blk_size -1), blk_size);
518 // translate to physical address
519 Fault fault = tc->translateDataWriteReq(memReq);
521 assert(fault != Alignment_Fault);
523 if (fault == NoFault) {
524 Addr dest_addr = memReq->paddr + offset;
525 // Need to read straight from memory since we have more than 8 bytes.
526 memReq->paddr = tc->copySrcPhysAddr;
527 tc->mem->read(memReq, data);
528 memReq->paddr = dest_addr;
529 tc->mem->write(memReq, data);
530 if (dcacheInterface) {
532 memReq->completionEvent = NULL;
533 memReq->paddr = tc->copySrcPhysAddr;
534 memReq->dest = dest_addr;
536 memReq->time = curTick;
537 dcacheInterface->access(memReq);
545 template <class Impl>
547 OzoneCPU<Impl>::dbg_vtophys(Addr addr)
549 return vtophys(tc, addr);
551 #endif // FULL_SYSTEM
554 template <class Impl>
556 OzoneCPU<Impl>::post_interrupt(int int_num, int index)
558 BaseCPU::post_interrupt(int_num, index);
560 if (_status == Idle) {
561 DPRINTF(IPI,"Suspended Processor awoke\n");
562 // thread.activate();
563 // Hack for now. Otherwise might have to go through the tc, or
564 // I need to figure out what's the right thing to call.
565 activateContext(thread.readTid(), 1);
568 #endif // FULL_SYSTEM
570 /* start simulation, program loaded, processor precise state initialized */
571 template <class Impl>
573 OzoneCPU<Impl>::tick()
575 DPRINTF(OzoneCPU, "\n\nOzoneCPU: Ticking cpu.\n");
578 thread.renameTable[ZeroReg]->setIntResult(0);
579 thread.renameTable[ZeroReg+TheISA::FP_Base_DepTag]->
580 setDoubleResult(0.0);
586 // check for instruction-count-based events
587 comInstEventQueue[0]->serviceEvents(numInst);
589 if (!tickEvent.scheduled() && _status == Running)
590 tickEvent.schedule(curTick + cycles(1));
593 template <class Impl>
595 OzoneCPU<Impl>::squashFromTC()
597 thread.inSyscall = true;
598 backEnd->generateTCEvent();
602 template <class Impl>
604 OzoneCPU<Impl>::syscall(uint64_t &callnum)
606 // Not sure this copy is needed, depending on how the TC proxy is made.
607 thread.renameTable.copyFrom(backEnd->renameTable);
609 thread.inSyscall = true;
611 thread.funcExeInst++;
613 DPRINTF(OzoneCPU, "FuncExeInst: %i\n", thread.funcExeInst);
615 thread.process->syscall(callnum, tc);
617 thread.funcExeInst--;
619 thread.inSyscall = false;
621 frontEnd->renameTable.copyFrom(thread.renameTable);
622 backEnd->renameTable.copyFrom(thread.renameTable);
625 template <class Impl>
627 OzoneCPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
629 // check for error condition. Alpha syscall convention is to
630 // indicate success/failure in reg a3 (r19) and put the
631 // return value itself in the standard return value reg (v0).
632 if (return_value.successful()) {
634 thread.renameTable[SyscallSuccessReg]->setIntResult(0);
635 thread.renameTable[ReturnValueReg]->setIntResult(
636 return_value.value());
638 // got an error, return details
639 thread.renameTable[SyscallSuccessReg]->setIntResult((IntReg) -1);
640 thread.renameTable[ReturnValueReg]->setIntResult(
641 -return_value.value());
645 template <class Impl>
647 OzoneCPU<Impl>::hwrei()
649 // Need to move this to ISA code
650 // May also need to make this per thread
653 lockAddrList.clear();
654 thread.kernelStats->hwrei();
656 checkInterrupts = true;
658 // FIXME: XXX check for interrupts? XXX
662 template <class Impl>
664 OzoneCPU<Impl>::processInterrupts()
666 // Check for interrupts here. For now can copy the code that
667 // exists within isa_fullsys_traits.hh. Also assume that thread 0
668 // is the one that handles the interrupts.
670 // Check if there are any outstanding interrupts
671 //Handle the interrupts
675 checkInterrupts = false;
677 if (thread.readMiscReg(IPR_ASTRR))
678 panic("asynchronous traps not implemented\n");
680 if (thread.readMiscReg(IPR_SIRR)) {
681 for (int i = INTLEVEL_SOFTWARE_MIN;
682 i < INTLEVEL_SOFTWARE_MAX; i++) {
683 if (thread.readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
684 // See table 4-19 of the 21164 hardware reference
685 ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
686 summary |= (ULL(1) << i);
691 uint64_t interrupts = intr_status();
694 for (int i = INTLEVEL_EXTERNAL_MIN;
695 i < INTLEVEL_EXTERNAL_MAX; i++) {
696 if (interrupts & (ULL(1) << i)) {
697 // See table 4-19 of the 21164 hardware reference
699 summary |= (ULL(1) << i);
704 if (ipl && ipl > thread.readMiscReg(IPR_IPLR)) {
705 thread.setMiscReg(IPR_ISR, summary);
706 thread.setMiscReg(IPR_INTID, ipl);
707 // @todo: Make this more transparent
709 checker->threadBase()->setMiscReg(IPR_ISR, summary);
710 checker->threadBase()->setMiscReg(IPR_INTID, ipl);
712 Fault fault = new InterruptFault;
713 fault->invoke(thread.getTC());
714 DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
715 thread.readMiscReg(IPR_IPLR), ipl, summary);
719 template <class Impl>
721 OzoneCPU<Impl>::simPalCheck(int palFunc)
723 // Need to move this to ISA code
724 // May also need to make this per thread
725 thread.kernelStats->callpal(palFunc, tc);
729 haltContext(thread.readTid());
730 if (--System::numSystemsRunning == 0)
731 exitSimLoop("all cpus halted");
736 if (system->breakpoint())
745 template <class Impl>
747 OzoneCPU<Impl>::OzoneTC::getCpuPtr()
752 template <class Impl>
754 OzoneCPU<Impl>::OzoneTC::setCpuId(int id)
757 thread->setCpuId(id);
761 template <class Impl>
763 OzoneCPU<Impl>::OzoneTC::delVirtPort(VirtualPort *vp)
765 delete vp->getPeer();
770 template <class Impl>
772 OzoneCPU<Impl>::OzoneTC::setStatus(Status new_status)
774 thread->setStatus(new_status);
777 template <class Impl>
779 OzoneCPU<Impl>::OzoneTC::activate(int delay)
781 cpu->activateContext(thread->readTid(), delay);
784 /// Set the status to Suspended.
785 template <class Impl>
787 OzoneCPU<Impl>::OzoneTC::suspend()
789 cpu->suspendContext(thread->readTid());
792 /// Set the status to Unallocated.
793 template <class Impl>
795 OzoneCPU<Impl>::OzoneTC::deallocate(int delay)
797 cpu->deallocateContext(thread->readTid(), delay);
800 /// Set the status to Halted.
801 template <class Impl>
803 OzoneCPU<Impl>::OzoneTC::halt()
805 cpu->haltContext(thread->readTid());
809 template <class Impl>
811 OzoneCPU<Impl>::OzoneTC::dumpFuncProfile()
815 template <class Impl>
817 OzoneCPU<Impl>::OzoneTC::takeOverFrom(ThreadContext *old_context)
819 // some things should already be set up
821 assert(getSystemPtr() == old_context->getSystemPtr());
823 assert(getProcessPtr() == old_context->getProcessPtr());
826 // copy over functional state
827 setStatus(old_context->status());
828 copyArchRegs(old_context);
829 setCpuId(old_context->readCpuId());
832 setFuncExeInst(old_context->readFuncExeInst());
834 EndQuiesceEvent *other_quiesce = old_context->getQuiesceEvent();
836 // Point the quiesce event's TC at this TC so that it wakes up
838 other_quiesce->tc = this;
840 if (thread->quiesceEvent) {
841 thread->quiesceEvent->tc = this;
844 thread->kernelStats = old_context->getKernelStats();
845 // storeCondFailures = 0;
846 cpu->lockFlag = false;
849 old_context->setStatus(ThreadContext::Unallocated);
852 template <class Impl>
854 OzoneCPU<Impl>::OzoneTC::regStats(const std::string &name)
857 thread->kernelStats = new Kernel::Statistics(cpu->system);
858 thread->kernelStats->regStats(name + ".kern");
862 template <class Impl>
864 OzoneCPU<Impl>::OzoneTC::serialize(std::ostream &os)
867 template <class Impl>
869 OzoneCPU<Impl>::OzoneTC::unserialize(Checkpoint *cp, const std::string §ion)
873 template <class Impl>
875 OzoneCPU<Impl>::OzoneTC::getQuiesceEvent()
877 return thread->quiesceEvent;
880 template <class Impl>
882 OzoneCPU<Impl>::OzoneTC::readLastActivate()
884 return thread->lastActivate;
887 template <class Impl>
889 OzoneCPU<Impl>::OzoneTC::readLastSuspend()
891 return thread->lastSuspend;
894 template <class Impl>
896 OzoneCPU<Impl>::OzoneTC::profileClear()
899 thread->profile->clear();
902 template <class Impl>
904 OzoneCPU<Impl>::OzoneTC::profileSample()
907 thread->profile->sample(thread->profileNode, thread->profilePC);
911 template <class Impl>
913 OzoneCPU<Impl>::OzoneTC::getThreadNum()
915 return thread->readTid();
918 // Also somewhat obnoxious. Really only used for the TLB fault.
919 template <class Impl>
921 OzoneCPU<Impl>::OzoneTC::getInst()
923 return thread->getInst();
926 template <class Impl>
928 OzoneCPU<Impl>::OzoneTC::copyArchRegs(ThreadContext *tc)
930 thread->PC = tc->readPC();
931 thread->nextPC = tc->readNextPC();
933 cpu->frontEnd->setPC(thread->PC);
934 cpu->frontEnd->setNextPC(thread->nextPC);
936 for (int i = 0; i < TheISA::TotalNumRegs; ++i) {
937 if (i < TheISA::FP_Base_DepTag) {
938 thread->renameTable[i]->setIntResult(tc->readIntReg(i));
939 } else if (i < (TheISA::FP_Base_DepTag + TheISA::NumFloatRegs)) {
940 int fp_idx = i - TheISA::FP_Base_DepTag;
941 thread->renameTable[i]->setDoubleResult(
942 tc->readFloatReg(fp_idx, 64));
947 thread->funcExeInst = tc->readFuncExeInst();
950 // Need to copy the TC values into the current rename table,
951 // copy the misc regs.
952 copyMiscRegs(tc, this);
955 template <class Impl>
957 OzoneCPU<Impl>::OzoneTC::clearArchRegs()
959 panic("Unimplemented!");
962 template <class Impl>
964 OzoneCPU<Impl>::OzoneTC::readIntReg(int reg_idx)
966 return thread->renameTable[reg_idx]->readIntResult();
969 template <class Impl>
971 OzoneCPU<Impl>::OzoneTC::readFloatReg(int reg_idx, int width)
973 int idx = reg_idx + TheISA::FP_Base_DepTag;
976 return thread->renameTable[idx]->readFloatResult();
978 return thread->renameTable[idx]->readDoubleResult();
980 panic("Unsupported width!");
985 template <class Impl>
987 OzoneCPU<Impl>::OzoneTC::readFloatReg(int reg_idx)
989 int idx = reg_idx + TheISA::FP_Base_DepTag;
990 return thread->renameTable[idx]->readFloatResult();
993 template <class Impl>
995 OzoneCPU<Impl>::OzoneTC::readFloatRegBits(int reg_idx, int width)
997 int idx = reg_idx + TheISA::FP_Base_DepTag;
998 return thread->renameTable[idx]->readIntResult();
1001 template <class Impl>
1003 OzoneCPU<Impl>::OzoneTC::readFloatRegBits(int reg_idx)
1005 int idx = reg_idx + TheISA::FP_Base_DepTag;
1006 return thread->renameTable[idx]->readIntResult();
1009 template <class Impl>
1011 OzoneCPU<Impl>::OzoneTC::setIntReg(int reg_idx, uint64_t val)
1013 thread->renameTable[reg_idx]->setIntResult(val);
1015 if (!thread->inSyscall) {
1016 cpu->squashFromTC();
1020 template <class Impl>
1022 OzoneCPU<Impl>::OzoneTC::setFloatReg(int reg_idx, FloatReg val, int width)
1024 int idx = reg_idx + TheISA::FP_Base_DepTag;
1027 panic("Unimplemented!");
1030 thread->renameTable[idx]->setDoubleResult(val);
1033 panic("Unsupported width!");
1036 if (!thread->inSyscall) {
1037 cpu->squashFromTC();
1041 template <class Impl>
1043 OzoneCPU<Impl>::OzoneTC::setFloatReg(int reg_idx, FloatReg val)
1045 int idx = reg_idx + TheISA::FP_Base_DepTag;
1047 thread->renameTable[idx]->setDoubleResult(val);
1049 if (!thread->inSyscall) {
1050 cpu->squashFromTC();
1054 template <class Impl>
1056 OzoneCPU<Impl>::OzoneTC::setFloatRegBits(int reg_idx, FloatRegBits val,
1059 panic("Unimplemented!");
1062 template <class Impl>
1064 OzoneCPU<Impl>::OzoneTC::setFloatRegBits(int reg_idx, FloatRegBits val)
1066 panic("Unimplemented!");
1069 template <class Impl>
1071 OzoneCPU<Impl>::OzoneTC::setPC(Addr val)
1074 cpu->frontEnd->setPC(val);
1076 if (!thread->inSyscall) {
1077 cpu->squashFromTC();
1081 template <class Impl>
1083 OzoneCPU<Impl>::OzoneTC::setNextPC(Addr val)
1085 thread->nextPC = val;
1086 cpu->frontEnd->setNextPC(val);
1088 if (!thread->inSyscall) {
1089 cpu->squashFromTC();
1093 template <class Impl>
1095 OzoneCPU<Impl>::OzoneTC::readMiscReg(int misc_reg)
1097 return thread->miscRegFile.readReg(misc_reg);
1100 template <class Impl>
1102 OzoneCPU<Impl>::OzoneTC::readMiscRegWithEffect(int misc_reg, Fault &fault)
1104 return thread->miscRegFile.readRegWithEffect(misc_reg,
1108 template <class Impl>
1110 OzoneCPU<Impl>::OzoneTC::setMiscReg(int misc_reg, const MiscReg &val)
1112 // Needs to setup a squash event unless we're in syscall mode
1113 Fault ret_fault = thread->miscRegFile.setReg(misc_reg, val);
1115 if (!thread->inSyscall) {
1116 cpu->squashFromTC();
1122 template <class Impl>
1124 OzoneCPU<Impl>::OzoneTC::setMiscRegWithEffect(int misc_reg, const MiscReg &val)
1126 // Needs to setup a squash event unless we're in syscall mode
1127 Fault ret_fault = thread->miscRegFile.setRegWithEffect(misc_reg, val,
1130 if (!thread->inSyscall) {
1131 cpu->squashFromTC();