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 "arch/isa_traits.hh" // For MachInst
33 #include "base/trace.hh"
34 #include "config/full_system.hh"
35 #include "cpu/base.hh"
36 #include "cpu/checker/exec_context.hh"
37 #include "cpu/exec_context.hh"
38 #include "cpu/exetrace.hh"
39 #include "cpu/ozone/cpu.hh"
40 #include "cpu/quiesce_event.hh"
41 #include "cpu/static_inst.hh"
42 //#include "mem/base_mem.hh"
43 #include "mem/mem_interface.hh"
44 #include "sim/sim_object.hh"
45 #include "sim/stats.hh"
48 #include "arch/faults.hh"
49 #include "arch/alpha/osfpal.hh"
50 #include "arch/alpha/tlb.hh"
51 #include "arch/vtophys.hh"
52 #include "base/callback.hh"
53 //#include "base/remote_gdb.hh"
54 #include "cpu/profile.hh"
55 #include "kern/kernel_stats.hh"
56 #include "mem/functional/memory_control.hh"
57 #include "mem/functional/physical.hh"
58 #include "sim/faults.hh"
59 #include "sim/sim_events.hh"
60 #include "sim/sim_exit.hh"
61 #include "sim/system.hh"
63 #include "mem/functional/functional.hh"
64 #include "sim/process.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, p->mem), tickEvent(this, p->width),
104 : BaseCPU(p), thread(this, 0, p->workload[0], 0), tickEvent(this, p->width),
105 mem(p->workload[0]->getMemory()),
109 frontEnd = new FrontEnd(p);
110 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 checkerXC = new CheckerExecContext<OzoneXC>(&ozoneXC, checker);
122 thread.xcProxy = checkerXC;
126 thread.xcProxy = &ozoneXC;
131 ozoneXC.thread = &thread;
133 thread.inSyscall = false;
135 thread.setStatus(ExecContext::Suspended);
137 /***** All thread state stuff *****/
142 thread.quiesceEvent = new EndQuiesceEvent(xcProxy);
147 memctrl = p->system->memctrl;
148 physmem = p->system->physmem;
151 thread.profile = new FunctionProfile(p->system->kernelSymtab);
152 // @todo: This might be better as an ExecContext instead of OzoneXC
154 new MakeCallback<OzoneXC,
155 &OzoneXC::dumpFuncProfile>(&ozoneXC);
156 registerExitCallback(cb);
159 // let's fill with a dummy node for now so we don't get a segfault
160 // on the first cycle when there's no node available.
161 static ProfileNode dummyNode;
162 thread.profileNode = &dummyNode;
163 thread.profilePC = 3;
167 thread.process = p->workload[0];
169 #endif // !FULL_SYSTEM
174 execContexts.push_back(xcProxy);
176 frontEnd->setCPU(this);
177 backEnd->setCPU(this);
179 frontEnd->setXC(xcProxy);
180 backEnd->setXC(xcProxy);
182 frontEnd->setThreadState(&thread);
183 backEnd->setThreadState(&thread);
185 frontEnd->setCommBuffer(&comm);
186 backEnd->setCommBuffer(&comm);
188 frontEnd->setBackEnd(backEnd);
189 backEnd->setFrontEnd(frontEnd);
191 decoupledFrontEnd = p->decoupledFrontEnd;
195 checkInterrupts = false;
197 for (int i = 0; i < TheISA::TotalNumRegs; ++i) {
198 thread.renameTable[i] = new DynInst(this);
199 thread.renameTable[i]->setResultReady();
202 frontEnd->renameTable.copyFrom(thread.renameTable);
203 backEnd->renameTable.copyFrom(thread.renameTable);
206 // pTable = p->pTable;
211 DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n");
214 template <class Impl>
215 OzoneCPU<Impl>::~OzoneCPU()
219 template <class Impl>
221 OzoneCPU<Impl>::switchOut(Sampler *_sampler)
225 // Front end needs state from back end, so switch out the back end first.
226 backEnd->switchOut();
227 frontEnd->switchOut();
230 template <class Impl>
232 OzoneCPU<Impl>::signalSwitched()
234 if (++switchCount == 2) {
235 backEnd->doSwitchOut();
236 frontEnd->doSwitchOut();
238 checker->switchOut(sampler);
239 _status = SwitchedOut;
240 if (tickEvent.scheduled())
242 sampler->signalSwitched();
244 assert(switchCount <= 2);
247 template <class Impl>
249 OzoneCPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
251 BaseCPU::takeOverFrom(oldCPU);
253 backEnd->takeOverFrom();
254 frontEnd->takeOverFrom();
255 assert(!tickEvent.scheduled());
257 // @todo: Fix hardcoded number
258 // Clear out any old information in time buffer.
259 for (int i = 0; i < 6; ++i) {
263 // if any of this CPU's ExecContexts are active, mark the CPU as
264 // running and schedule its tick event.
265 for (int i = 0; i < execContexts.size(); ++i) {
266 ExecContext *xc = execContexts[i];
267 if (xc->status() == ExecContext::Active &&
268 _status != Running) {
270 tickEvent.schedule(curTick);
273 // Nothing running, change status to reflect that we're no longer
275 if (_status == SwitchedOut) {
280 template <class Impl>
282 OzoneCPU<Impl>::activateContext(int thread_num, int delay)
284 // Eventually change this in SMT.
285 assert(thread_num == 0);
287 assert(_status == Idle);
289 scheduleTickEvent(delay);
291 thread._status = ExecContext::Active;
292 frontEnd->wakeFromQuiesce();
295 template <class Impl>
297 OzoneCPU<Impl>::suspendContext(int thread_num)
299 // Eventually change this in SMT.
300 assert(thread_num == 0);
301 // @todo: Figure out how to initially set the status properly so
303 // assert(_status == Running);
305 unscheduleTickEvent();
309 template <class Impl>
311 OzoneCPU<Impl>::deallocateContext(int thread_num)
313 // for now, these are equivalent
314 suspendContext(thread_num);
317 template <class Impl>
319 OzoneCPU<Impl>::haltContext(int thread_num)
321 // for now, these are equivalent
322 suspendContext(thread_num);
325 template <class Impl>
327 OzoneCPU<Impl>::regStats()
329 using namespace Stats;
334 .name(name() + ".num_insts")
335 .desc("Number of instructions executed")
339 .name(name() + ".num_refs")
340 .desc("Number of memory references")
344 .name(name() + ".not_idle_fraction")
345 .desc("Percentage of non-idle cycles")
349 .name(name() + ".idle_fraction")
350 .desc("Percentage of idle cycles")
354 .name(name() + ".quiesce_cycles")
355 .desc("Number of cycles spent in quiesce")
358 idleFraction = constant(1.0) - notIdleFraction;
360 frontEnd->regStats();
364 template <class Impl>
366 OzoneCPU<Impl>::resetStats()
368 startNumInst = numInst;
369 notIdleFraction = (_status != Idle);
372 template <class Impl>
374 OzoneCPU<Impl>::init()
378 // Mark this as in syscall so it won't need to squash
379 thread.inSyscall = true;
381 for (int i = 0; i < execContexts.size(); ++i) {
382 ExecContext *xc = execContexts[i];
384 // initialize CPU, including PC
385 TheISA::initCPU(xc, xc->readCpuId());
388 frontEnd->renameTable.copyFrom(thread.renameTable);
389 backEnd->renameTable.copyFrom(thread.renameTable);
391 thread.inSyscall = false;
394 template <class Impl>
396 OzoneCPU<Impl>::serialize(std::ostream &os)
398 BaseCPU::serialize(os);
399 SERIALIZE_ENUM(_status);
400 nameOut(os, csprintf("%s.xc", name()));
401 ozoneXC.serialize(os);
402 nameOut(os, csprintf("%s.tickEvent", name()));
403 tickEvent.serialize(os);
406 template <class Impl>
408 OzoneCPU<Impl>::unserialize(Checkpoint *cp, const std::string §ion)
410 BaseCPU::unserialize(cp, section);
411 UNSERIALIZE_ENUM(_status);
412 ozoneXC.unserialize(cp, csprintf("%s.xc", section));
413 tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
416 template <class Impl>
418 OzoneCPU<Impl>::copySrcTranslate(Addr src)
420 panic("Copy not implemented!\n");
423 static bool no_warn = true;
424 int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
425 // Only support block sizes of 64 atm.
426 assert(blk_size == 64);
427 int offset = src & (blk_size - 1);
429 // Make sure block doesn't span page
431 (src & TheISA::PageMask) != ((src + blk_size) & TheISA::PageMask) &&
432 (src >> 40) != 0xfffffc) {
433 warn("Copied block source spans pages %x.", src);
437 memReq->reset(src & ~(blk_size - 1), blk_size);
439 // translate to physical address
440 Fault fault = xc->translateDataReadReq(memReq);
442 assert(fault != Alignment_Fault);
444 if (fault == NoFault) {
445 xc->copySrcAddr = src;
446 xc->copySrcPhysAddr = memReq->paddr + offset;
449 xc->copySrcPhysAddr = 0;
455 template <class Impl>
457 OzoneCPU<Impl>::copy(Addr dest)
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 uint8_t data[blk_size];
467 //assert(xc->copySrcAddr);
468 int offset = dest & (blk_size - 1);
470 // Make sure block doesn't span page
472 (dest & TheISA::PageMask) != ((dest + blk_size) & TheISA::PageMask) &&
473 (dest >> 40) != 0xfffffc) {
475 warn("Copied block destination spans pages %x. ", dest);
478 memReq->reset(dest & ~(blk_size -1), blk_size);
479 // translate to physical address
480 Fault fault = xc->translateDataWriteReq(memReq);
482 assert(fault != Alignment_Fault);
484 if (fault == NoFault) {
485 Addr dest_addr = memReq->paddr + offset;
486 // Need to read straight from memory since we have more than 8 bytes.
487 memReq->paddr = xc->copySrcPhysAddr;
488 xc->mem->read(memReq, data);
489 memReq->paddr = dest_addr;
490 xc->mem->write(memReq, data);
491 if (dcacheInterface) {
493 memReq->completionEvent = NULL;
494 memReq->paddr = xc->copySrcPhysAddr;
495 memReq->dest = dest_addr;
497 memReq->time = curTick;
498 dcacheInterface->access(memReq);
506 template <class Impl>
508 OzoneCPU<Impl>::dbg_vtophys(Addr addr)
510 return vtophys(xcProxy, addr);
512 #endif // FULL_SYSTEM
515 template <class Impl>
517 OzoneCPU<Impl>::post_interrupt(int int_num, int index)
519 BaseCPU::post_interrupt(int_num, index);
521 if (_status == Idle) {
522 DPRINTF(IPI,"Suspended Processor awoke\n");
523 // thread.activate();
524 // Hack for now. Otherwise might have to go through the xcProxy, or
525 // I need to figure out what's the right thing to call.
526 activateContext(thread.tid, 1);
529 #endif // FULL_SYSTEM
531 /* start simulation, program loaded, processor precise state initialized */
532 template <class Impl>
534 OzoneCPU<Impl>::tick()
536 DPRINTF(OzoneCPU, "\n\nOzoneCPU: Ticking cpu.\n");
539 thread.renameTable[ZeroReg]->setIntResult(0);
540 thread.renameTable[ZeroReg+TheISA::FP_Base_DepTag]->
541 setDoubleResult(0.0);
547 // check for instruction-count-based events
548 comInstEventQueue[0]->serviceEvents(numInst);
550 if (!tickEvent.scheduled() && _status == Running)
551 tickEvent.schedule(curTick + cycles(1));
554 template <class Impl>
556 OzoneCPU<Impl>::squashFromXC()
558 thread.inSyscall = true;
559 backEnd->generateXCEvent();
563 template <class Impl>
565 OzoneCPU<Impl>::syscall()
567 // Not sure this copy is needed, depending on how the XC proxy is made.
568 thread.renameTable.copyFrom(backEnd->renameTable);
570 thread.inSyscall = true;
572 thread.funcExeInst++;
574 DPRINTF(OzoneCPU, "FuncExeInst: %i\n", thread.funcExeInst);
576 thread.process->syscall(xcProxy);
578 thread.funcExeInst--;
580 thread.inSyscall = false;
582 frontEnd->renameTable.copyFrom(thread.renameTable);
583 backEnd->renameTable.copyFrom(thread.renameTable);
586 template <class Impl>
588 OzoneCPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
590 // check for error condition. Alpha syscall convention is to
591 // indicate success/failure in reg a3 (r19) and put the
592 // return value itself in the standard return value reg (v0).
593 if (return_value.successful()) {
595 thread.renameTable[SyscallSuccessReg]->setIntResult(0);
596 thread.renameTable[ReturnValueReg]->setIntResult(
597 return_value.value());
599 // got an error, return details
600 thread.renameTable[SyscallSuccessReg]->setIntResult((IntReg) -1);
601 thread.renameTable[ReturnValueReg]->setIntResult(
602 -return_value.value());
606 template <class Impl>
608 OzoneCPU<Impl>::hwrei()
610 // Need to move this to ISA code
611 // May also need to make this per thread
614 lockAddrList.clear();
615 thread.kernelStats->hwrei();
617 checkInterrupts = true;
619 // FIXME: XXX check for interrupts? XXX
623 template <class Impl>
625 OzoneCPU<Impl>::processInterrupts()
627 // Check for interrupts here. For now can copy the code that
628 // exists within isa_fullsys_traits.hh. Also assume that thread 0
629 // is the one that handles the interrupts.
631 // Check if there are any outstanding interrupts
632 //Handle the interrupts
636 checkInterrupts = false;
638 if (thread.readMiscReg(IPR_ASTRR))
639 panic("asynchronous traps not implemented\n");
641 if (thread.readMiscReg(IPR_SIRR)) {
642 for (int i = INTLEVEL_SOFTWARE_MIN;
643 i < INTLEVEL_SOFTWARE_MAX; i++) {
644 if (thread.readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
645 // See table 4-19 of the 21164 hardware reference
646 ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
647 summary |= (ULL(1) << i);
652 uint64_t interrupts = intr_status();
655 for (int i = INTLEVEL_EXTERNAL_MIN;
656 i < INTLEVEL_EXTERNAL_MAX; i++) {
657 if (interrupts & (ULL(1) << i)) {
658 // See table 4-19 of the 21164 hardware reference
660 summary |= (ULL(1) << i);
665 if (ipl && ipl > thread.readMiscReg(IPR_IPLR)) {
666 thread.setMiscReg(IPR_ISR, summary);
667 thread.setMiscReg(IPR_INTID, ipl);
668 // @todo: Make this more transparent
670 checker->cpuXCBase()->setMiscReg(IPR_ISR, summary);
671 checker->cpuXCBase()->setMiscReg(IPR_INTID, ipl);
673 Fault fault = new InterruptFault;
674 fault->invoke(thread.getXCProxy());
675 DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
676 thread.readMiscReg(IPR_IPLR), ipl, summary);
680 template <class Impl>
682 OzoneCPU<Impl>::simPalCheck(int palFunc)
684 // Need to move this to ISA code
685 // May also need to make this per thread
686 thread.kernelStats->callpal(palFunc, xcProxy);
690 haltContext(thread.tid);
691 if (--System::numSystemsRunning == 0)
692 new SimExitEvent("all cpus halted");
697 if (system->breakpoint())
706 template <class Impl>
708 OzoneCPU<Impl>::OzoneXC::getCpuPtr()
713 template <class Impl>
715 OzoneCPU<Impl>::OzoneXC::setCpuId(int id)
721 template <class Impl>
723 OzoneCPU<Impl>::OzoneXC::setStatus(Status new_status)
725 thread->_status = new_status;
728 template <class Impl>
730 OzoneCPU<Impl>::OzoneXC::activate(int delay)
732 cpu->activateContext(thread->tid, delay);
735 /// Set the status to Suspended.
736 template <class Impl>
738 OzoneCPU<Impl>::OzoneXC::suspend()
740 cpu->suspendContext(thread->tid);
743 /// Set the status to Unallocated.
744 template <class Impl>
746 OzoneCPU<Impl>::OzoneXC::deallocate()
748 cpu->deallocateContext(thread->tid);
751 /// Set the status to Halted.
752 template <class Impl>
754 OzoneCPU<Impl>::OzoneXC::halt()
756 cpu->haltContext(thread->tid);
760 template <class Impl>
762 OzoneCPU<Impl>::OzoneXC::dumpFuncProfile()
766 template <class Impl>
768 OzoneCPU<Impl>::OzoneXC::takeOverFrom(ExecContext *old_context)
770 // some things should already be set up
771 assert(getMemPtr() == old_context->getMemPtr());
773 assert(getSystemPtr() == old_context->getSystemPtr());
775 assert(getProcessPtr() == old_context->getProcessPtr());
778 // copy over functional state
779 setStatus(old_context->status());
780 copyArchRegs(old_context);
781 setCpuId(old_context->readCpuId());
784 setFuncExeInst(old_context->readFuncExeInst());
786 EndQuiesceEvent *other_quiesce = old_context->getQuiesceEvent();
788 // Point the quiesce event's XC at this XC so that it wakes up
790 other_quiesce->xc = this;
792 if (thread->quiesceEvent) {
793 thread->quiesceEvent->xc = this;
796 thread->kernelStats = old_context->getKernelStats();
797 // storeCondFailures = 0;
798 cpu->lockFlag = false;
801 old_context->setStatus(ExecContext::Unallocated);
804 template <class Impl>
806 OzoneCPU<Impl>::OzoneXC::regStats(const std::string &name)
809 thread->kernelStats = new Kernel::Statistics(cpu->system);
810 thread->kernelStats->regStats(name + ".kern");
814 template <class Impl>
816 OzoneCPU<Impl>::OzoneXC::serialize(std::ostream &os)
819 template <class Impl>
821 OzoneCPU<Impl>::OzoneXC::unserialize(Checkpoint *cp, const std::string §ion)
825 template <class Impl>
827 OzoneCPU<Impl>::OzoneXC::getQuiesceEvent()
829 return thread->quiesceEvent;
832 template <class Impl>
834 OzoneCPU<Impl>::OzoneXC::readLastActivate()
836 return thread->lastActivate;
839 template <class Impl>
841 OzoneCPU<Impl>::OzoneXC::readLastSuspend()
843 return thread->lastSuspend;
846 template <class Impl>
848 OzoneCPU<Impl>::OzoneXC::profileClear()
851 thread->profile->clear();
854 template <class Impl>
856 OzoneCPU<Impl>::OzoneXC::profileSample()
859 thread->profile->sample(thread->profileNode, thread->profilePC);
863 template <class Impl>
865 OzoneCPU<Impl>::OzoneXC::getThreadNum()
870 // Also somewhat obnoxious. Really only used for the TLB fault.
871 template <class Impl>
873 OzoneCPU<Impl>::OzoneXC::getInst()
878 template <class Impl>
880 OzoneCPU<Impl>::OzoneXC::copyArchRegs(ExecContext *xc)
882 thread->PC = xc->readPC();
883 thread->nextPC = xc->readNextPC();
885 cpu->frontEnd->setPC(thread->PC);
886 cpu->frontEnd->setNextPC(thread->nextPC);
888 for (int i = 0; i < TheISA::TotalNumRegs; ++i) {
889 if (i < TheISA::FP_Base_DepTag) {
890 thread->renameTable[i]->setIntResult(xc->readIntReg(i));
891 } else if (i < (TheISA::FP_Base_DepTag + TheISA::NumFloatRegs)) {
892 int fp_idx = i - TheISA::FP_Base_DepTag;
893 thread->renameTable[i]->setDoubleResult(
894 xc->readFloatRegDouble(fp_idx));
899 thread->funcExeInst = xc->readFuncExeInst();
902 // Need to copy the XC values into the current rename table,
903 // copy the misc regs.
904 thread->regs.miscRegs.copyMiscRegs(xc);
907 template <class Impl>
909 OzoneCPU<Impl>::OzoneXC::clearArchRegs()
911 panic("Unimplemented!");
914 template <class Impl>
916 OzoneCPU<Impl>::OzoneXC::readIntReg(int reg_idx)
918 return thread->renameTable[reg_idx]->readIntResult();
921 template <class Impl>
923 OzoneCPU<Impl>::OzoneXC::readFloatRegSingle(int reg_idx)
925 int idx = reg_idx + TheISA::FP_Base_DepTag;
926 return thread->renameTable[idx]->readFloatResult();
929 template <class Impl>
931 OzoneCPU<Impl>::OzoneXC::readFloatRegDouble(int reg_idx)
933 int idx = reg_idx + TheISA::FP_Base_DepTag;
934 return thread->renameTable[idx]->readDoubleResult();
937 template <class Impl>
939 OzoneCPU<Impl>::OzoneXC::readFloatRegInt(int reg_idx)
941 int idx = reg_idx + TheISA::FP_Base_DepTag;
942 return thread->renameTable[idx]->readIntResult();
945 template <class Impl>
947 OzoneCPU<Impl>::OzoneXC::setIntReg(int reg_idx, uint64_t val)
949 thread->renameTable[reg_idx]->setIntResult(val);
951 if (!thread->inSyscall) {
956 template <class Impl>
958 OzoneCPU<Impl>::OzoneXC::setFloatRegSingle(int reg_idx, float val)
960 panic("Unimplemented!");
963 template <class Impl>
965 OzoneCPU<Impl>::OzoneXC::setFloatRegDouble(int reg_idx, double val)
967 int idx = reg_idx + TheISA::FP_Base_DepTag;
969 thread->renameTable[idx]->setDoubleResult(val);
971 if (!thread->inSyscall) {
976 template <class Impl>
978 OzoneCPU<Impl>::OzoneXC::setFloatRegInt(int reg_idx, uint64_t val)
980 panic("Unimplemented!");
983 template <class Impl>
985 OzoneCPU<Impl>::OzoneXC::setPC(Addr val)
988 cpu->frontEnd->setPC(val);
990 if (!thread->inSyscall) {
995 template <class Impl>
997 OzoneCPU<Impl>::OzoneXC::setNextPC(Addr val)
999 thread->nextPC = val;
1000 cpu->frontEnd->setNextPC(val);
1002 if (!thread->inSyscall) {
1003 cpu->squashFromXC();
1007 template <class Impl>
1009 OzoneCPU<Impl>::OzoneXC::readMiscReg(int misc_reg)
1011 return thread->regs.miscRegs.readReg(misc_reg);
1014 template <class Impl>
1016 OzoneCPU<Impl>::OzoneXC::readMiscRegWithEffect(int misc_reg, Fault &fault)
1018 return thread->regs.miscRegs.readRegWithEffect(misc_reg,
1022 template <class Impl>
1024 OzoneCPU<Impl>::OzoneXC::setMiscReg(int misc_reg, const MiscReg &val)
1026 // Needs to setup a squash event unless we're in syscall mode
1027 Fault ret_fault = thread->regs.miscRegs.setReg(misc_reg, val);
1029 if (!thread->inSyscall) {
1030 cpu->squashFromXC();
1036 template <class Impl>
1038 OzoneCPU<Impl>::OzoneXC::setMiscRegWithEffect(int misc_reg, const MiscReg &val)
1040 // Needs to setup a squash event unless we're in syscall mode
1041 Fault ret_fault = thread->regs.miscRegs.setRegWithEffect(misc_reg, val,
1044 if (!thread->inSyscall) {
1045 cpu->squashFromXC();