diff options
Diffstat (limited to 'src/arch')
76 files changed, 2578 insertions, 2011 deletions
diff --git a/src/arch/alpha/arguments.cc b/src/arch/alpha/arguments.cc index f19ed7ff7..9f9002003 100644 --- a/src/arch/alpha/arguments.cc +++ b/src/arch/alpha/arguments.cc @@ -30,7 +30,7 @@ #include "arch/alpha/arguments.hh" #include "arch/alpha/vtophys.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "mem/vport.hh" using namespace AlphaISA; @@ -56,14 +56,14 @@ AlphaArguments::getArg(bool fp) { if (number < 6) { if (fp) - return xc->readFloatRegBits(16 + number); + return tc->readFloatRegBits(16 + number); else - return xc->readIntReg(16 + number); + return tc->readIntReg(16 + number); } else { - Addr sp = xc->readIntReg(30); - VirtualPort *vp = xc->getVirtPort(xc); + Addr sp = tc->readIntReg(30); + VirtualPort *vp = tc->getVirtPort(tc); uint64_t arg = vp->read<uint64_t>(sp + (number-6) * sizeof(uint64_t)); - xc->delVirtPort(vp); + tc->delVirtPort(vp); return arg; } } diff --git a/src/arch/alpha/arguments.hh b/src/arch/alpha/arguments.hh index 11a67f3d4..d977d48d6 100644 --- a/src/arch/alpha/arguments.hh +++ b/src/arch/alpha/arguments.hh @@ -37,14 +37,14 @@ #include "base/refcnt.hh" #include "sim/host.hh" -class ExecContext; +class ThreadContext; namespace AlphaISA { class AlphaArguments { protected: - ExecContext *xc; + ThreadContext *tc; int number; uint64_t getArg(bool fp = false); @@ -65,17 +65,17 @@ class AlphaArguments RefCountingPtr<Data> data; public: - AlphaArguments(ExecContext *ctx, int n = 0) - : xc(ctx), number(n), data(NULL) + AlphaArguments(ThreadContext *ctx, int n = 0) + : tc(ctx), number(n), data(NULL) { assert(number >= 0); data = new Data;} AlphaArguments(const AlphaArguments &args) - : xc(args.xc), number(args.number), data(args.data) {} + : tc(args.tc), number(args.number), data(args.data) {} ~AlphaArguments() {} - ExecContext *getExecContext() const { return xc; } + ThreadContext *getThreadContext() const { return tc; } const AlphaArguments &operator=(const AlphaArguments &args) { - xc = args.xc; + tc = args.tc; number = args.number; data = args.data; return *this; @@ -120,7 +120,7 @@ class AlphaArguments } AlphaArguments operator[](int index) { - return AlphaArguments(xc, index); + return AlphaArguments(tc, index); } template <class T> @@ -133,13 +133,13 @@ class AlphaArguments template <class T> operator T *() { T *buf = (T *)data->alloc(sizeof(T)); - CopyData(xc, buf, getArg(), sizeof(T)); + CopyData(tc, buf, getArg(), sizeof(T)); return buf; } operator char *() { char *buf = data->alloc(2048); - CopyStringOut(xc, buf, getArg(), 2048); + CopyStringOut(tc, buf, getArg(), 2048); return buf; } }; diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 4d0482019..dddefeb28 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -37,8 +37,8 @@ #include "base/stats/events.hh" #include "config/full_system.hh" #include "cpu/base.hh" -#include "cpu/cpu_exec_context.hh" -#include "cpu/exec_context.hh" +#include "cpu/simple_thread.hh" +#include "cpu/thread_context.hh" #include "kern/kernel_stats.hh" #include "sim/debug.hh" #include "sim/sim_events.hh" @@ -52,15 +52,15 @@ using namespace EV5; // Machine dependent functions // void -AlphaISA::initCPU(ExecContext *xc, int cpuId) +AlphaISA::initCPU(ThreadContext *tc, int cpuId) { - initIPRs(xc, cpuId); + initIPRs(tc, cpuId); - xc->setIntReg(16, cpuId); - xc->setIntReg(0, cpuId); + tc->setIntReg(16, cpuId); + tc->setIntReg(0, cpuId); - xc->setPC(xc->readMiscReg(IPR_PAL_BASE) + (new ResetFault)->vect()); - xc->setNextPC(xc->readPC() + sizeof(MachInst)); + tc->setPC(tc->readMiscReg(IPR_PAL_BASE) + (new ResetFault)->vect()); + tc->setNextPC(tc->readPC() + sizeof(MachInst)); } //////////////////////////////////////////////////////////////////////// @@ -68,15 +68,15 @@ AlphaISA::initCPU(ExecContext *xc, int cpuId) // // void -AlphaISA::initIPRs(ExecContext *xc, int cpuId) +AlphaISA::initIPRs(ThreadContext *tc, int cpuId) { for (int i = 0; i < NumInternalProcRegs; ++i) { - xc->setMiscReg(i, 0); + tc->setMiscReg(i, 0); } - xc->setMiscReg(IPR_PAL_BASE, PalBase); - xc->setMiscReg(IPR_MCSR, 0x6); - xc->setMiscReg(IPR_PALtemp16, cpuId); + tc->setMiscReg(IPR_PAL_BASE, PalBase); + tc->setMiscReg(IPR_MCSR, 0x6); + tc->setMiscReg(IPR_PALtemp16, cpuId); } @@ -135,12 +135,12 @@ AlphaISA::zeroRegisters(CPU *cpu) // Insure ISA semantics // (no longer very clean due to the change in setIntReg() in the // cpu model. Consider changing later.) - cpu->cpuXC->setIntReg(ZeroReg, 0); - cpu->cpuXC->setFloatReg(ZeroReg, 0.0); + cpu->thread->setIntReg(ZeroReg, 0); + cpu->thread->setFloatReg(ZeroReg, 0.0); } Fault -CPUExecContext::hwrei() +SimpleThread::hwrei() { if (!inPalMode()) return new UnimplementedOpcodeFault; @@ -148,7 +148,8 @@ CPUExecContext::hwrei() setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR)); if (!misspeculating()) { - cpu->kernelStats->hwrei(); + if (kernelStats) + kernelStats->hwrei(); cpu->checkInterrupts = true; } @@ -170,7 +171,7 @@ AlphaISA::MiscRegFile::getDataAsid() } AlphaISA::MiscReg -AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc) +AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc) { uint64_t retval = 0; // return value, default 0 @@ -224,7 +225,7 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc) case AlphaISA::IPR_CC: retval |= ipr[idx] & ULL(0xffffffff00000000); - retval |= xc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff); + retval |= tc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff); break; case AlphaISA::IPR_VA: @@ -241,7 +242,7 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc) case AlphaISA::IPR_DTB_PTE: { - AlphaISA::PTE &pte = xc->getDTBPtr()->index(!xc->misspeculating()); + AlphaISA::PTE &pte = tc->getDTBPtr()->index(!tc->misspeculating()); retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32; retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8; @@ -281,11 +282,11 @@ int break_ipl = -1; #endif Fault -AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) +AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) { uint64_t old; - if (xc->misspeculating()) + if (tc->misspeculating()) return NoFault; switch (idx) { @@ -338,7 +339,8 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) // write entire quad w/ no side-effect old = ipr[idx]; ipr[idx] = val; - xc->getCpuPtr()->kernelStats->context(old, val, xc); + if (tc->getKernelStats()) + tc->getKernelStats()->context(old, val, tc); break; case AlphaISA::IPR_DTB_PTE: @@ -365,14 +367,18 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) // only write least significant five bits - interrupt level ipr[idx] = val & 0x1f; - xc->getCpuPtr()->kernelStats->swpipl(ipr[idx]); + if (tc->getKernelStats()) + tc->getKernelStats()->swpipl(ipr[idx]); break; case AlphaISA::IPR_DTB_CM: - if (val & 0x18) - xc->getCpuPtr()->kernelStats->mode(Kernel::user, xc); - else - xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc); + if (val & 0x18) { + if (tc->getKernelStats()) + tc->getKernelStats()->mode(Kernel::user, tc); + } else { + if (tc->getKernelStats()) + tc->getKernelStats()->mode(Kernel::kernel, tc); + } case AlphaISA::IPR_ICM: // only write two mode bits - processor mode @@ -446,21 +452,21 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) // really a control write ipr[idx] = 0; - xc->getDTBPtr()->flushAll(); + tc->getDTBPtr()->flushAll(); break; case AlphaISA::IPR_DTB_IAP: // really a control write ipr[idx] = 0; - xc->getDTBPtr()->flushProcesses(); + tc->getDTBPtr()->flushProcesses(); break; case AlphaISA::IPR_DTB_IS: // really a control write ipr[idx] = val; - xc->getDTBPtr()->flushAddr(val, + tc->getDTBPtr()->flushAddr(val, DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); break; @@ -484,7 +490,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]); // insert new TAG/PTE value into data TLB - xc->getDTBPtr()->insert(val, pte); + tc->getDTBPtr()->insert(val, pte); } break; @@ -508,7 +514,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]); // insert new TAG/PTE value into data TLB - xc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], pte); + tc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], pte); } break; @@ -516,21 +522,21 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) // really a control write ipr[idx] = 0; - xc->getITBPtr()->flushAll(); + tc->getITBPtr()->flushAll(); break; case AlphaISA::IPR_ITB_IAP: // really a control write ipr[idx] = 0; - xc->getITBPtr()->flushProcesses(); + tc->getITBPtr()->flushProcesses(); break; case AlphaISA::IPR_ITB_IS: // really a control write ipr[idx] = val; - xc->getITBPtr()->flushAddr(val, + tc->getITBPtr()->flushAddr(val, ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); break; @@ -544,7 +550,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) } void -AlphaISA::copyIprs(ExecContext *src, ExecContext *dest) +AlphaISA::copyIprs(ThreadContext *src, ThreadContext *dest) { for (int i = IPR_Base_DepTag; i < NumInternalProcRegs; ++i) { dest->setMiscReg(i, src->readMiscReg(i)); @@ -556,9 +562,10 @@ AlphaISA::copyIprs(ExecContext *src, ExecContext *dest) * If return value is false, actual PAL call will be suppressed. */ bool -CPUExecContext::simPalCheck(int palFunc) +SimpleThread::simPalCheck(int palFunc) { - cpu->kernelStats->callpal(palFunc, proxy); + if (kernelStats) + kernelStats->callpal(palFunc, tc); switch (palFunc) { case PAL::halt: diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index 88084bf86..8493223ff 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -30,7 +30,7 @@ */ #include "arch/alpha/faults.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "cpu/base.hh" #include "base/trace.hh" #if FULL_SYSTEM @@ -110,67 +110,67 @@ FaultStat IntegerOverflowFault::_count; #if FULL_SYSTEM -void AlphaFault::invoke(ExecContext * xc) +void AlphaFault::invoke(ThreadContext * tc) { - FaultBase::invoke(xc); + FaultBase::invoke(tc); countStat()++; // exception restart address - if (setRestartAddress() || !xc->inPalMode()) - xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->readPC()); + if (setRestartAddress() || !tc->inPalMode()) + tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, tc->readPC()); if (skipFaultingInstruction()) { // traps... skip faulting instruction. - xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, - xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); + tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, + tc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); } - xc->setPC(xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect()); - xc->setNextPC(xc->readPC() + sizeof(MachInst)); + tc->setPC(tc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect()); + tc->setNextPC(tc->readPC() + sizeof(MachInst)); } -void ArithmeticFault::invoke(ExecContext * xc) +void ArithmeticFault::invoke(ThreadContext * tc) { - FaultBase::invoke(xc); + FaultBase::invoke(tc); panic("Arithmetic traps are unimplemented!"); } -void DtbFault::invoke(ExecContext * xc) +void DtbFault::invoke(ThreadContext * tc) { // Set fault address and flags. Even though we're modeling an // EV5, we use the EV6 technique of not latching fault registers // on VPTE loads (instead of locking the registers until IPR_VA is // read, like the EV5). The EV6 approach is cleaner and seems to // work with EV5 PAL code, but not the other way around. - if (!xc->misspeculating() + if (!tc->misspeculating() && !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) { // set VA register with faulting address - xc->setMiscReg(AlphaISA::IPR_VA, vaddr); + tc->setMiscReg(AlphaISA::IPR_VA, vaddr); // set MM_STAT register flags - xc->setMiscReg(AlphaISA::IPR_MM_STAT, - (((EV5::Opcode(xc->getInst()) & 0x3f) << 11) - | ((EV5::Ra(xc->getInst()) & 0x1f) << 6) + tc->setMiscReg(AlphaISA::IPR_MM_STAT, + (((EV5::Opcode(tc->getInst()) & 0x3f) << 11) + | ((EV5::Ra(tc->getInst()) & 0x1f) << 6) | (flags & 0x3f))); // set VA_FORM register with faulting formatted address - xc->setMiscReg(AlphaISA::IPR_VA_FORM, - xc->readMiscReg(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3)); + tc->setMiscReg(AlphaISA::IPR_VA_FORM, + tc->readMiscReg(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3)); } - AlphaFault::invoke(xc); + AlphaFault::invoke(tc); } -void ItbFault::invoke(ExecContext * xc) +void ItbFault::invoke(ThreadContext * tc) { - if (!xc->misspeculating()) { - xc->setMiscReg(AlphaISA::IPR_ITB_TAG, pc); - xc->setMiscReg(AlphaISA::IPR_IFAULT_VA_FORM, - xc->readMiscReg(AlphaISA::IPR_IVPTBR) | + if (!tc->misspeculating()) { + tc->setMiscReg(AlphaISA::IPR_ITB_TAG, pc); + tc->setMiscReg(AlphaISA::IPR_IFAULT_VA_FORM, + tc->readMiscReg(AlphaISA::IPR_IVPTBR) | (AlphaISA::VAddr(pc).vpn() << 3)); } - AlphaFault::invoke(xc); + AlphaFault::invoke(tc); } #endif diff --git a/src/arch/alpha/faults.hh b/src/arch/alpha/faults.hh index 0d60367f7..f952cf9d6 100644 --- a/src/arch/alpha/faults.hh +++ b/src/arch/alpha/faults.hh @@ -49,7 +49,7 @@ class AlphaFault : public FaultBase virtual bool setRestartAddress() {return true;} public: #if FULL_SYSTEM - void invoke(ExecContext * xc); + void invoke(ThreadContext * tc); #endif virtual FaultVect vect() = 0; virtual FaultStat & countStat() = 0; @@ -116,7 +116,7 @@ class ArithmeticFault : public AlphaFault FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} #if FULL_SYSTEM - void invoke(ExecContext * xc); + void invoke(ThreadContext * tc); #endif }; @@ -150,7 +150,7 @@ class DtbFault : public AlphaFault FaultVect vect() = 0; FaultStat & countStat() = 0; #if FULL_SYSTEM - void invoke(ExecContext * xc); + void invoke(ThreadContext * tc); #endif }; @@ -251,7 +251,7 @@ class ItbFault : public AlphaFault FaultVect vect() = 0; FaultStat & countStat() = 0; #if FULL_SYSTEM - void invoke(ExecContext * xc); + void invoke(ThreadContext * tc); #endif }; diff --git a/src/arch/alpha/freebsd/system.cc b/src/arch/alpha/freebsd/system.cc index 2781fed3d..91f8b5af1 100644 --- a/src/arch/alpha/freebsd/system.cc +++ b/src/arch/alpha/freebsd/system.cc @@ -38,7 +38,7 @@ #include "arch/alpha/system.hh" #include "arch/alpha/freebsd/system.hh" #include "base/loader/symtab.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "mem/physical.hh" #include "mem/port.hh" #include "arch/isa_traits.hh" @@ -72,13 +72,13 @@ FreebsdAlphaSystem::~FreebsdAlphaSystem() void -FreebsdAlphaSystem::doCalibrateClocks(ExecContext *xc) +FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc) { Addr ppc_vaddr = 0; Addr timer_vaddr = 0; - ppc_vaddr = (Addr)xc->readIntReg(ArgumentReg1); - timer_vaddr = (Addr)xc->readIntReg(ArgumentReg2); + ppc_vaddr = (Addr)tc->readIntReg(ArgumentReg1); + timer_vaddr = (Addr)tc->readIntReg(ArgumentReg2); virtPort.write(ppc_vaddr, (uint32_t)Clock::Frequency); virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY); @@ -86,10 +86,10 @@ FreebsdAlphaSystem::doCalibrateClocks(ExecContext *xc) void -FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ExecContext *xc) +FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ThreadContext *tc) { - SkipFuncEvent::process(xc); - ((FreebsdAlphaSystem *)xc->getSystemPtr())->doCalibrateClocks(xc); + SkipFuncEvent::process(tc); + ((FreebsdAlphaSystem *)tc->getSystemPtr())->doCalibrateClocks(tc); } diff --git a/src/arch/alpha/freebsd/system.hh b/src/arch/alpha/freebsd/system.hh index 46a5e665c..e0d874e8f 100644 --- a/src/arch/alpha/freebsd/system.hh +++ b/src/arch/alpha/freebsd/system.hh @@ -42,7 +42,7 @@ class FreebsdAlphaSystem : public AlphaSystem SkipCalibrateClocksEvent(PCEventQueue *q, const std::string &desc, Addr addr) : SkipFuncEvent(q, desc, addr) {} - virtual void process(ExecContext *xc); + virtual void process(ThreadContext *tc); }; SkipFuncEvent *skipDelayEvent; @@ -51,7 +51,7 @@ class FreebsdAlphaSystem : public AlphaSystem public: FreebsdAlphaSystem(Params *p); ~FreebsdAlphaSystem(); - void doCalibrateClocks(ExecContext *xc); + void doCalibrateClocks(ThreadContext *tc); }; diff --git a/src/arch/alpha/isa/branch.isa b/src/arch/alpha/isa/branch.isa index aa7abf289..7438e7e18 100644 --- a/src/arch/alpha/isa/branch.isa +++ b/src/arch/alpha/isa/branch.isa @@ -106,7 +106,7 @@ output header {{ { } - Addr branchTarget(ExecContext *xc) const; + Addr branchTarget(ThreadContext *tc) const; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; @@ -121,10 +121,10 @@ output decoder {{ } Addr - Jump::branchTarget(ExecContext *xc) const + Jump::branchTarget(ThreadContext *tc) const { - Addr NPC = xc->readPC() + 4; - uint64_t Rb = xc->readIntReg(_srcRegIdx[0]); + Addr NPC = tc->readPC() + 4; + uint64_t Rb = tc->readIntReg(_srcRegIdx[0]); return (Rb & ~3) | (NPC & 1); } diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 17132bbc2..fbdb119b6 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -80,7 +80,7 @@ decode OPCODE default Unknown::unknown() { uint64_t tmp = write_result; // see stq_c Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; - }}, mem_flags = LOCKED); + }}, mem_flags = LOCKED, inst_flags = IsStoreConditional); 0x2f: stq_c({{ Mem.uq = Ra; }}, {{ uint64_t tmp = write_result; @@ -92,7 +92,7 @@ decode OPCODE default Unknown::unknown() { // mailbox access, and we don't update the // result register at all. Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; - }}, mem_flags = LOCKED); + }}, mem_flags = LOCKED, inst_flags = IsStoreConditional); } format IntegerOperate { @@ -598,8 +598,8 @@ decode OPCODE default Unknown::unknown() { 0x02e: fcmovle({{ Fc = (Fa <= 0) ? Fb : Fc; }}); 0x02f: fcmovgt({{ Fc = (Fa > 0) ? Fb : Fc; }}); - 0x024: mt_fpcr({{ FPCR = Fa.uq; }}); - 0x025: mf_fpcr({{ Fa.uq = FPCR; }}); + 0x024: mt_fpcr({{ FPCR = Fa.uq; }}, IsIprAccess); + 0x025: mf_fpcr({{ Fa.uq = FPCR; }}, IsIprAccess); } } @@ -630,7 +630,7 @@ decode OPCODE default Unknown::unknown() { #else Ra = curTick; #endif - }}); + }}, IsUnverifiable); // All of the barrier instructions below do nothing in // their execute() methods (hence the empty code blocks). @@ -648,8 +648,8 @@ decode OPCODE default Unknown::unknown() { // a barrier on integer and FP traps. "EXCB is thus a // superset of TRAPB." (Alpha ARM, Sec 4.11.4) We treat // them the same though. - 0x0000: trapb({{ }}, IsSerializing, No_OpClass); - 0x0400: excb({{ }}, IsSerializing, No_OpClass); + 0x0000: trapb({{ }}, IsSerializing, IsSerializeBefore, No_OpClass); + 0x0400: excb({{ }}, IsSerializing, IsSerializeBefore, No_OpClass); 0x4000: mb({{ }}, IsMemBarrier, MemReadOp); 0x4400: wmb({{ }}, IsWriteBarrier, MemWriteOp); } @@ -703,9 +703,9 @@ decode OPCODE default Unknown::unknown() { xc->syscall(R0); }}, IsNonSpeculative); // Read uniq reg into ABI return value register (r0) - 0x9e: rduniq({{ R0 = Runiq; }}); + 0x9e: rduniq({{ R0 = Runiq; }}, IsIprAccess); // Write uniq reg with value from ABI arg register (r16) - 0x9f: wruniq({{ Runiq = R16; }}); + 0x9f: wruniq({{ Runiq = R16; }}, IsIprAccess); } } #endif @@ -742,7 +742,7 @@ decode OPCODE default Unknown::unknown() { format HwMoveIPR { 1: hw_mfpr({{ Ra = xc->readMiscRegWithEffect(ipr_index, fault); - }}); + }}, IsIprAccess); } } @@ -752,69 +752,69 @@ decode OPCODE default Unknown::unknown() { 1: hw_mtpr({{ xc->setMiscRegWithEffect(ipr_index, Ra); if (traceData) { traceData->setData(Ra); } - }}); + }}, IsIprAccess); } } format BasicOperate { 0x1e: decode PALMODE { 0: OpcdecFault::hw_rei(); - 1:hw_rei({{ xc->hwrei(); }}, IsSerializing); + 1:hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore); } // M5 special opcodes use the reserved 0x01 opcode space 0x01: decode M5FUNC { 0x00: arm({{ - AlphaPseudo::arm(xc->xcBase()); + AlphaPseudo::arm(xc->tcBase()); }}, IsNonSpeculative); 0x01: quiesce({{ - AlphaPseudo::quiesce(xc->xcBase()); - }}, IsNonSpeculative); + AlphaPseudo::quiesce(xc->tcBase()); + }}, IsNonSpeculative, IsQuiesce); 0x02: quiesceNs({{ - AlphaPseudo::quiesceNs(xc->xcBase(), R16); - }}, IsNonSpeculative); + AlphaPseudo::quiesceNs(xc->tcBase(), R16); + }}, IsNonSpeculative, IsQuiesce); 0x03: quiesceCycles({{ - AlphaPseudo::quiesceCycles(xc->xcBase(), R16); - }}, IsNonSpeculative); + AlphaPseudo::quiesceCycles(xc->tcBase(), R16); + }}, IsNonSpeculative, IsQuiesce); 0x04: quiesceTime({{ - R0 = AlphaPseudo::quiesceTime(xc->xcBase()); + R0 = AlphaPseudo::quiesceTime(xc->tcBase()); }}, IsNonSpeculative); 0x10: ivlb({{ - AlphaPseudo::ivlb(xc->xcBase()); + AlphaPseudo::ivlb(xc->tcBase()); }}, No_OpClass, IsNonSpeculative); 0x11: ivle({{ - AlphaPseudo::ivle(xc->xcBase()); + AlphaPseudo::ivle(xc->tcBase()); }}, No_OpClass, IsNonSpeculative); 0x20: m5exit_old({{ - AlphaPseudo::m5exit_old(xc->xcBase()); + AlphaPseudo::m5exit_old(xc->tcBase()); }}, No_OpClass, IsNonSpeculative); 0x21: m5exit({{ - AlphaPseudo::m5exit(xc->xcBase(), R16); + AlphaPseudo::m5exit(xc->tcBase(), R16); }}, No_OpClass, IsNonSpeculative); - 0x30: initparam({{ Ra = xc->xcBase()->getCpuPtr()->system->init_param; }}); + 0x30: initparam({{ Ra = xc->tcBase()->getCpuPtr()->system->init_param; }}); 0x40: resetstats({{ - AlphaPseudo::resetstats(xc->xcBase(), R16, R17); + AlphaPseudo::resetstats(xc->tcBase(), R16, R17); }}, IsNonSpeculative); 0x41: dumpstats({{ - AlphaPseudo::dumpstats(xc->xcBase(), R16, R17); + AlphaPseudo::dumpstats(xc->tcBase(), R16, R17); }}, IsNonSpeculative); 0x42: dumpresetstats({{ - AlphaPseudo::dumpresetstats(xc->xcBase(), R16, R17); + AlphaPseudo::dumpresetstats(xc->tcBase(), R16, R17); }}, IsNonSpeculative); 0x43: m5checkpoint({{ - AlphaPseudo::m5checkpoint(xc->xcBase(), R16, R17); + AlphaPseudo::m5checkpoint(xc->tcBase(), R16, R17); }}, IsNonSpeculative); 0x50: m5readfile({{ - R0 = AlphaPseudo::readfile(xc->xcBase(), R16, R17, R18); + R0 = AlphaPseudo::readfile(xc->tcBase(), R16, R17, R18); }}, IsNonSpeculative); 0x51: m5break({{ - AlphaPseudo::debugbreak(xc->xcBase()); + AlphaPseudo::debugbreak(xc->tcBase()); }}, IsNonSpeculative); 0x52: m5switchcpu({{ - AlphaPseudo::switchcpu(xc->xcBase()); + AlphaPseudo::switchcpu(xc->tcBase()); }}, IsNonSpeculative); 0x53: m5addsymbol({{ - AlphaPseudo::addsymbol(xc->xcBase(), R16, R17); + AlphaPseudo::addsymbol(xc->tcBase(), R16, R17); }}, IsNonSpeculative); 0x54: m5panic({{ panic("M5 panic instruction called at pc=%#x.", xc->readPC()); diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index 91ece0935..1270bf8d8 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -56,7 +56,7 @@ output decoder {{ #include "base/fenv.hh" #include "base/loader/symtab.hh" #include "config/ss_compatible_fp.hh" -#include "cpu/exec_context.hh" // for Jump::branchTarget() +#include "cpu/thread_context.hh" // for Jump::branchTarget() #include <math.h> diff --git a/src/arch/alpha/isa/pal.isa b/src/arch/alpha/isa/pal.isa index 7c426a94e..f4c10da1d 100644 --- a/src/arch/alpha/isa/pal.isa +++ b/src/arch/alpha/isa/pal.isa @@ -266,9 +266,11 @@ output decoder {{ } }}; -def format HwMoveIPR(code) {{ +def format HwMoveIPR(code, *flags) {{ + all_flags = ['IprAccessOp'] + all_flags += flags iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code), - ['IprAccessOp']) + all_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index abd17c224..997c78ac9 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -34,7 +34,7 @@ #include "arch/alpha/isa_traits.hh" #include "base/trace.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "kern/linux/linux.hh" #include "sim/process.hh" @@ -48,9 +48,9 @@ using namespace AlphaISA; /// Target uname() handler. static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) + ThreadContext *tc) { - TypedBufferArg<Linux::utsname> name(xc->getSyscallArg(0)); + TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -58,7 +58,7 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process, strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); strcpy(name->machine, "alpha"); - name.copyOut(xc->getMemPort()); + name.copyOut(tc->getMemPort()); return 0; } @@ -67,18 +67,18 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process, /// different in practice from those used by Tru64 processes. static SyscallReturn osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) + ThreadContext *tc) { - unsigned op = xc->getSyscallArg(0); - // unsigned nbytes = xc->getSyscallArg(2); + unsigned op = tc->getSyscallArg(0); + // unsigned nbytes = tc->getSyscallArg(2); switch (op) { case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1)); + TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1)); // I don't think this exactly matches the HW FPCR *fpcr = 0; - fpcr.copyOut(xc->getMemPort()); + fpcr.copyOut(tc->getMemPort()); return 0; } @@ -94,17 +94,17 @@ osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, /// Target osf_setsysinfo() handler. static SyscallReturn osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) + ThreadContext *tc) { - unsigned op = xc->getSyscallArg(0); - // unsigned nbytes = xc->getSyscallArg(2); + unsigned op = tc->getSyscallArg(0); + // unsigned nbytes = tc->getSyscallArg(2); switch (op) { case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1)); + TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1)); // I don't think this exactly matches the HW FPCR - fpcr.copyIn(xc->getMemPort()); + fpcr.copyIn(tc->getMemPort()); DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr)); return 0; diff --git a/src/arch/alpha/linux/system.cc b/src/arch/alpha/linux/system.cc index f267e9d42..3e061bba8 100644 --- a/src/arch/alpha/linux/system.cc +++ b/src/arch/alpha/linux/system.cc @@ -46,7 +46,7 @@ #include "arch/alpha/linux/threadinfo.hh" #include "arch/alpha/system.hh" #include "base/loader/symtab.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "cpu/base.hh" #include "dev/platform.hh" #include "kern/linux/printk.hh" @@ -175,30 +175,33 @@ LinuxAlphaSystem::~LinuxAlphaSystem() void -LinuxAlphaSystem::setDelayLoop(ExecContext *xc) +LinuxAlphaSystem::setDelayLoop(ThreadContext *tc) { Addr addr = 0; if (kernelSymtab->findAddress("loops_per_jiffy", addr)) { - Tick cpuFreq = xc->getCpuPtr()->frequency(); + Tick cpuFreq = tc->getCpuPtr()->frequency(); Tick intrFreq = platform->intrFrequency(); - xc->getVirtPort(xc)->write(addr, - (uint32_t)((cpuFreq / intrFreq) * 0.9988)); + VirtualPort *vp; + + vp = tc->getVirtPort(); + vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988)); + tc->delVirtPort(vp); } } void -LinuxAlphaSystem::SkipDelayLoopEvent::process(ExecContext *xc) +LinuxAlphaSystem::SkipDelayLoopEvent::process(ThreadContext *tc) { - SkipFuncEvent::process(xc); + SkipFuncEvent::process(tc); // calculate and set loops_per_jiffy - ((LinuxAlphaSystem *)xc->getSystemPtr())->setDelayLoop(xc); + ((LinuxAlphaSystem *)tc->getSystemPtr())->setDelayLoop(tc); } void -LinuxAlphaSystem::PrintThreadInfo::process(ExecContext *xc) +LinuxAlphaSystem::PrintThreadInfo::process(ThreadContext *tc) { - Linux::ThreadInfo ti(xc); + Linux::ThreadInfo ti(tc); DPRINTF(Thread, "Currently Executing Thread %s, pid %d, started at: %d\n", ti.curTaskName(), ti.curTaskPID(), ti.curTaskStart()); diff --git a/src/arch/alpha/linux/system.hh b/src/arch/alpha/linux/system.hh index 46bf6ea91..c03586ac5 100644 --- a/src/arch/alpha/linux/system.hh +++ b/src/arch/alpha/linux/system.hh @@ -33,7 +33,7 @@ #ifndef __ARCH_ALPHA_LINUX_SYSTEM_HH__ #define __ARCH_ALPHA_LINUX_SYSTEM_HH__ -class ExecContext; +class ThreadContext; class BreakPCEvent; class IdleStartEvent; @@ -57,7 +57,7 @@ class LinuxAlphaSystem : public AlphaSystem public: SkipDelayLoopEvent(PCEventQueue *q, const std::string &desc, Addr addr) : SkipFuncEvent(q, desc, addr) {} - virtual void process(ExecContext *xc); + virtual void process(ThreadContext *tc); }; class PrintThreadInfo : public PCEvent @@ -65,7 +65,7 @@ class LinuxAlphaSystem : public AlphaSystem public: PrintThreadInfo(PCEventQueue *q, const std::string &desc, Addr addr) : PCEvent(q, desc, addr) {} - virtual void process(ExecContext *xc); + virtual void process(ThreadContext *tc); }; @@ -143,7 +143,7 @@ class LinuxAlphaSystem : public AlphaSystem LinuxAlphaSystem(Params *p); ~LinuxAlphaSystem(); - void setDelayLoop(ExecContext *xc); + void setDelayLoop(ThreadContext *tc); }; #endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__ diff --git a/src/arch/alpha/linux/threadinfo.hh b/src/arch/alpha/linux/threadinfo.hh index 74444f427..caeb69f15 100644 --- a/src/arch/alpha/linux/threadinfo.hh +++ b/src/arch/alpha/linux/threadinfo.hh @@ -33,7 +33,7 @@ #define __ARCH_ALPHA_LINUX_LINUX_TREADNIFO_HH__ #include "arch/alpha/linux/thread_info.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "kern/linux/sched.hh" #include "sim/vptr.hh" @@ -42,10 +42,10 @@ namespace Linux { class ThreadInfo { private: - ExecContext *xc; + ThreadContext *tc; public: - ThreadInfo(ExecContext *exec) : xc(exec) {} + ThreadInfo(ThreadContext *_tc) : tc(_tc) {} ~ThreadInfo() {} inline VPtr<thread_info> @@ -57,15 +57,15 @@ class ThreadInfo * thread_info struct. So we can get the address by masking off * the lower 14 bits. */ - current = xc->readIntReg(TheISA::StackPointerReg) & ~0x3fff; - return VPtr<thread_info>(xc, current); + current = tc->readIntReg(TheISA::StackPointerReg) & ~0x3fff; + return VPtr<thread_info>(tc, current); } inline VPtr<task_struct> curTaskInfo() { Addr task = curThreadInfo()->task; - return VPtr<task_struct>(xc, task); + return VPtr<task_struct>(tc, task); } std::string diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index 490e04972..4c0c68761 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -35,7 +35,7 @@ #include "arch/alpha/tru64/process.hh" #include "base/loader/object_file.hh" #include "base/misc.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "sim/builder.hh" #include "sim/system.hh" @@ -107,7 +107,7 @@ AlphaLiveProcess::startup() { argsInit(MachineBytes, VMPageSize); - execContexts[0]->setIntReg(GlobalPointerReg, objFile->globalPointer()); + threadContexts[0]->setIntReg(GlobalPointerReg, objFile->globalPointer()); } diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index 2652144b6..1025412cd 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -36,7 +36,7 @@ #include "sim/faults.hh" class Checkpoint; -class ExecContext; +class ThreadContext; namespace AlphaISA { @@ -62,6 +62,8 @@ namespace AlphaISA void unserialize(Checkpoint *cp, const std::string §ion); + void clear() + { bzero(regs, sizeof(regs)); } }; class FloatRegFile @@ -77,6 +79,8 @@ namespace AlphaISA void unserialize(Checkpoint *cp, const std::string §ion); + void clear() + { bzero(d, sizeof(d)); } }; class MiscRegFile { @@ -90,7 +94,7 @@ namespace AlphaISA MiscReg readReg(int misc_reg); MiscReg readRegWithEffect(int misc_reg, Fault &fault, - ExecContext *xc); + ThreadContext *tc); //These functions should be removed once the simplescalar cpu model //has been replaced. @@ -100,8 +104,14 @@ namespace AlphaISA Fault setReg(int misc_reg, const MiscReg &val); Fault setRegWithEffect(int misc_reg, const MiscReg &val, - ExecContext *xc); + ThreadContext *tc); + void clear() + { + fpcr = uniq = 0; + lock_flag = 0; + lock_addr = 0; + } #if FULL_SYSTEM protected: typedef uint64_t InternalProcReg; @@ -109,9 +119,9 @@ namespace AlphaISA InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs private: - InternalProcReg readIpr(int idx, Fault &fault, ExecContext *xc); + InternalProcReg readIpr(int idx, Fault &fault, ThreadContext *tc); - Fault setIpr(int idx, InternalProcReg val, ExecContext *xc); + Fault setIpr(int idx, InternalProcReg val, ThreadContext *tc); #endif friend class RegFile; }; @@ -171,9 +181,9 @@ namespace AlphaISA void clear() { - bzero(&intRegFile, sizeof(intRegFile)); - bzero(&floatRegFile, sizeof(floatRegFile)); - bzero(&miscRegFile, sizeof(miscRegFile)); + intRegFile.clear(); + floatRegFile.clear(); + miscRegFile.clear(); } MiscReg readMiscReg(int miscReg) @@ -182,10 +192,10 @@ namespace AlphaISA } MiscReg readMiscRegWithEffect(int miscReg, - Fault &fault, ExecContext *xc) + Fault &fault, ThreadContext *tc) { fault = NoFault; - return miscRegFile.readRegWithEffect(miscReg, fault, xc); + return miscRegFile.readRegWithEffect(miscReg, fault, tc); } Fault setMiscReg(int miscReg, const MiscReg &val) @@ -194,9 +204,9 @@ namespace AlphaISA } Fault setMiscRegWithEffect(int miscReg, const MiscReg &val, - ExecContext * xc) + ThreadContext * tc) { - return miscRegFile.setRegWithEffect(miscReg, val, xc); + return miscRegFile.setRegWithEffect(miscReg, val, tc); } FloatReg readFloatReg(int floatReg) @@ -268,12 +278,12 @@ namespace AlphaISA } }; - void copyRegs(ExecContext *src, ExecContext *dest); + void copyRegs(ThreadContext *src, ThreadContext *dest); - void copyMiscRegs(ExecContext *src, ExecContext *dest); + void copyMiscRegs(ThreadContext *src, ThreadContext *dest); #if FULL_SYSTEM - void copyIprs(ExecContext *src, ExecContext *dest); + void copyIprs(ThreadContext *src, ThreadContext *dest); #endif } // namespace AlphaISA diff --git a/src/arch/alpha/stacktrace.cc b/src/arch/alpha/stacktrace.cc index 792b63e2f..d70a4d6dd 100644 --- a/src/arch/alpha/stacktrace.cc +++ b/src/arch/alpha/stacktrace.cc @@ -36,36 +36,42 @@ #include "base/bitfield.hh" #include "base/trace.hh" #include "cpu/base.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "sim/system.hh" using namespace std; using namespace AlphaISA; -ProcessInfo::ProcessInfo(ExecContext *_xc) - : xc(_xc) +ProcessInfo::ProcessInfo(ThreadContext *_tc) + : tc(_tc) { Addr addr = 0; - if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) + VirtualPort *vp; + + vp = tc->getVirtPort(); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) panic("thread info not compiled into kernel\n"); - thread_info_size = gtoh(xc->getVirtPort()->read<int32_t>(addr)); + thread_info_size = vp->readGtoH<int32_t>(addr); - if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) panic("thread info not compiled into kernel\n"); - task_struct_size = gtoh(xc->getVirtPort()->read<int32_t>(addr)); + task_struct_size = vp->readGtoH<int32_t>(addr); - if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) + if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) panic("thread info not compiled into kernel\n"); - task_off = gtoh(xc->getVirtPort()->read<int32_t>(addr)); + task_off = vp->readGtoH<int32_t>(addr); - if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) panic("thread info not compiled into kernel\n"); - pid_off = gtoh(xc->getVirtPort()->read<int32_t>(addr)); + pid_off = vp->readGtoH<int32_t>(addr); - if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) panic("thread info not compiled into kernel\n"); - name_off = gtoh(xc->getVirtPort()->read<int32_t>(addr)); + name_off = vp->readGtoH<int32_t>(addr); + + tc->delVirtPort(vp); } Addr @@ -75,7 +81,15 @@ ProcessInfo::task(Addr ksp) const if (base == ULL(0xfffffc0000000000)) return 0; - return gtoh(xc->getVirtPort()->read<Addr>(base + task_off)); + Addr tsk; + + VirtualPort *vp; + + vp = tc->getVirtPort(); + tsk = vp->readGtoH<Addr>(base + task_off); + tc->delVirtPort(vp); + + return tsk; } int @@ -85,7 +99,15 @@ ProcessInfo::pid(Addr ksp) const if (!task) return -1; - return gtoh(xc->getVirtPort()->read<uint16_t>(task + pid_off)); + uint16_t pd; + + VirtualPort *vp; + + vp = tc->getVirtPort(); + pd = vp->readGtoH<uint16_t>(task + pid_off); + tc->delVirtPort(vp); + + return pd; } string @@ -96,7 +118,7 @@ ProcessInfo::name(Addr ksp) const return "console"; char comm[256]; - CopyStringOut(xc, comm, task + name_off, sizeof(comm)); + CopyStringOut(tc, comm, task + name_off, sizeof(comm)); if (!comm[0]) return "startup"; @@ -104,14 +126,14 @@ ProcessInfo::name(Addr ksp) const } StackTrace::StackTrace() - : xc(0), stack(64) + : tc(0), stack(64) { } -StackTrace::StackTrace(ExecContext *_xc, StaticInstPtr inst) - : xc(0), stack(64) +StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) + : tc(0), stack(64) { - trace(_xc, inst); + trace(_tc, inst); } StackTrace::~StackTrace() @@ -119,15 +141,15 @@ StackTrace::~StackTrace() } void -StackTrace::trace(ExecContext *_xc, bool is_call) +StackTrace::trace(ThreadContext *_tc, bool is_call) { - xc = _xc; + tc = _tc; - bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; + bool usermode = (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; - Addr pc = xc->readNextPC(); - bool kernel = xc->getSystemPtr()->kernelStart <= pc && - pc <= xc->getSystemPtr()->kernelEnd; + Addr pc = tc->readNextPC(); + bool kernel = tc->getSystemPtr()->kernelStart <= pc && + pc <= tc->getSystemPtr()->kernelEnd; if (usermode) { stack.push_back(user); @@ -139,8 +161,8 @@ StackTrace::trace(ExecContext *_xc, bool is_call) return; } - SymbolTable *symtab = xc->getSystemPtr()->kernelSymtab; - Addr ksp = xc->readIntReg(TheISA::StackPointerReg); + SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; + Addr ksp = tc->readIntReg(TheISA::StackPointerReg); Addr bottom = ksp & ~0x3fff; Addr addr; @@ -149,7 +171,7 @@ StackTrace::trace(ExecContext *_xc, bool is_call) panic("could not find address %#x", pc); stack.push_back(addr); - pc = xc->readPC(); + pc = tc->readPC(); } Addr ra; @@ -181,8 +203,8 @@ StackTrace::trace(ExecContext *_xc, bool is_call) return; } - bool kernel = xc->getSystemPtr()->kernelStart <= pc && - pc <= xc->getSystemPtr()->kernelEnd; + bool kernel = tc->getSystemPtr()->kernelStart <= pc && + pc <= tc->getSystemPtr()->kernelEnd; if (!kernel) return; @@ -196,22 +218,22 @@ StackTrace::trace(ExecContext *_xc, bool is_call) bool StackTrace::isEntry(Addr addr) { - if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp12)) + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp12)) return true; - if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp7)) + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp7)) return true; - if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp11)) + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp11)) return true; - if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp21)) + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp21)) return true; - if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp9)) + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp9)) return true; - if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp2)) + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp2)) return true; return false; @@ -296,7 +318,7 @@ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { MachInst inst; - CopyOut(xc, (uint8_t *)&inst, pc, sizeof(MachInst)); + CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst)); int reg, disp; if (decodeStack(inst, disp)) { @@ -307,7 +329,7 @@ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, size += disp; } else if (decodeSave(inst, reg, disp)) { if (!ra && reg == ReturnAddressReg) { - CopyOut(xc, (uint8_t *)&ra, sp + disp, sizeof(Addr)); + CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr)); if (!ra) { // panic("no return address value pc=%#x\n", pc); return false; @@ -323,8 +345,8 @@ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, void StackTrace::dump() { - StringWrap name(xc->getCpuPtr()->name()); - SymbolTable *symtab = xc->getSystemPtr()->kernelSymtab; + StringWrap name(tc->getCpuPtr()->name()); + SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; DPRINTFN("------ Stack ------\n"); diff --git a/src/arch/alpha/stacktrace.hh b/src/arch/alpha/stacktrace.hh index dd86a1553..d12aee211 100644 --- a/src/arch/alpha/stacktrace.hh +++ b/src/arch/alpha/stacktrace.hh @@ -34,13 +34,13 @@ #include "base/trace.hh" #include "cpu/static_inst.hh" -class ExecContext; +class ThreadContext; class StackTrace; class ProcessInfo { private: - ExecContext *xc; + ThreadContext *tc; int thread_info_size; int task_struct_size; @@ -49,7 +49,7 @@ class ProcessInfo int name_off; public: - ProcessInfo(ExecContext *_xc); + ProcessInfo(ThreadContext *_tc); Addr task(Addr ksp) const; int pid(Addr ksp) const; @@ -61,7 +61,7 @@ class StackTrace protected: typedef TheISA::MachInst MachInst; private: - ExecContext *xc; + ThreadContext *tc; std::vector<Addr> stack; private: @@ -70,21 +70,21 @@ class StackTrace bool decodeSave(MachInst inst, int ®, int &disp); bool decodeStack(MachInst inst, int &disp); - void trace(ExecContext *xc, bool is_call); + void trace(ThreadContext *tc, bool is_call); public: StackTrace(); - StackTrace(ExecContext *xc, StaticInstPtr inst); + StackTrace(ThreadContext *tc, StaticInstPtr inst); ~StackTrace(); void clear() { - xc = 0; + tc = 0; stack.clear(); } - bool valid() const { return xc != NULL; } - bool trace(ExecContext *xc, StaticInstPtr inst); + bool valid() const { return tc != NULL; } + bool trace(ThreadContext *tc, StaticInstPtr inst); public: const std::vector<Addr> &getstack() const { return stack; } @@ -106,7 +106,7 @@ class StackTrace }; inline bool -StackTrace::trace(ExecContext *xc, StaticInstPtr inst) +StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) { if (!inst->isCall() && !inst->isReturn()) return false; @@ -114,7 +114,7 @@ StackTrace::trace(ExecContext *xc, StaticInstPtr inst) if (valid()) clear(); - trace(xc, !inst->isReturn()); + trace(tc, !inst->isReturn()); return true; } diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index 0bcca1887..c6684274b 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -38,7 +38,7 @@ #include "base/str.hh" #include "base/trace.hh" #include "config/alpha_tlaser.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "sim/builder.hh" using namespace std; @@ -286,7 +286,7 @@ AlphaITB::regStats() Fault -AlphaITB::translate(RequestPtr &req, ExecContext *xc) const +AlphaITB::translate(RequestPtr &req, ThreadContext *tc) const { if (AlphaISA::PcPAL(req->getVaddr())) { // strip off PAL PC marker (lsb is 1) @@ -308,13 +308,13 @@ AlphaITB::translate(RequestPtr &req, ExecContext *xc) const // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5 // VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6 #if ALPHA_TLASER - if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && + if ((MCSR_SP(tc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && VAddrSpaceEV5(req->getVaddr()) == 2) { #else if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) { #endif // only valid in kernel mode - if (ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM)) != + if (ICM_CM(tc->readMiscReg(AlphaISA::IPR_ICM)) != AlphaISA::mode_kernel) { acv++; return new ItbAcvFault(req->getVaddr()); @@ -332,7 +332,7 @@ AlphaITB::translate(RequestPtr &req, ExecContext *xc) const } else { // not a physical address: need to look up pte - int asn = DTB_ASN_ASN(xc->readMiscReg(AlphaISA::IPR_DTB_ASN)); + int asn = DTB_ASN_ASN(tc->readMiscReg(AlphaISA::IPR_DTB_ASN)); AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(), asn); @@ -347,7 +347,7 @@ AlphaITB::translate(RequestPtr &req, ExecContext *xc) const // check permissions for this access if (!(pte->xre & - (1 << ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM))))) { + (1 << ICM_CM(tc->readMiscReg(AlphaISA::IPR_ICM))))) { // instruction access fault acv++; return new ItbAcvFault(req->getVaddr()); @@ -443,12 +443,12 @@ AlphaDTB::regStats() } Fault -AlphaDTB::translate(RequestPtr &req, ExecContext *xc, bool write) const +AlphaDTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const { - Addr pc = xc->readPC(); + Addr pc = tc->readPC(); AlphaISA::mode_type mode = - (AlphaISA::mode_type)DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)); + (AlphaISA::mode_type)DTB_CM_CM(tc->readMiscReg(AlphaISA::IPR_DTB_CM)); /** @@ -464,7 +464,7 @@ AlphaDTB::translate(RequestPtr &req, ExecContext *xc, bool write) const if (pc & 0x1) { mode = (req->getFlags() & ALTMODE) ? (AlphaISA::mode_type)ALT_MODE_AM( - xc->readMiscReg(AlphaISA::IPR_ALT_MODE)) + tc->readMiscReg(AlphaISA::IPR_ALT_MODE)) : AlphaISA::mode_kernel; } @@ -482,14 +482,14 @@ AlphaDTB::translate(RequestPtr &req, ExecContext *xc, bool write) const // Check for "superpage" mapping #if ALPHA_TLASER - if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && + if ((MCSR_SP(tc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && VAddrSpaceEV5(req->getVaddr()) == 2) { #else if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) { #endif // only valid in kernel mode - if (DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)) != + if (DTB_CM_CM(tc->readMiscReg(AlphaISA::IPR_DTB_CM)) != AlphaISA::mode_kernel) { if (write) { write_acv++; } else { read_acv++; } uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) | @@ -513,7 +513,7 @@ AlphaDTB::translate(RequestPtr &req, ExecContext *xc, bool write) const else read_accesses++; - int asn = DTB_ASN_ASN(xc->readMiscReg(AlphaISA::IPR_DTB_ASN)); + int asn = DTB_ASN_ASN(tc->readMiscReg(AlphaISA::IPR_DTB_ASN)); // not a physical address: need to look up pte AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(), diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index 81719cc48..07d01fa5c 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -41,7 +41,7 @@ #include "mem/request.hh" #include "sim/sim_object.hh" -class ExecContext; +class ThreadContext; class AlphaTLB : public SimObject { @@ -95,7 +95,7 @@ class AlphaITB : public AlphaTLB AlphaITB(const std::string &name, int size); virtual void regStats(); - Fault translate(RequestPtr &req, ExecContext *xc) const; + Fault translate(RequestPtr &req, ThreadContext *tc) const; }; class AlphaDTB : public AlphaTLB @@ -118,7 +118,7 @@ class AlphaDTB : public AlphaTLB AlphaDTB(const std::string &name, int size); virtual void regStats(); - Fault translate(RequestPtr &req, ExecContext *xc, bool write) const; + Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const; }; #endif // __ALPHA_MEMORY_HH__ diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index d2d148cc6..82e44b9e7 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -33,7 +33,7 @@ #include "arch/alpha/isa_traits.hh" #include "arch/alpha/tru64/process.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "kern/tru64/tru64.hh" #include "sim/process.hh" @@ -45,9 +45,9 @@ using namespace AlphaISA; /// Target uname() handler. static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) + ThreadContext *tc) { - TypedBufferArg<AlphaTru64::utsname> name(xc->getSyscallArg(0)); + TypedBufferArg<AlphaTru64::utsname> name(tc->getSyscallArg(0)); strcpy(name->sysname, "OSF1"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -55,43 +55,43 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process, strcpy(name->version, "732"); strcpy(name->machine, "alpha"); - name.copyOut(xc->getMemPort()); + name.copyOut(tc->getMemPort()); return 0; } /// Target getsysyinfo() handler. static SyscallReturn getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) + ThreadContext *tc) { - unsigned op = xc->getSyscallArg(0); - unsigned nbytes = xc->getSyscallArg(2); + unsigned op = tc->getSyscallArg(0); + unsigned nbytes = tc->getSyscallArg(2); switch (op) { case AlphaTru64::GSI_MAX_CPU: { - TypedBufferArg<uint32_t> max_cpu(xc->getSyscallArg(1)); + TypedBufferArg<uint32_t> max_cpu(tc->getSyscallArg(1)); *max_cpu = htog((uint32_t)process->numCpus()); - max_cpu.copyOut(xc->getMemPort()); + max_cpu.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CPUS_IN_BOX: { - TypedBufferArg<uint32_t> cpus_in_box(xc->getSyscallArg(1)); + TypedBufferArg<uint32_t> cpus_in_box(tc->getSyscallArg(1)); *cpus_in_box = htog((uint32_t)process->numCpus()); - cpus_in_box.copyOut(xc->getMemPort()); + cpus_in_box.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PHYSMEM: { - TypedBufferArg<uint64_t> physmem(xc->getSyscallArg(1)); + TypedBufferArg<uint64_t> physmem(tc->getSyscallArg(1)); *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB - physmem.copyOut(xc->getMemPort()); + physmem.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CPU_INFO: { - TypedBufferArg<AlphaTru64::cpu_info> infop(xc->getSyscallArg(1)); + TypedBufferArg<AlphaTru64::cpu_info> infop(tc->getSyscallArg(1)); infop->current_cpu = htog(0); infop->cpus_in_box = htog(process->numCpus()); @@ -103,30 +103,30 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, infop->cpu_ex_binding = htog(0); infop->mhz = htog(667); - infop.copyOut(xc->getMemPort()); + infop.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PROC_TYPE: { - TypedBufferArg<uint64_t> proc_type(xc->getSyscallArg(1)); + TypedBufferArg<uint64_t> proc_type(tc->getSyscallArg(1)); *proc_type = htog((uint64_t)11); - proc_type.copyOut(xc->getMemPort()); + proc_type.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PLATFORM_NAME: { - BufferArg bufArg(xc->getSyscallArg(1), nbytes); + BufferArg bufArg(tc->getSyscallArg(1), nbytes); strncpy((char *)bufArg.bufferPtr(), "COMPAQ Professional Workstation XP1000", nbytes); - bufArg.copyOut(xc->getMemPort()); + bufArg.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CLK_TCK: { - TypedBufferArg<uint64_t> clk_hz(xc->getSyscallArg(1)); + TypedBufferArg<uint64_t> clk_hz(tc->getSyscallArg(1)); *clk_hz = htog((uint64_t)1024); - clk_hz.copyOut(xc->getMemPort()); + clk_hz.copyOut(tc->getMemPort()); return 1; } @@ -141,14 +141,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, /// Target setsysyinfo() handler. static SyscallReturn setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) + ThreadContext *tc) { - unsigned op = xc->getSyscallArg(0); + unsigned op = tc->getSyscallArg(0); switch (op) { case AlphaTru64::SSI_IEEE_FP_CONTROL: warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n", - xc->getSyscallArg(1)); + tc->getSyscallArg(1)); break; default: @@ -163,22 +163,22 @@ setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, /// Target table() handler. static SyscallReturn tableFunc(SyscallDesc *desc, int callnum,Process *process, - ExecContext *xc) + ThreadContext *tc) { using namespace std; using namespace TheISA; - int id = xc->getSyscallArg(0); // table ID - int index = xc->getSyscallArg(1); // index into table + int id = tc->getSyscallArg(0); // table ID + int index = tc->getSyscallArg(1); // index into table // arg 2 is buffer pointer; type depends on table ID - int nel = xc->getSyscallArg(3); // number of elements - int lel = xc->getSyscallArg(4); // expected element size + int nel = tc->getSyscallArg(3); // number of elements + int lel = tc->getSyscallArg(4); // expected element size switch (id) { case AlphaTru64::TBL_SYSINFO: { if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo)) return -EINVAL; - TypedBufferArg<Tru64::tbl_sysinfo> elp(xc->getSyscallArg(2)); + TypedBufferArg<Tru64::tbl_sysinfo> elp(tc->getSyscallArg(2)); const int clk_hz = one_million; elp->si_user = htog(curTick / (Clock::Frequency / clk_hz)); @@ -190,7 +190,7 @@ SyscallReturn tableFunc(SyscallDesc *desc, int callnum,Process *process, elp->si_phz = htog(clk_hz); elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch? elp->si_max_procs = htog(process->numCpus()); - elp.copyOut(xc->getMemPort()); + elp.copyOut(tc->getMemPort()); return 0; } diff --git a/src/arch/alpha/tru64/system.cc b/src/arch/alpha/tru64/system.cc index 13e5c36db..8d9a53273 100644 --- a/src/arch/alpha/tru64/system.cc +++ b/src/arch/alpha/tru64/system.cc @@ -35,7 +35,7 @@ #include "base/loader/symtab.hh" #include "base/trace.hh" #include "cpu/base.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "kern/tru64/tru64_events.hh" #include "kern/system_events.hh" #include "mem/physical.hh" diff --git a/src/arch/alpha/tru64/system.hh b/src/arch/alpha/tru64/system.hh index 7f64d1042..947e92f50 100644 --- a/src/arch/alpha/tru64/system.hh +++ b/src/arch/alpha/tru64/system.hh @@ -36,7 +36,7 @@ #include "arch/isa_traits.hh" #include "sim/system.hh" -class ExecContext; +class ThreadContext; class BreakPCEvent; class BadAddrEvent; diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh index a94742320..ec136091c 100644 --- a/src/arch/alpha/utility.hh +++ b/src/arch/alpha/utility.hh @@ -109,10 +109,10 @@ namespace AlphaISA /** * Function to insure ISA semantics about 0 registers. - * @param xc The execution context. + * @param tc The thread context. */ - template <class XC> - void zeroRegisters(XC *xc); + template <class TC> + void zeroRegisters(TC *tc); #if FULL_SYSTEM // Alpha IPR register accessors @@ -143,15 +143,15 @@ namespace AlphaISA RoundPage(Addr addr) { return (addr + PageBytes - 1) & ~(PageBytes - 1); } - void initCPU(ExecContext *xc, int cpuId); - void initIPRs(ExecContext *xc, int cpuId); + void initCPU(ThreadContext *tc, int cpuId); + void initIPRs(ThreadContext *tc, int cpuId); /** * Function to check for and process any interrupts. - * @param xc The execution context. + * @param tc The thread context. */ - template <class XC> - void processInterrupts(XC *xc); + template <class TC> + void processInterrupts(TC *tc); #endif } // namespace AlphaISA diff --git a/src/arch/alpha/vtophys.cc b/src/arch/alpha/vtophys.cc index 0c69ea0a9..f7fd92c15 100644 --- a/src/arch/alpha/vtophys.cc +++ b/src/arch/alpha/vtophys.cc @@ -36,7 +36,7 @@ #include "arch/alpha/vtophys.hh" #include "base/chunk_generator.hh" #include "base/trace.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "mem/vport.hh" using namespace std; @@ -85,10 +85,10 @@ AlphaISA::vtophys(Addr vaddr) } Addr -AlphaISA::vtophys(ExecContext *xc, Addr addr) +AlphaISA::vtophys(ThreadContext *tc, Addr addr) { AlphaISA::VAddr vaddr = addr; - Addr ptbr = xc->readMiscReg(AlphaISA::IPR_PALtemp20); + Addr ptbr = tc->readMiscReg(AlphaISA::IPR_PALtemp20); Addr paddr = 0; //@todo Andrew couldn't remember why he commented some of this code //so I put it back in. Perhaps something to do with gdb debugging? @@ -101,7 +101,7 @@ AlphaISA::vtophys(ExecContext *xc, Addr addr) paddr = vaddr; } else { AlphaISA::PageTableEntry pte = - kernel_pte_lookup(xc->getPhysPort(), ptbr, vaddr); + kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr); if (pte.valid()) paddr = pte.paddr() | vaddr.offset(); } @@ -115,52 +115,52 @@ AlphaISA::vtophys(ExecContext *xc, Addr addr) void -AlphaISA::CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen) +AlphaISA::CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen) { uint8_t *dst = (uint8_t *)dest; - VirtualPort *vp = xc->getVirtPort(xc); + VirtualPort *vp = tc->getVirtPort(tc); vp->readBlob(src, dst, cplen); - xc->delVirtPort(vp); + tc->delVirtPort(vp); } void -AlphaISA::CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen) +AlphaISA::CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen) { uint8_t *src = (uint8_t *)source; - VirtualPort *vp = xc->getVirtPort(xc); + VirtualPort *vp = tc->getVirtPort(tc); vp->writeBlob(dest, src, cplen); - xc->delVirtPort(vp); + tc->delVirtPort(vp); } void -AlphaISA::CopyStringOut(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen) +AlphaISA::CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen) { int len = 0; - VirtualPort *vp = xc->getVirtPort(xc); + VirtualPort *vp = tc->getVirtPort(tc); do { vp->readBlob(vaddr++, (uint8_t*)dst++, 1); len++; } while (len < maxlen && dst[len] != 0 ); - xc->delVirtPort(vp); + tc->delVirtPort(vp); dst[len] = 0; } void -AlphaISA::CopyStringIn(ExecContext *xc, char *src, Addr vaddr) +AlphaISA::CopyStringIn(ThreadContext *tc, char *src, Addr vaddr) { - VirtualPort *vp = xc->getVirtPort(xc); + VirtualPort *vp = tc->getVirtPort(tc); for (ChunkGenerator gen(vaddr, strlen(src), AlphaISA::PageBytes); !gen.done(); gen.next()) { vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size()); src += gen.size(); } - xc->delVirtPort(vp); + tc->delVirtPort(vp); } diff --git a/src/arch/alpha/vtophys.hh b/src/arch/alpha/vtophys.hh index 57782a87a..472c694ff 100644 --- a/src/arch/alpha/vtophys.hh +++ b/src/arch/alpha/vtophys.hh @@ -34,7 +34,7 @@ #include "arch/alpha/isa_traits.hh" -class ExecContext; +class ThreadContext; class FunctionalPort; namespace AlphaISA { @@ -43,12 +43,12 @@ PageTableEntry kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr); Addr vtophys(Addr vaddr); -Addr vtophys(ExecContext *xc, Addr vaddr); +Addr vtophys(ThreadContext *tc, Addr vaddr); -void CopyOut(ExecContext *xc, void *dst, Addr src, size_t len); -void CopyIn(ExecContext *xc, Addr dst, void *src, size_t len); -void CopyStringOut(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen); -void CopyStringIn(ExecContext *xc, char *src, Addr vaddr); +void CopyOut(ThreadContext *tc, void *dst, Addr src, size_t len); +void CopyIn(ThreadContext *tc, Addr dst, void *src, size_t len); +void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen); +void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr); }; #endif // __ARCH_ALPHA_VTOPHYS_H__ diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index 22baaf98e..4d522e18a 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -25,6 +25,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Steve Reinhardt +# Korey Sewell import os import sys @@ -1181,6 +1182,11 @@ class IntRegOperand(Operand): if (self.size == self.dflt_size): return '%s = xc->readIntReg(this, %d);\n' % \ (self.base_name, self.src_reg_idx) + elif (self.size > self.dflt_size): + int_reg_val = 'xc->readIntReg(this, %d)' % (self.src_reg_idx) + if (self.is_signed): + int_reg_val = 'sext<%d>(%s)' % (self.dflt_size, int_reg_val) + return '%s = %s;\n' % (self.base_name, int_reg_val) else: return '%s = bits(xc->readIntReg(this, %d), %d, 0);\n' % \ (self.base_name, self.src_reg_idx, self.size-1) diff --git a/src/arch/mips/SConscript b/src/arch/mips/SConscript index 0365f5373..6295a6c11 100644 --- a/src/arch/mips/SConscript +++ b/src/arch/mips/SConscript @@ -28,6 +28,7 @@ # # Authors: Gabe Black # Steve Reinhardt +# Korey Sewell import os import sys @@ -46,6 +47,7 @@ Import('env') base_sources = Split(''' faults.cc isa_traits.cc + utility.cc ''') # Full-system sources diff --git a/src/arch/mips/faults.cc b/src/arch/mips/faults.cc index fa7275908..810c3fed4 100644 --- a/src/arch/mips/faults.cc +++ b/src/arch/mips/faults.cc @@ -29,7 +29,7 @@ */ #include "arch/mips/faults.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "cpu/base.hh" #include "base/trace.hh" @@ -102,28 +102,28 @@ FaultStat IntegerOverflowFault::_count; #if FULL_SYSTEM -void MipsFault::invoke(ExecContext * xc) +void MipsFault::invoke(ThreadContext * tc) { - FaultBase::invoke(xc); + FaultBase::invoke(tc); countStat()++; // exception restart address - if (setRestartAddress() || !xc->inPalMode()) - xc->setMiscReg(MipsISA::IPR_EXC_ADDR, xc->readPC()); + if (setRestartAddress() || !tc->inPalMode()) + tc->setMiscReg(MipsISA::IPR_EXC_ADDR, tc->readPC()); if (skipFaultingInstruction()) { // traps... skip faulting instruction. - xc->setMiscReg(MipsISA::IPR_EXC_ADDR, - xc->readMiscReg(MipsISA::IPR_EXC_ADDR) + 4); + tc->setMiscReg(MipsISA::IPR_EXC_ADDR, + tc->readMiscReg(MipsISA::IPR_EXC_ADDR) + 4); } - xc->setPC(xc->readMiscReg(MipsISA::IPR_PAL_BASE) + vect()); - xc->setNextPC(xc->readPC() + sizeof(MachInst)); + tc->setPC(tc->readMiscReg(MipsISA::IPR_PAL_BASE) + vect()); + tc->setNextPC(tc->readPC() + sizeof(MachInst)); } -void ArithmeticFault::invoke(ExecContext * xc) +void ArithmeticFault::invoke(ThreadContext * tc) { - FaultBase::invoke(xc); + FaultBase::invoke(tc); panic("Arithmetic traps are unimplemented!"); } diff --git a/src/arch/mips/faults.hh b/src/arch/mips/faults.hh index 134fa2c4e..d8bf59cc1 100644 --- a/src/arch/mips/faults.hh +++ b/src/arch/mips/faults.hh @@ -47,7 +47,7 @@ class MipsFault : public FaultBase virtual bool setRestartAddress() {return true;} public: #if FULL_SYSTEM - void invoke(ExecContext * xc); + void invoke(ThreadContext * tc); #endif virtual FaultVect vect() = 0; virtual FaultStat & countStat() = 0; @@ -114,7 +114,7 @@ class ArithmeticFault : public MipsFault FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} #if FULL_SYSTEM - void invoke(ExecContext * xc); + void invoke(ThreadContext * tc); #endif }; diff --git a/src/arch/mips/isa/base.isa b/src/arch/mips/isa/base.isa index b2a31c018..b733da7da 100644 --- a/src/arch/mips/isa/base.isa +++ b/src/arch/mips/isa/base.isa @@ -1,5 +1,33 @@ // -*- mode:c++ -*- +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell + //////////////////////////////////////////////////////////////////// // // Base class for MIPS instructions, and some support functions @@ -18,16 +46,6 @@ output header {{ { protected: - /// Make MipsISA register dependence tags directly visible in - /// this class and derived classes. Maybe these should really - /// live here and not in the MipsISA namespace. - /*enum DependenceTags { - FP_Base_DepTag = MipsISA::FP_Base_DepTag, - Fpcr_DepTag = MipsISA::Fpcr_DepTag, - Uniq_DepTag = MipsISA::Uniq_DepTag, - IPR_Base_DepTag = MipsISA::IPR_Base_DepTag - };*/ - // Constructor MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) : StaticInst(mnem, _machInst, __opClass) @@ -67,12 +85,12 @@ output decoder {{ } if(_numSrcRegs > 0) { - ss << ","; + ss << ", "; printReg(ss, _srcRegIdx[0]); } if(_numSrcRegs > 1) { - ss << ","; + ss << ", "; printReg(ss, _srcRegIdx[1]); } diff --git a/src/arch/mips/isa/bitfields.isa b/src/arch/mips/isa/bitfields.isa index e1124a591..e8d4578c7 100644 --- a/src/arch/mips/isa/bitfields.isa +++ b/src/arch/mips/isa/bitfields.isa @@ -1,5 +1,33 @@ // -*- mode:c++ -*- +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell + //////////////////////////////////////////////////////////////////// // // Bitfield definitions. @@ -17,20 +45,19 @@ def bitfield FUNCTION < 5: 0>; def bitfield FUNCTION_HI < 5: 3>; def bitfield FUNCTION_LO < 2: 0>; -// Integer operate format -def bitfield RT <20:16>; -def bitfield RT_HI <20:19>; -def bitfield RT_LO <18:16>; - def bitfield RS <25:21>; def bitfield RS_MSB <25:25>; def bitfield RS_HI <25:24>; def bitfield RS_LO <23:21>; -def bitfield RS_SRL <25:22>; - +def bitfield RS_SRL <25:22>; +def bitfield RS_RT <25:16>; +def bitfield RT <20:16>; +def bitfield RT_HI <20:19>; +def bitfield RT_LO <18:16>; +def bitfield RT_RD <20:11>; def bitfield RD <15:11>; -def bitfield INTIMM <15: 0>; // integer immediate (literal) +def bitfield INTIMM <15: 0>; // Floating-point operate format def bitfield FMT <25:21>; @@ -67,5 +94,9 @@ def bitfield HINT <10: 6>; def bitfield SYSCALLCODE <25: 6>; def bitfield TRAPCODE <15:13>; +// EXT/INS instructions +def bitfield MSB <15:11>; +def bitfield LSB <10: 6>; + // M5 instructions def bitfield M5FUNC <7:0>; diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa index 1454aba39..a64f74c4f 100644 --- a/src/arch/mips/isa/decoder.isa +++ b/src/arch/mips/isa/decoder.isa @@ -1,4 +1,32 @@ - // -*- mode:c++ -*- +// -*- mode:c++ -*- + +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell //////////////////////////////////////////////////////////////////// // @@ -6,41 +34,33 @@ // ----------------------------- // The following instructions are specified in the MIPS32 ISA // Specification. Decoding closely follows the style specified -// in the MIPS32 ISAthe specification document starting with Table +// in the MIPS32 ISA specification document starting with Table // A-2 (document available @ www.mips.com) // -//@todo: Distinguish "unknown/future" use insts from "reserved" -// ones decode OPCODE_HI default Unknown::unknown() { - - // Derived From ... Table A-2 MIPS32 ISA Manual + //Table A-2 0x0: decode OPCODE_LO { - 0x0: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { 0x1: decode MOVCI { format BasicOp { - 0: movf({{ if (getFPConditionCode(FCSR, CC) == 0) Rd = Rs}}); - 1: movt({{ if (getFPConditionCode(FCSR, CC) == 1) Rd = Rs}}); + 0: movf({{ Rd = (getCondCode(FCSR, CC) == 0) ? Rd : Rs; }}); + 1: movt({{ Rd = (getCondCode(FCSR, CC) == 1) ? Rd : Rs; }}); } } format BasicOp { - - //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields - //are used to distinguish among the SLL, NOP, SSNOP and EHB functions. + //Table A-3 Note: "Specific encodings of the rd, rs, and + //rt fields are used to distinguish SLL, SSNOP, and EHB + //functions 0x0: decode RS { - 0x0: decode RT { //fix Nop traditional vs. Nop converted disassembly later - 0x0: decode RD default Nop::nop(){ - 0x0: decode SA { - 0x1: ssnop({{ ; }}); //really sll r0,r0,1 - 0x3: ehb({{ ; }}); //really sll r0,r0,3 - } - } - - default: sll({{ Rd = Rt.uw << SA; }}); + 0x0: decode RT_RD { + 0x0: decode SA default Nop::nop(){ + 0x1: WarnUnimpl::ssnop(); + 0x3: WarnUnimpl::ehb(); + } + default: sll({{ Rd = Rt.uw << SA; }}); } - } 0x2: decode RS_SRL { @@ -55,7 +75,6 @@ decode OPCODE_HI default Unknown::unknown() { 0x3: decode RS { 0x0: sra({{ uint32_t temp = Rt >> SA; - if ( (Rt & 0x80000000) > 0 ) { uint32_t mask = 0x80000000; for(int i=0; i < SA; i++) { @@ -63,7 +82,6 @@ decode OPCODE_HI default Unknown::unknown() { mask = mask >> 1; } } - Rd = temp; }}); } @@ -96,37 +114,36 @@ decode OPCODE_HI default Unknown::unknown() { } 0x1: decode FUNCTION_LO { - - //Table A-3 Note: "Specific encodings of the hint field are used - //to distinguish JR from JR.HB and JALR from JALR.HB" + //Table A-3 Note: "Specific encodings of the hint field are + //used to distinguish JR from JR.HB and JALR from JALR.HB" format Jump { 0x0: decode HINT { - 0:jr({{ NNPC = Rs & ~1; }},IsReturn); - - 1:jr_hb({{ NNPC = Rs & ~1; clear_exe_inst_hazards(); }},IsReturn); + 0x1: jr_hb({{ NNPC = Rs & ~1; }}, IsReturn, ClearHazards); + default: jr({{ NNPC = Rs & ~1; }}, IsReturn); } 0x1: decode HINT { - 0: jalr({{ Rd = NNPC; NNPC = Rs; }},IsCall,IsReturn); - - 1: jalr_hb({{ Rd = NNPC; NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn); + 0x1: jalr_hb({{ Rd = NNPC; NNPC = Rs; }}, IsCall, Link + , ClearHazards); + default: jalr({{ Rd = NNPC; NNPC = Rs; }}, IsCall, + Link); } } format BasicOp { - 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); - 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); + 0x2: movz({{ Rd = (Rt == 0) ? Rs : Rd; }}); + 0x3: movn({{ Rd = (Rt != 0) ? Rs : Rd; }}); + 0x4: syscall({{ xc->syscall(R2); }}, IsNonSpeculative); + 0x7: sync({{ ; }}, IsMemBarrier); } - format BasicOp { - 0x4: syscall({{ xc->syscall(R2); }},IsNonSpeculative); - 0x5: break({{ panic("Not implemented break yet"); }},IsNonSpeculative); - 0x7: sync({{ panic("Not implemented sync yet"); }},IsNonSpeculative); + format FailUnimpl { + 0x5: break(); } } 0x2: decode FUNCTION_LO { - format BasicOp { + format HiLoMiscOp { 0x0: mfhi({{ Rd = HI; }}); 0x1: mthi({{ HI = Rs; }}); 0x2: mflo({{ Rd = LO; }}); @@ -135,24 +152,16 @@ decode OPCODE_HI default Unknown::unknown() { } 0x3: decode FUNCTION_LO { - format IntOp { - 0x0: mult({{ - int64_t temp1 = Rs.sd * Rt.sd; - HI = temp1<63:32>; - LO = temp1<31:0>; - }}); - - 0x1: multu({{ - uint64_t temp1 = Rs.ud * Rt.ud; - HI = temp1<63:32>; - LO = temp1<31:0>; - }}); + format HiLoOp { + 0x0: mult({{ val = Rs.sd * Rt.sd; }}); + 0x1: multu({{ val = Rs.ud * Rt.ud; }}); + } + format HiLoMiscOp { 0x2: div({{ HI = Rs.sd % Rt.sd; LO = Rs.sd / Rt.sd; }}); - 0x3: divu({{ HI = Rs.ud % Rt.ud; LO = Rs.ud / Rt.ud; @@ -201,11 +210,8 @@ decode OPCODE_HI default Unknown::unknown() { format Branch { 0x0: bltz({{ cond = (Rs.sw < 0); }}); 0x1: bgez({{ cond = (Rs.sw >= 0); }}); - } - - format BranchLikely { - 0x2: bltzl({{ cond = (Rs.sw < 0); }}); - 0x3: bgezl({{ cond = (Rs.sw >= 0); }}); + 0x2: bltzl({{ cond = (Rs.sw < 0); }}, Likely); + 0x3: bgezl({{ cond = (Rs.sw >= 0); }}, Likely); } } @@ -222,13 +228,13 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode REGIMM_LO { format Branch { - 0x0: bltzal({{ cond = (Rs.sw < 0); }}, IsCall,IsReturn); - 0x1: bgezal({{ cond = (Rs.sw >= 0); }}, IsCall,IsReturn); - } - - format BranchLikely { - 0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsCall, IsReturn); - 0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsCall, IsReturn); + 0x0: bltzal({{ cond = (Rs.sw < 0); }}, Link); + 0x1: decode RS { + 0x0: bal ({{ cond = 1; }}, IsCall, Link); + default: bgezal({{ cond = (Rs.sw >= 0); }}, Link); + } + 0x2: bltzall({{ cond = (Rs.sw < 0); }}, Link, Likely); + 0x3: bgezall({{ cond = (Rs.sw >= 0); }}, Link, Likely); } } @@ -241,25 +247,23 @@ decode OPCODE_HI default Unknown::unknown() { format Jump { 0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2);}}); - - 0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }},IsCall,IsReturn); + 0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }}, IsCall, + Link); } format Branch { - 0x4: beq({{ cond = (Rs.sw == Rt.sw); }}); - 0x5: bne({{ cond = (Rs.sw != Rt.sw); }}); - 0x6: decode RT { - 0x0: blez({{ cond = (Rs.sw <= 0); }}); - } - - 0x7: decode RT { - 0x0: bgtz({{ cond = (Rs.sw > 0); }}); + 0x4: decode RS_RT { + 0x0: b({{ cond = 1; }}); + default: beq({{ cond = (Rs.sw == Rt.sw); }}); } + 0x5: bne({{ cond = (Rs.sw != Rt.sw); }}); + 0x6: blez({{ cond = (Rs.sw <= 0); }}); + 0x7: bgtz({{ cond = (Rs.sw > 0); }}); } } 0x1: decode OPCODE_LO { - format IntOp { + format IntImmOp { 0x0: addi({{ Rt.sw = Rs.sw + imm; /*Trap If Overflow*/}}); 0x1: addiu({{ Rt.sw = Rs.sw + imm;}}); 0x2: slti({{ Rt.sw = ( Rs.sw < imm) ? 1 : 0 }}); @@ -275,112 +279,47 @@ decode OPCODE_HI default Unknown::unknown() { } 0x2: decode OPCODE_LO { - //Table A-11 MIPS32 COP0 Encoding of rs Field 0x0: decode RS_MSB { 0x0: decode RS { - format System { - 0x0: mfc0({{ - //uint64_t reg_num = Rd.uw; - - Rt = xc->readMiscReg(RD << 5 | SEL); - }}); - - 0x4: mtc0({{ - //uint64_t reg_num = Rd.uw; - - xc->setMiscReg(RD << 5 | SEL,Rt); - }}); - - 0x8: mftr({{ - //The contents of the coprocessor 0 register specified by the - //combination of rd and sel are loaded into general register - //rt. Note that not all coprocessor 0 registers support the - //sel field. In those instances, the sel field must be zero. - - //MT Code Needed Here - - }}); - - 0xC: mttr({{ - //The contents of the coprocessor 0 register specified by the - //combination of rd and sel are loaded into general register - //rt. Note that not all coprocessor 0 registers support the - //sel field. In those instances, the sel field must be zero. - - //MT Code Needed Here - }}); - - - 0xA: rdpgpr({{ - //Accessing Previous Shadow Set Register Number - //uint64_t prev = xc->readMiscReg(SRSCtl)/*[PSS]*/; - //uint64_t reg_num = Rt.uw; - - //Rd = xc->regs.IntRegFile[prev]; - //Rd = xc->shadowIntRegFile[prev][reg_num]; - }}); + format CP0Control { + 0x0: mfc0({{ Rt = xc->readMiscReg(RD << 5 | SEL); }}); + 0x4: mtc0({{ xc->setMiscReg(RD << 5 | SEL, Rt); }}); + } + format MipsMT { + 0x8: mftr(); + 0xC: mttr(); 0xB: decode RD { - 0x0: decode SC { - 0x0: dvpe({{ - Rt.sw = xc->readMiscReg(MVPControl); - xc->setMiscReg(MVPControl,0); - }}); - - 0x1: evpe({{ - Rt.sw = xc->readMiscReg(MVPControl); - xc->setMiscReg(MVPControl,1); - }}); + 0x0: dvpe(); + 0x1: evpe(); } - 0x1: decode SC { - 0x0: dmt({{ - Rt.sw = xc->readMiscReg(VPEControl); - xc->setMiscReg(VPEControl,0); - }}); - - 0x1: emt({{ - Rt.sw = xc->readMiscReg(VPEControl); - xc->setMiscReg(VPEControl,1); - }}); - } - - 0xC: decode SC { - 0x0: di({{ - Rt.sw = xc->readMiscReg(Status); - xc->setMiscReg(Status,0); - }}); - - 0x1: ei({{ - Rt.sw = xc->readMiscReg(Status); - xc->setMiscReg(Status,1); - }}); + 0x0: dmt(); + 0x1: emt(); + 0xC: decode SC { + 0x0: di(); + 0x1: ei(); + } } } + } - 0xE: wrpgpr({{ - //Accessing Previous Shadow Set Register Number - //uint64_t prev = xc->readMiscReg(SRSCtl/*[PSS]*/); - //uint64_t reg_num = Rd.uw; - - //xc->regs.IntRegFile[prev]; - //xc->shadowIntRegFile[prev][reg_num] = Rt; - }}); + format FailUnimpl { + 0xA: rdpgpr(); + 0xE: wrpgpr(); } } //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO 0x1: decode FUNCTION { - format System { - 0x01: tlbr({{ }}); - 0x02: tlbwi({{ }}); - 0x06: tlbwr({{ }}); - 0x08: tlbp({{ }}); - } + format FailUnimpl { + 0x01: tlbr(); + 0x02: tlbwi(); + 0x06: tlbwr(); + 0x08: tlbp(); - format WarnUnimpl { 0x18: eret(); 0x1F: deret(); 0x20: wait(); @@ -393,18 +332,9 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode RS_HI { 0x0: decode RS_LO { - format FloatOp { + format CP1Control { 0x0: mfc1 ({{ Rt.uw = Fs.uw<31:0>; }}); - 0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}}); - 0x4: mtc1 ({{ Fs.uw = Rt.uw; }}); - 0x7: mthc1({{ - uint64_t fs_hi = Rt.uw; - uint64_t fs_lo = Fs.ud & 0x0000FFFF; - Fs.ud = fs_hi << 32 | fs_lo; - }}); - } - format System { 0x2: cfc1({{ switch (FS) { @@ -424,11 +354,14 @@ decode OPCODE_HI default Unknown::unknown() { Rt = FCSR; break; default: - panic("FP Control Value (%d) Not Available. Ignoring Access to" - "Floating Control Status Register",FS); + panic("FP Control Value (%d) Not Valid"); } }}); + 0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}}); + + 0x4: mtc1 ({{ Fs.uw = Rt.uw; }}); + 0x6: ctc1({{ switch (FS) { @@ -464,21 +397,29 @@ decode OPCODE_HI default Unknown::unknown() { "Floating Control Status Register", FS); } }}); + + 0x7: mthc1({{ + uint64_t fs_hi = Rt.uw; + uint64_t fs_lo = Fs.ud & 0x0FFFFFFFF; + Fs.ud = (fs_hi << 32) | fs_lo; + }}); + } } 0x1: decode ND { - 0x0: decode TF { - format Branch { - 0x0: bc1f({{ cond = (getFPConditionCode(FCSR,CC) == 0); }}); - 0x1: bc1t({{ cond = (getFPConditionCode(FCSR,CC) == 1); }}); + format Branch { + 0x0: decode TF { + 0x0: bc1f({{ cond = getCondCode(FCSR, BRANCH_CC) == 0; + }}); + 0x1: bc1t({{ cond = getCondCode(FCSR, BRANCH_CC) == 1; + }}); } - } - - 0x1: decode TF { - format BranchLikely { - 0x0: bc1fl({{ cond = (getFPConditionCode(FCSR,CC) == 0); }}); - 0x1: bc1tl({{ cond = (getFPConditionCode(FCSR,CC) == 1); }}); + 0x1: decode TF { + 0x0: bc1fl({{ cond = getCondCode(FCSR, BRANCH_CC) == 0; + }}, Likely); + 0x1: bc1tl({{ cond = getCondCode(FCSR, BRANCH_CC) == 1; + }}, Likely); } } } @@ -486,9 +427,8 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: decode RS_HI { 0x2: decode RS_LO { - //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S - //(( single-word )) + //(( single-precision floating point)) 0x0: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { format FloatOp { @@ -499,194 +439,102 @@ decode OPCODE_HI default Unknown::unknown() { 0x4: sqrt_s({{ Fd.sf = sqrt(Fs.sf);}}); 0x5: abs_s({{ Fd.sf = fabs(Fs.sf);}}); 0x6: mov_s({{ Fd.sf = Fs.sf;}}); - 0x7: neg_s({{ Fd.sf = -1 * Fs.sf;}}); + 0x7: neg_s({{ Fd.sf = -Fs.sf;}}); } } 0x1: decode FUNCTION_LO { - format Float64Op { - 0x0: round_l_s({{ - Fd.ud = fpConvert(roundFP(Fs.sf,0), SINGLE_TO_LONG); - }}); - - 0x1: trunc_l_s({{ - Fd.ud = fpConvert(truncFP(Fs.sf), SINGLE_TO_LONG); - }}); - - 0x2: ceil_l_s({{ - Fd.ud = fpConvert(ceil(Fs.sf), SINGLE_TO_LONG); - }}); - - 0x3: floor_l_s({{ - Fd.ud = fpConvert(floor(Fs.sf), SINGLE_TO_LONG); - }}); - } - - format FloatOp { - 0x4: round_w_s({{ - Fd.uw = fpConvert(roundFP(Fs.sf,0), SINGLE_TO_WORD); - }}); - - 0x5: trunc_w_s({{ - Fd.uw = fpConvert(truncFP(Fs.sf), SINGLE_TO_WORD); - }}); - - 0x6: ceil_w_s({{ - Fd.uw = fpConvert(ceil(Fs.sf), SINGLE_TO_WORD); - }}); - - 0x7: floor_w_s({{ - Fd.uw = fpConvert(floor(Fs.sf), SINGLE_TO_WORD); - }}); + format FloatConvertOp { + 0x0: round_l_s({{ val = Fs.sf; }}, ToLong, + Round); + 0x1: trunc_l_s({{ val = Fs.sf; }}, ToLong, + Trunc); + 0x2: ceil_l_s({{ val = Fs.sf; }}, ToLong, + Ceil); + 0x3: floor_l_s({{ val = Fs.sf; }}, ToLong, + Floor); + 0x4: round_w_s({{ val = Fs.sf; }}, ToWord, + Round); + 0x5: trunc_w_s({{ val = Fs.sf; }}, ToWord, + Trunc); + 0x6: ceil_w_s({{ val = Fs.sf; }}, ToWord, + Ceil); + 0x7: floor_w_s({{ val = Fs.sf; }}, ToWord, + Floor); } } 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { - format FloatOp { - 0x0: movf_s({{if (getFPConditionCode(FCSR,CC) == 0) Fd = Fs;}}); - 0x1: movt_s({{if (getFPConditionCode(FCSR,CC) == 1) Fd = Fs;}}); + format BasicOp { + 0x0: movf_s({{ Fd = (getCondCode(FCSR,CC) == 0) ? Fs : Fd; }}); + 0x1: movt_s({{ Fd = (getCondCode(FCSR,CC) == 1) ? Fs : Fd; }}); } } + format BasicOp { + 0x2: movz_s({{ Fd = (Rt == 0) ? Fs : Fd; }}); + 0x3: movn_s({{ Fd = (Rt != 0) ? Fs : Fd; }}); + } + format FloatOp { - 0x2: movz_s({{ if (Rt == 0) Fd = Fs; }}); - 0x3: movn_s({{ if (Rt != 0) Fd = Fs; }}); 0x5: recip_s({{ Fd = 1 / Fs; }}); 0x6: rsqrt_s({{ Fd = 1 / sqrt(Fs);}}); } } 0x4: decode FUNCTION_LO { - format FloatConvertOp { - 0x1: cvt_d_s({{ - Fd.ud = fpConvert(Fs.sf, SINGLE_TO_DOUBLE); - }}); - - 0x4: cvt_w_s({{ - Fd.uw = fpConvert(Fs.sf, SINGLE_TO_WORD); - }}); + 0x1: cvt_d_s({{ val = Fs.sf; }}, ToDouble); + 0x4: cvt_w_s({{ val = Fs.sf; }}, ToWord); + 0x5: cvt_l_s({{ val = Fs.sf; }}, ToLong); } - format FloatConvertOp { - 0x5: cvt_l_s({{ - Fd.ud = fpConvert(Fs.sf, SINGLE_TO_LONG); + 0x6: FloatOp::cvt_ps_s({{ + Fd.ud = (uint64_t) Fs.uw << 32 | + (uint64_t) Ft.uw; }}); - - 0x6: cvt_ps_st({{ - Fd.ud = (uint64_t)Fs.uw << 32 | (uint64_t)Ft.uw; - }}); - } } 0x6: decode FUNCTION_LO { format FloatCompareOp { - 0x0: c_f_s({{ cond = 0; }}); - - 0x1: c_un_s({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond = 1; - else - cond = 0; - }}); - - 0x2: c_eq_s({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond = 0; - else - cond = (Fs.sf == Ft.sf); - }}); - - 0x3: c_ueq_s({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond = 1; - else - cond = (Fs.sf == Ft.sf); - }}); - - 0x4: c_olt_s({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond = 0; - else - cond = (Fs.sf < Ft.sf); - }}); - - 0x5: c_ult_s({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond = 1; - else - cond = (Fs.sf < Ft.sf); - }}); - - 0x6: c_ole_s({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond = 0; - else - cond = (Fs.sf <= Ft.sf); - }}); - - 0x7: c_ule_s({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond = 1; - else - cond = (Fs.sf <= Ft.sf); - }}); + 0x0: c_f_s({{ cond = 0; }}, SinglePrecision, + UnorderedFalse); + 0x1: c_un_s({{ cond = 0; }}, SinglePrecision, + UnorderedTrue); + 0x2: c_eq_s({{ cond = (Fs.sf == Ft.sf); }}, + UnorderedFalse); + 0x3: c_ueq_s({{ cond = (Fs.sf == Ft.sf); }}, + UnorderedTrue); + 0x4: c_olt_s({{ cond = (Fs.sf < Ft.sf); }}, + UnorderedFalse); + 0x5: c_ult_s({{ cond = (Fs.sf < Ft.sf); }}, + UnorderedTrue); + 0x6: c_ole_s({{ cond = (Fs.sf <= Ft.sf); }}, + UnorderedFalse); + 0x7: c_ule_s({{ cond = (Fs.sf <= Ft.sf); }}, + UnorderedTrue); } } 0x7: decode FUNCTION_LO { - format FloatCompareWithXcptOp { - 0x0: c_sf_s({{ cond = 0; }}); - - 0x1: c_ngle_s({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond = 1; - else - cond = 0; - }}); - - 0x2: c_seq_s({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond = 0; - else - cond = (Fs.sf == Ft.sf); - }}); - - 0x3: c_ngl_s({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond = 1; - else - cond = (Fs.sf == Ft.sf); - }}); - - 0x4: c_lt_s({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond = 0; - else - cond = (Fs.sf < Ft.sf); - }}); - - 0x5: c_nge_s({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond = 1; - else - cond = (Fs.sf < Ft.sf); - }}); - - 0x6: c_le_s({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond = 0; - else - cond = (Fs.sf <= Ft.sf); - }}); - - 0x7: c_ngt_s({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond = 1; - else - cond = (Fs.sf <= Ft.sf); - }}); + format FloatCompareOp { + 0x0: c_sf_s({{ cond = 0; }}, SinglePrecision, + UnorderedFalse, QnanException); + 0x1: c_ngle_s({{ cond = 0; }}, SinglePrecision, + UnorderedTrue, QnanException); + 0x2: c_seq_s({{ cond = (Fs.sf == Ft.sf);}}, + UnorderedFalse, QnanException); + 0x3: c_ngl_s({{ cond = (Fs.sf == Ft.sf); }}, + UnorderedTrue, QnanException); + 0x4: c_lt_s({{ cond = (Fs.sf < Ft.sf); }}, + UnorderedFalse, QnanException); + 0x5: c_nge_s({{ cond = (Fs.sf < Ft.sf); }}, + UnorderedTrue, QnanException); + 0x6: c_le_s({{ cond = (Fs.sf <= Ft.sf); }}, + UnorderedFalse, QnanException); + 0x7: c_ngt_s({{ cond = (Fs.sf <= Ft.sf); }}, + UnorderedTrue, QnanException); } } } @@ -695,197 +543,108 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { format FloatOp { - 0x0: add_d({{ Fd.df = Fs.df + Ft.df;}}); - 0x1: sub_d({{ Fd.df = Fs.df - Ft.df;}}); - 0x2: mul_d({{ Fd.df = Fs.df * Ft.df;}}); - 0x3: div_d({{ Fd.df = Fs.df / Ft.df;}}); - 0x4: sqrt_d({{ Fd.df = sqrt(Fs.df);}}); - 0x5: abs_d({{ Fd.df = fabs(Fs.df);}}); - 0x6: mov_d({{ Fd.ud = Fs.ud;}}); - 0x7: neg_d({{ Fd.df = -1 * Fs.df;}}); + 0x0: add_d({{ Fd.df = Fs.df + Ft.df; }}); + 0x1: sub_d({{ Fd.df = Fs.df - Ft.df; }}); + 0x2: mul_d({{ Fd.df = Fs.df * Ft.df; }}); + 0x3: div_d({{ Fd.df = Fs.df / Ft.df; }}); + 0x4: sqrt_d({{ Fd.df = sqrt(Fs.df); }}); + 0x5: abs_d({{ Fd.df = fabs(Fs.df); }}); + 0x6: mov_d({{ Fd.df = Fs.df; }}); + 0x7: neg_d({{ Fd.df = -1 * Fs.df; }}); } } 0x1: decode FUNCTION_LO { - format FloatOp { - 0x0: round_l_d({{ - Fd.ud = fpConvert(roundFP(Fs.df,0), DOUBLE_TO_LONG); - }}); - - 0x1: trunc_l_d({{ - Fd.ud = fpConvert(truncFP(Fs.df), DOUBLE_TO_LONG); - }}); - - 0x2: ceil_l_d({{ - Fd.ud = fpConvert(ceil(Fs.df), DOUBLE_TO_LONG); - }}); - - 0x3: floor_l_d({{ - Fd.ud = fpConvert(floor(Fs.df), DOUBLE_TO_LONG); - }}); - } - - format FloatOp { - 0x4: round_w_d({{ - Fd.uw = fpConvert(roundFP(Fs.df,0), DOUBLE_TO_WORD); - }}); - - 0x5: trunc_w_d({{ - Fd.uw = fpConvert(truncFP(Fs.df), DOUBLE_TO_WORD); - }}); - - 0x6: ceil_w_d({{ - Fd.uw = fpConvert(ceil(Fs.df), DOUBLE_TO_WORD); - }}); - - 0x7: floor_w_d({{ - Fd.uw = fpConvert(floor(Fs.df), DOUBLE_TO_WORD); - }}); + format FloatConvertOp { + 0x0: round_l_d({{ val = Fs.df; }}, ToLong, + Round); + 0x1: trunc_l_d({{ val = Fs.df; }}, ToLong, + Trunc); + 0x2: ceil_l_d({{ val = Fs.df; }}, ToLong, + Ceil); + 0x3: floor_l_d({{ val = Fs.df; }}, ToLong, + Floor); + 0x4: round_w_d({{ val = Fs.df; }}, ToWord, + Round); + 0x5: trunc_w_d({{ val = Fs.df; }}, ToWord, + Trunc); + 0x6: ceil_w_d({{ val = Fs.df; }}, ToWord, + Ceil); + 0x7: floor_w_d({{ val = Fs.df; }}, ToWord, + Floor); } } 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { - format FloatOp { - 0x0: movf_d({{if (getFPConditionCode(FCSR,CC) == 0) Fd.df = Fs.df; }}); - 0x1: movt_d({{if (getFPConditionCode(FCSR,CC) == 1) Fd.df = Fs.df; }}); + format BasicOp { + 0x0: movf_d({{ Fd.df = (getCondCode(FCSR,CC) == 0) ? + Fs.df : Fd.df; + }}); + 0x1: movt_d({{ Fd.df = (getCondCode(FCSR,CC) == 1) ? + Fs.df : Fd.df; + }}); } } format BasicOp { - 0x2: movz_d({{ if (Rt == 0) Fd.df = Fs.df; }}); - 0x3: movn_d({{ if (Rt != 0) Fd.df = Fs.df; }}); + 0x2: movz_d({{ Fd.df = (Rt == 0) ? Fs.df : Fd.df; }}); + 0x3: movn_d({{ Fd.df = (Rt != 0) ? Fs.df : Fd.df; }}); } format FloatOp { - 0x5: recip_d({{ Fd.df = 1 / Fs.df}}); + 0x5: recip_d({{ Fd.df = 1 / Fs.df }}); 0x6: rsqrt_d({{ Fd.df = 1 / sqrt(Fs.df) }}); } } 0x4: decode FUNCTION_LO { - format FloatOp { - 0x0: cvt_s_d({{ - Fd.uw = fpConvert(Fs.df, DOUBLE_TO_SINGLE); - }}); - - 0x4: cvt_w_d({{ - Fd.uw = fpConvert(Fs.df, DOUBLE_TO_WORD); - }}); - - 0x5: cvt_l_d({{ - Fd.ud = fpConvert(Fs.df, DOUBLE_TO_LONG); - }}); + format FloatConvertOp { + 0x0: cvt_s_d({{ val = Fs.df; }}, ToSingle); + 0x4: cvt_w_d({{ val = Fs.df; }}, ToWord); + 0x5: cvt_l_d({{ val = Fs.df; }}, ToLong); } } 0x6: decode FUNCTION_LO { format FloatCompareOp { - 0x0: c_f_d({{ cond = 0; }}); - - 0x1: c_un_d({{ - if (isnan(Fs.df) || isnan(Ft.df)) - cond = 1; - else - cond = 0; - }}); - - 0x2: c_eq_d({{ - if (isnan(Fs.df) || isnan(Ft.df)) - cond = 0; - else - cond = (Fs.df == Ft.df); - }}); - - 0x3: c_ueq_d({{ - if (isnan(Fs.df) || isnan(Ft.df)) - cond = 1; - else - cond = (Fs.df == Ft.df); - }}); - - 0x4: c_olt_d({{ - if (isnan(Fs.df) || isnan(Ft.df)) - cond = 0; - else - cond = (Fs.df < Ft.df); - }}); - - 0x5: c_ult_d({{ - if (isnan(Fs.df) || isnan(Ft.df)) - cond = 1; - else - cond = (Fs.df < Ft.df); - }}); - - 0x6: c_ole_d({{ - if (isnan(Fs.df) || isnan(Ft.df)) - cond = 0; - else - cond = (Fs.df <= Ft.df); - }}); - - 0x7: c_ule_d({{ - if (isnan(Fs.df) || isnan(Ft.df)) - cond = 1; - else - cond = (Fs.df <= Ft.df); - }}); + 0x0: c_f_d({{ cond = 0; }}, DoublePrecision, + UnorderedFalse); + 0x1: c_un_d({{ cond = 0; }}, DoublePrecision, + UnorderedTrue); + 0x2: c_eq_d({{ cond = (Fs.df == Ft.df); }}, + UnorderedFalse); + 0x3: c_ueq_d({{ cond = (Fs.df == Ft.df); }}, + UnorderedTrue); + 0x4: c_olt_d({{ cond = (Fs.df < Ft.df); }}, + UnorderedFalse); + 0x5: c_ult_d({{ cond = (Fs.df < Ft.df); }}, + UnorderedTrue); + 0x6: c_ole_d({{ cond = (Fs.df <= Ft.df); }}, + UnorderedFalse); + 0x7: c_ule_d({{ cond = (Fs.df <= Ft.df); }}, + UnorderedTrue); } } 0x7: decode FUNCTION_LO { - format FloatCompareWithXcptOp { - 0x0: c_sf_d({{ cond = 0; }}); - - 0x1: c_ngle_d({{ - if (isnan(Fs.df) || isnan(Ft.df)) - cond = 1; - else - cond = 0; - }}); - - 0x2: c_seq_d({{ - if (isnan(Fs.df) || isnan(Ft.df)) - cond = 0; - else - cond = (Fs.df == Ft.df); - }}); - - 0x3: c_ngl_d({{ - if (isnan(Fs.df) || isnan(Ft.df)) - cond = 1; - else - cond = (Fs.df == Ft.df); - }}); - - 0x4: c_lt_d({{ - if (isnan(Fs.df) || isnan(Ft.df)) - cond = 0; - else - cond = (Fs.df < Ft.df); - }}); - - 0x5: c_nge_d({{ - if (isnan(Fs.df) || isnan(Ft.df)) - cond = 1; - else - cond = (Fs.df < Ft.df); - }}); - - 0x6: c_le_d({{ - if (isnan(Fs.df) || isnan(Ft.df)) - cond = 0; - else - cond = (Fs.df <= Ft.df); - }}); - - 0x7: c_ngt_d({{ - if (isnan(Fs.df) || isnan(Ft.df)) - cond = 1; - else - cond = (Fs.df <= Ft.df); - }}); + format FloatCompareOp { + 0x0: c_sf_d({{ cond = 0; }}, DoublePrecision, + UnorderedFalse, QnanException); + 0x1: c_ngle_d({{ cond = 0; }}, DoublePrecision, + UnorderedTrue, QnanException); + 0x2: c_seq_d({{ cond = (Fs.df == Ft.df); }}, + UnorderedFalse, QnanException); + 0x3: c_ngl_d({{ cond = (Fs.df == Ft.df); }}, + UnorderedTrue, QnanException); + 0x4: c_lt_d({{ cond = (Fs.df < Ft.df); }}, + UnorderedFalse, QnanException); + 0x5: c_nge_d({{ cond = (Fs.df < Ft.df); }}, + UnorderedTrue, QnanException); + 0x6: c_le_d({{ cond = (Fs.df <= Ft.df); }}, + UnorderedFalse, QnanException); + 0x7: c_ngt_d({{ cond = (Fs.df <= Ft.df); }}, + UnorderedTrue, QnanException); } } } @@ -893,19 +652,9 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W 0x4: decode FUNCTION { format FloatConvertOp { - 0x20: cvt_s_w({{ - Fd.uw = fpConvert(Fs.sf, WORD_TO_SINGLE); - }}); - - 0x21: cvt_d_w({{ - Fd.ud = fpConvert(Fs.sf, WORD_TO_DOUBLE); - }}); - } - - format Float64ConvertOp { - 0x26: cvt_ps_pw({{ - Fd.ud = fpConvert(Fs.ud, WORD_TO_PS); - }}); + 0x20: cvt_s_w({{ val = Fs.uw; }}, ToSingle); + 0x21: cvt_d_w({{ val = Fs.uw; }}, ToDouble); + 0x26: FailUnimpl::cvt_ps_w(); } } @@ -913,18 +662,10 @@ decode OPCODE_HI default Unknown::unknown() { //Note: "1. Format type L is legal only if 64-bit floating point operations //are enabled." 0x5: decode FUNCTION_HI { - format Float64ConvertOp { - 0x20: cvt_s_l({{ - Fd.uw = fpConvert(Fs.ud, LONG_TO_SINGLE); - }}); - - 0x21: cvt_d_l({{ - Fd.ud = fpConvert(Fs.ud, LONG_TO_DOUBLE); - }}); - - 0x26: cvt_ps_l({{ - Fd.ud = fpConvert(Fs.ud, LONG_TO_PS); - }}); + format FloatConvertOp { + 0x20: cvt_s_l({{ val = Fs.ud; }}, ToSingle); + 0x21: cvt_d_l({{ val = Fs.ud; }}, ToDouble); + 0x26: FailUnimpl::cvt_ps_l(); } } @@ -938,30 +679,25 @@ decode OPCODE_HI default Unknown::unknown() { Fd1.sf = Fs1.sf + Ft2.sf; Fd2.sf = Fs2.sf + Ft2.sf; }}); - 0x1: sub_ps({{ Fd1.sf = Fs1.sf - Ft2.sf; Fd2.sf = Fs2.sf - Ft2.sf; }}); - 0x2: mul_ps({{ Fd1.sf = Fs1.sf * Ft2.sf; Fd2.sf = Fs2.sf * Ft2.sf; }}); - 0x5: abs_ps({{ Fd1.sf = fabs(Fs1.sf); Fd2.sf = fabs(Fs2.sf); }}); - 0x6: mov_ps({{ Fd1.sf = Fs1.sf; Fd2.sf = Fs2.sf; }}); - 0x7: neg_ps({{ - Fd1.sf = -1 * Fs1.sf; - Fd2.sf = -1 * Fs2.sf; + Fd1.sf = -(Fs1.sf); + Fd2.sf = -(Fs2.sf); }}); } } @@ -970,236 +706,112 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: decode MOVCF { format Float64Op { 0x0: movf_ps({{ - if (getFPConditionCode(FCSR, CC) == 0) - Fd1 = Fs1; - if (getFPConditionCode(FCSR, CC+1) == 0) - Fd2 = Fs2; + Fd1 = (getCondCode(FCSR, CC) == 0) ? + Fs1 : Fd1; + Fd2 = (getCondCode(FCSR, CC+1) == 0) ? + Fs2 : Fd2; }}); - 0x1: movt_ps({{ - if (getFPConditionCode(FCSR, CC) == 1) - Fd1 = Fs1; - if (getFPConditionCode(FCSR, CC+1) == 1) - Fd2 = Fs2; + Fd2 = (getCondCode(FCSR, CC) == 1) ? + Fs1 : Fd1; + Fd2 = (getCondCode(FCSR, CC+1) == 1) ? + Fs2 : Fd2; }}); } } format Float64Op { 0x2: movz_ps({{ - if (getFPConditionCode(FCSR, CC) == 0) - Fd1 = Fs1; - if (getFPConditionCode(FCSR, CC) == 0) - Fd2 = Fs2; + Fd1 = (getCondCode(FCSR, CC) == 0) ? + Fs1 : Fd1; + Fd2 = (getCondCode(FCSR, CC) == 0) ? + Fs2 : Fd2; }}); - 0x3: movn_ps({{ - if (getFPConditionCode(FCSR, CC) == 1) - Fd1 = Fs1; - if (getFPConditionCode(FCSR, CC) == 1) - Fd2 = Fs2; + Fd1 = (getCondCode(FCSR, CC) == 1) ? + Fs1 : Fd1; + Fd2 = (getCondCode(FCSR, CC) == 1) ? + Fs2 : Fd2; }}); } } 0x4: decode FUNCTION_LO { - 0x0: Float64Op::cvt_s_pu({{ - Fd.uw = fpConvert(Fs2.uw, PU_TO_SINGLE); - }}); + 0x0: FloatOp::cvt_s_pu({{ Fd.sf = Fs2.sf; }}); } 0x5: decode FUNCTION_LO { - format Float64Op { - 0x0: cvt_s_pl({{ - Fd.uw = fpConvert(Fs1.uw, PL_TO_SINGLE); - }}); + 0x0: FloatOp::cvt_s_pl({{ Fd.sf = Fs1.sf; }}); - 0x4: pll({{ Fd.ud = (uint64_t) Fs1.uw << 32 | Ft1.uw; }}); - 0x5: plu({{ Fd.ud = (uint64_t) Fs1.uw << 32 | Ft2.uw; }}); - 0x6: pul({{ Fd.ud = (uint64_t) Fs2.uw << 32 | Ft1.uw; }}); - 0x7: puu({{ Fd.ud = (uint64_t) Fs2.uw << 32 | Ft2.uw; }}); + format Float64Op { + 0x4: pll({{ Fd.ud = (uint64_t) Fs1.uw << 32 | + Ft1.uw; + }}); + 0x5: plu({{ Fd.ud = (uint64_t) Fs1.uw << 32 | + Ft2.uw; + }}); + 0x6: pul({{ Fd.ud = (uint64_t) Fs2.uw << 32 | + Ft1.uw; + }}); + 0x7: puu({{ Fd.ud = (uint64_t) Fs2.uw << 32 | + Ft2.uw; + }}); } } 0x6: decode FUNCTION_LO { format FloatPSCompareOp { - 0x0: c_f_ps({{ cond1 = 0; cond2 = 0; }}); - - 0x1: c_un_ps({{ - if (isnan(Fs1.sf) || isnan(Ft1.sf)) - cond1 = 1; - else - cond1 = 0; - - if (isnan(Fs2.sf) || isnan(Ft2.sf)) - cond2 = 1; - else - cond2 = 0; - - }}); - - 0x2: c_eq_ps({{ - if (isnan(Fs1.sf) || isnan(Ft1.sf)) - cond1 = 0; - else - cond1 = (Fs1.sf == Ft1.sf); - - if (isnan(Fs2.sf) || isnan(Ft2.sf)) - cond2 = 0; - else - cond2 = (Fs2.sf == Ft2.sf); - }}); - - 0x3: c_ueq_ps({{ - if (isnan(Fs1.sf) || isnan(Ft1.sf)) - cond1 = 1; - else - cond1 = (Fs1.sf == Ft1.sf); - - if (isnan(Fs2.sf) || isnan(Ft2.sf)) - cond2 = 1; - else - cond2 = (Fs2.sf == Ft2.sf); - }}); - - 0x4: c_olt_ps({{ - if (isnan(Fs1.sf) || isnan(Ft1.sf)) - cond1 = 0; - else - cond1 = (Fs1.sf < Ft1.sf); - - if (isnan(Fs2.sf) || isnan(Ft2.sf)) - cond2 = 0; - else - cond2 = (Fs2.sf < Ft2.sf); - }}); - - 0x5: c_ult_ps({{ - if (isnan(Fs1.sf) || isnan(Ft1.sf)) - cond1 = 1; - else - cond1 = (Fs.sf < Ft.sf); - - if (isnan(Fs2.sf) || isnan(Ft2.sf)) - cond2 = 1; - else - cond2 = (Fs2.sf < Ft2.sf); - }}); - - 0x6: c_ole_ps({{ - if (isnan(Fs.sf) || isnan(Ft.sf)) - cond1 = 0; - else - cond1 = (Fs.sf <= Ft.sf); - - if (isnan(Fs2.sf) || isnan(Ft2.sf)) - cond2 = 0; - else - cond2 = (Fs2.sf <= Ft2.sf); - }}); - - 0x7: c_ule_ps({{ - if (isnan(Fs1.sf) || isnan(Ft1.sf)) - cond1 = 1; - else - cond1 = (Fs1.sf <= Ft1.sf); - - if (isnan(Fs2.sf) || isnan(Ft2.sf)) - cond2 = 1; - else - cond2 = (Fs2.sf <= Ft2.sf); - }}); + 0x0: c_f_ps({{ cond1 = 0; }}, {{ cond2 = 0; }}, + UnorderedFalse); + 0x1: c_un_ps({{ cond1 = 0; }}, {{ cond2 = 0; }}, + UnorderedTrue); + 0x2: c_eq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }}, + {{ cond2 = (Fs2.sf == Ft2.sf); }}, + UnorderedFalse); + 0x3: c_ueq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }}, + {{ cond2 = (Fs2.sf == Ft2.sf); }}, + UnorderedTrue); + 0x4: c_olt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }}, + {{ cond2 = (Fs2.sf < Ft2.sf); }}, + UnorderedFalse); + 0x5: c_ult_ps({{ cond1 = (Fs.sf < Ft.sf); }}, + {{ cond2 = (Fs2.sf < Ft2.sf); }}, + UnorderedTrue); + 0x6: c_ole_ps({{ cond1 = (Fs.sf <= Ft.sf); }}, + {{ cond2 = (Fs2.sf <= Ft2.sf); }}, + UnorderedFalse); + 0x7: c_ule_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }}, + {{ cond2 = (Fs2.sf <= Ft2.sf); }}, + UnorderedTrue); } } 0x7: decode FUNCTION_LO { - format FloatPSCompareWithXcptOp { - 0x0: c_sf_ps({{ cond1 = 0; cond2 = 0; }}); - - 0x1: c_ngle_ps({{ - if (isnan(Fs1.sf) || isnan(Ft1.sf)) - cond1 = 1; - else - cond1 = 0; - - if (isnan(Fs2.sf) || isnan(Ft2.sf)) - cond2 = 1; - else - cond2 = 0; - }}); - - 0x2: c_seq_ps({{ - if (isnan(Fs1.sf) || isnan(Ft1.sf)) - cond1 = 0; - else - cond1 = (Fs1.sf == Ft1.sf); - - if (isnan(Fs2.sf) || isnan(Ft2.sf)) - cond2 = 0; - else - cond2 = (Fs2.sf == Ft2.sf); - }}); - - 0x3: c_ngl_ps({{ - if (isnan(Fs1.sf) || isnan(Ft1.sf)) - cond1 = 1; - else - cond1 = (Fs1.sf == Ft1.sf); - - if (isnan(Fs2.sf) || isnan(Ft2.sf)) - cond2 = 1; - else - cond2 = (Fs2.sf == Ft2.sf); - }}); - - 0x4: c_lt_ps({{ - if (isnan(Fs1.sf) || isnan(Ft1.sf)) - cond1 = 0; - else - cond1 = (Fs1.sf < Ft1.sf); - - if (isnan(Fs2.sf) || isnan(Ft2.sf)) - cond2 = 0; - else - cond2 = (Fs2.sf < Ft2.sf); - }}); - - 0x5: c_nge_ps({{ - if (isnan(Fs1.sf) || isnan(Ft1.sf)) - cond1 = 1; - else - cond1 = (Fs1.sf < Ft1.sf); - - if (isnan(Fs2.sf) || isnan(Ft2.sf)) - cond2 = 1; - else - cond2 = (Fs2.sf < Ft2.sf); - }}); - - 0x6: c_le_ps({{ - if (isnan(Fs1.sf) || isnan(Ft1.sf)) - cond1 = 0; - else - cond1 = (Fs1.sf <= Ft1.sf); - - if (isnan(Fs2.sf) || isnan(Ft2.sf)) - cond2 = 0; - else - cond2 = (Fs2.sf <= Ft2.sf); - }}); - - 0x7: c_ngt_ps({{ - if (isnan(Fs1.sf) || isnan(Ft1.sf)) - cond1 = 1; - else - cond1 = (Fs1.sf <= Ft1.sf); - - if (isnan(Fs2.sf) || isnan(Ft2.sf)) - cond2 = 1; - else - cond2 = (Fs2.sf <= Ft2.sf); - }}); + format FloatPSCompareOp { + 0x0: c_sf_ps({{ cond1 = 0; }}, {{ cond2 = 0; }}, + UnorderedFalse, QnanException); + 0x1: c_ngle_ps({{ cond1 = 0; }}, + {{ cond2 = 0; }}, + UnorderedTrue, QnanException); + 0x2: c_seq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }}, + {{ cond2 = (Fs2.sf == Ft2.sf); }}, + UnorderedFalse, QnanException); + 0x3: c_ngl_ps({{ cond1 = (Fs1.sf == Ft1.sf); }}, + {{ cond2 = (Fs2.sf == Ft2.sf); }}, + UnorderedTrue, QnanException); + 0x4: c_lt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }}, + {{ cond2 = (Fs2.sf < Ft2.sf); }}, + UnorderedFalse, QnanException); + 0x5: c_nge_ps({{ cond1 = (Fs1.sf < Ft1.sf); }}, + {{ cond2 = (Fs2.sf < Ft2.sf); }}, + UnorderedTrue, QnanException); + 0x6: c_le_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }}, + {{ cond2 = (Fs2.sf <= Ft2.sf); }}, + UnorderedFalse, QnanException); + 0x7: c_ngt_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }}, + {{ cond2 = (Fs2.sf <= Ft2.sf); }}, + UnorderedTrue, QnanException); } } } @@ -1209,9 +821,9 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-19 MIPS32 COP2 Encoding of rs Field 0x2: decode RS_MSB { - 0x0: decode RS_HI { - 0x0: decode RS_LO { - format WarnUnimpl { + format FailUnimpl { + 0x0: decode RS_HI { + 0x0: decode RS_LO { 0x0: mfc2(); 0x2: cfc2(); 0x3: mfhc2(); @@ -1219,18 +831,14 @@ decode OPCODE_HI default Unknown::unknown() { 0x6: ctc2(); 0x7: mftc2(); } - } - 0x1: decode ND { - 0x0: decode TF { - format WarnUnimpl { + 0x1: decode ND { + 0x0: decode TF { 0x0: bc2f(); 0x1: bc2t(); } - } - 0x1: decode TF { - format WarnUnimpl { + 0x1: decode TF { 0x0: bc2fl(); 0x1: bc2tl(); } @@ -1244,441 +852,240 @@ decode OPCODE_HI default Unknown::unknown() { //operations are enabled." 0x3: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { - format LoadFloatMemory { - 0x0: lwxc1({{ Ft.uw = Mem.uw;}}, {{ EA = Rs + Rt; }}); - 0x1: ldxc1({{ Ft.ud = Mem.ud;}}, {{ EA = Rs + Rt; }}); - 0x5: luxc1({{ Ft.uw = Mem.ud;}}, {{ EA = Rs + Rt; }}); + format LoadIndexedMemory { + 0x0: lwxc1({{ Ft.uw = Mem.uw;}}); + 0x1: ldxc1({{ Ft.ud = Mem.ud;}}); + 0x5: luxc1({{ Ft.uw = Mem.ud;}}); } } 0x1: decode FUNCTION_LO { - format StoreFloatMemory { - 0x0: swxc1({{ Mem.uw = Ft.uw;}}, {{ EA = Rs + Rt; }}); - 0x1: sdxc1({{ Mem.ud = Ft.ud;}}, {{ EA = Rs + Rt; }}); - 0x5: suxc1({{ Mem.ud = Ft.ud;}}, {{ EA = Rs + Rt; }}); + format StoreIndexedMemory { + 0x0: swxc1({{ Mem.uw = Ft.uw;}}); + 0x1: sdxc1({{ Mem.ud = Ft.ud;}}); + 0x5: suxc1({{ Mem.ud = Ft.ud;}}); } - 0x7: WarnUnimpl::prefx(); + 0x7: Prefetch::prefx({{ EA = Rs + Rt; }}); } - format FloatOp { - 0x3: WarnUnimpl::alnv_ps(); + 0x3: decode FUNCTION_LO { + 0x6: Float64Op::alnv_ps({{ if (Rs<2:0> == 0) { + Fd.ud = Fs.ud; + } else if (Rs<2:0> == 4) { + #if BYTE_ORDER == BIG_ENDIAN + Fd.ud = Fs.ud<31:0> << 32 | + Ft.ud<63:32>; + #elif BYTE_ORDER == LITTLE_ENDIAN + Fd.ud = Ft.ud<31:0> << 32 | + Fs.ud<63:32>; + #endif + } else { + Fd.ud = Fd.ud; + } + }}); + } - format BasicOp { - 0x4: decode FUNCTION_LO { - 0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }}); - 0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }}); - 0x6: madd_ps({{ - Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df; - Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df; - }}); - } + format FloatAccOp { + 0x4: decode FUNCTION_LO { + 0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }}); + 0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }}); + 0x6: madd_ps({{ + Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df; + Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df; + }}); + } - 0x5: decode FUNCTION_LO { - 0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }}); - 0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }}); - 0x6: msub_ps({{ - Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df; - Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df; - }}); - } + 0x5: decode FUNCTION_LO { + 0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }}); + 0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }}); + 0x6: msub_ps({{ + Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df; + Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df; + }}); + } - 0x6: decode FUNCTION_LO { - 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }}); - 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }}); - 0x6: nmadd_ps({{ - Fd1.sf = -1 * ((Fs1.df * Ft1.df) + Fr1.df); - Fd2.sf = -1 * ((Fs2.df * Ft2.df) + Fr2.df); - }}); - } + 0x6: decode FUNCTION_LO { + 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }}); + 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }}); + 0x6: nmadd_ps({{ + Fd1.sf = -((Fs1.df * Ft1.df) + Fr1.df); + Fd2.sf = -((Fs2.df * Ft2.df) + Fr2.df); + }}); + } - 0x7: decode FUNCTION_LO { - 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }}); - 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }}); - 0x6: nmsub_ps({{ - Fd1.sf = -1 * ((Fs1.df * Ft1.df) - Fr1.df); - Fd2.sf = -1 * ((Fs2.df * Ft2.df) - Fr2.df); - }}); - } + 0x7: decode FUNCTION_LO { + 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }}); + 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }}); + 0x6: nmsub_ps({{ + Fd1.sf = -((Fs1.df * Ft1.df) - Fr1.df); + Fd2.sf = -((Fs2.df * Ft2.df) - Fr2.df); + }}); } + } } - format BranchLikely { - 0x4: beql({{ cond = (Rs.sw == 0); }}); - 0x5: bnel({{ cond = (Rs.sw != 0); }}); - 0x6: blezl({{ cond = (Rs.sw <= 0); }}); - 0x7: bgtzl({{ cond = (Rs.sw > 0); }}); + format Branch { + 0x4: beql({{ cond = (Rs.sw == Rt.sw); }}, Likely); + 0x5: bnel({{ cond = (Rs.sw != Rt.sw); }}, Likely); + 0x6: blezl({{ cond = (Rs.sw <= 0); }}, Likely); + 0x7: bgtzl({{ cond = (Rs.sw > 0); }}, Likely); } } - 0x3: decode OPCODE_LO default FailUnimpl::reserved() { - + 0x3: decode OPCODE_LO { //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field 0x4: decode FUNCTION_HI { - 0x0: decode FUNCTION_LO { - format IntOp { - 0x0: madd({{ - int64_t temp1 = (int64_t) HI << 32 | LO; - temp1 = temp1 + (Rs.sw * Rt.sw); - HI = temp1<63:32>; - LO = temp1<31:0>; - }}); - - 0x1: maddu({{ - int64_t temp1 = (int64_t) HI << 32 | LO; - temp1 = temp1 + (Rs.uw * Rt.uw); - HI = temp1<63:32>; - LO = temp1<31:0>; - }}); - - 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); - - 0x4: msub({{ - int64_t temp1 = (int64_t) HI << 32 | LO; - temp1 = temp1 - (Rs.sw * Rt.sw); - HI = temp1<63:32>; - LO = temp1<31:0>; - }}); + 0x2: IntOp::mul({{ int64_t temp1 = Rs.sd * Rt.sd; + Rd.sw = temp1<31:0> + }}); - 0x5: msubu({{ - int64_t temp1 = (int64_t) HI << 32 | LO; - temp1 = temp1 - (Rs.uw * Rt.uw); - HI = temp1<63:32>; - LO = temp1<31:0>; - }}); + format HiLoOp { + 0x0: madd({{ val = ((int64_t) HI << 32 | LO) + + (Rs.sd * Rt.sd); + }}); + 0x1: maddu({{ val = ((uint64_t) HI << 32 | LO) + + (Rs.ud * Rt.ud); + }}); + 0x4: msub({{ val = ((int64_t) HI << 32 | LO) - + (Rs.sd * Rt.sd); + }}); + 0x5: msubu({{ val = ((uint64_t) HI << 32 | LO) - + (Rs.ud * Rt.ud); + }}); } } 0x4: decode FUNCTION_LO { format BasicOp { - 0x0: clz({{ - int cnt = 0; - uint32_t mask = 0x80000000; - for (int i=0; i < 32; i++) { - if( (Rs & mask) == 0) { - cnt++; - } else { - break; - } - } - Rd.uw = cnt; - }}); - - 0x1: clo({{ - int cnt = 0; - uint32_t mask = 0x80000000; - for (int i=0; i < 32; i++) { - if( (Rs & mask) != 0) { - cnt++; - } else { - break; - } - } - Rd.uw = cnt; - }}); + 0x0: clz({{ int cnt = 32; + for (int idx = 31; idx >= 0; idx--) { + if( Rs<idx:idx> == 1) { + cnt = 31 - idx; + break; + } + } + Rd.uw = cnt; + }}); + 0x1: clo({{ int cnt = 32; + for (int idx = 31; idx >= 0; idx--) { + if( Rs<idx:idx> == 0) { + cnt = 31 - idx; + break; + } + } + Rd.uw = cnt; + }}); } } 0x7: decode FUNCTION_LO { - 0x7: WarnUnimpl::sdbbp(); + 0x7: FailUnimpl::sdbbp(); } } - //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture + //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 + //of the Architecture 0x7: decode FUNCTION_HI { - 0x0: decode FUNCTION_LO { - format FailUnimpl { - 0x1: ext(); - 0x4: ins(); + format BasicOp { + 0x1: ext({{ Rt.uw = bits(Rs.uw, MSB+LSB, LSB); }}); + 0x4: ins({{ Rt.uw = bits(Rt.uw, 31, MSB+1) << (MSB+1) | + bits(Rs.uw, MSB-LSB, 0) << LSB | + bits(Rt.uw, LSB-1, 0); + }}); } } 0x1: decode FUNCTION_LO { - format FailUnimpl { + format MipsMT { 0x0: fork(); 0x1: yield(); } } - //Table A-10 MIPS32 BSHFL Encoding of sa Field 0x4: decode SA { - - 0x02: FailUnimpl::wsbh(); - format BasicOp { + 0x02: wsbh({{ Rd.uw = Rt.uw<23:16> << 24 | + Rt.uw<31:24> << 16 | + Rt.uw<7:0> << 8 | + Rt.uw<15:8>; + }}); 0x10: seb({{ Rd.sw = Rt.sw<7:0>}}); 0x18: seh({{ Rd.sw = Rt.sw<15:0>}}); } } 0x6: decode FUNCTION_LO { - 0x7: FailUnimpl::rdhwr();//{{ /*Rt = xc->hwRegs[RD];*/ }} + 0x7: FailUnimpl::rdhwr(); } } } - 0x4: decode OPCODE_LO default FailUnimpl::reserved() { + 0x4: decode OPCODE_LO { format LoadMemory { 0x0: lb({{ Rt.sw = Mem.sb; }}); 0x1: lh({{ Rt.sw = Mem.sh; }}); - - 0x2: lwl({{ - uint32_t mem_word = Mem.uw; - uint32_t unalign_addr = Rs + disp; - uint32_t offset = unalign_addr & 0x00000003; -#if BYTE_ORDER == BIG_ENDIAN - switch(offset) - { - case 0: - Rt = mem_word; - break; - - case 1: - Rt &= 0x000F; - Rt |= (mem_word << 4); - break; - - case 2: - Rt &= 0x00FF; - Rt |= (mem_word << 8); - break; - - case 3: - Rt &= 0x0FFF; - Rt |= (mem_word << 12); - break; - - default: - panic("lwl: bad offset"); - } -#elif BYTE_ORDER == LITTLE_ENDIAN - switch(offset) - { - case 0: - Rt &= 0x0FFF; - Rt |= (mem_word << 12); - break; - - case 1: - Rt &= 0x00FF; - Rt |= (mem_word << 8); - break; - - case 2: - Rt &= 0x000F; - Rt |= (mem_word << 4); - break; - - case 3: - Rt = mem_word; - break; - - default: - panic("lwl: bad offset"); - } -#endif - }}, {{ EA = (Rs + disp) & ~3; }}); - 0x3: lw({{ Rt.sw = Mem.sw; }}); 0x4: lbu({{ Rt.uw = Mem.ub; }}); 0x5: lhu({{ Rt.uw = Mem.uh; }}); - 0x6: lwr({{ - uint32_t mem_word = Mem.uw; - uint32_t unalign_addr = Rs + disp; - uint32_t offset = unalign_addr & 0x00000003; - -#if BYTE_ORDER == BIG_ENDIAN - switch(offset) - { - case 0: Rt &= 0xFFF0; Rt |= (mem_word >> 12); break; - case 1: Rt &= 0xFF00; Rt |= (mem_word >> 8); break; - case 2: Rt &= 0xF000; Rt |= (mem_word >> 4); break; - case 3: Rt = mem_word; break; - default: panic("lwr: bad offset"); - } -#elif BYTE_ORDER == LITTLE_ENDIAN - switch(offset) - { - case 0: Rt = mem_word; break; - case 1: Rt &= 0xF000; Rt |= (mem_word >> 4); break; - case 2: Rt &= 0xFF00; Rt |= (mem_word >> 8); break; - case 3: Rt &= 0xFFF0; Rt |= (mem_word >> 12); break; - default: panic("lwr: bad offset"); - } -#endif - }}, - {{ EA = (Rs + disp) & ~3; }}); + } + + format LoadUnalignedMemory { + 0x2: lwl({{ uint32_t mem_shift = 24 - (8 * byte_offset); + Rt.uw = mem_word << mem_shift | + Rt.uw & mask(mem_shift); + }}); + 0x6: lwr({{ uint32_t mem_shift = 8 * byte_offset; + Rt.uw = Rt.uw & (mask(mem_shift) << (32 - mem_shift)) | + mem_word >> mem_shift; + }}); } } - 0x5: decode OPCODE_LO default FailUnimpl::reserved() { + 0x5: decode OPCODE_LO { format StoreMemory { 0x0: sb({{ Mem.ub = Rt<7:0>; }}); 0x1: sh({{ Mem.uh = Rt<15:0>; }}); - 0x2: swl({{ - uint32_t mem_word = 0; - uint32_t aligned_addr = (Rs + disp) & ~3; - uint32_t unalign_addr = Rs + disp; - uint32_t offset = unalign_addr & 0x00000003; - - DPRINTF(IEW,"Execute: aligned=0x%x unaligned=0x%x\n offset=0x%x", - aligned_addr,unalign_addr,offset); - - fault = xc->read(aligned_addr, (uint32_t&)mem_word, memAccessFlags); - -#if BYTE_ORDER == BIG_ENDIAN - switch(offset) - { - case 0: - Mem = Rt; - break; - - case 1: - mem_word &= 0xF000; - mem_word |= (Rt >> 4); - Mem = mem_word; - break; - - case 2: - mem_word &= 0xFF00; - mem_word |= (Rt >> 8); - Mem = mem_word; - break; - - case 3: - mem_word &= 0xFFF0; - mem_word |= (Rt >> 12); - Mem = mem_word; - break; - - default: - panic("swl: bad offset"); - } -#elif BYTE_ORDER == LITTLE_ENDIAN - switch(offset) - { - case 0: - mem_word &= 0xFFF0; - mem_word |= (Rt >> 12); - Mem = mem_word; - break; - - case 1: - mem_word &= 0xFF00; - mem_word |= (Rt >> 8); - Mem = mem_word; - break; - - case 2: - mem_word &= 0xF000; - mem_word |= (Rt >> 4); - Mem = mem_word; - break; - - case 3: - Mem = Rt; - break; - - default: - panic("swl: bad offset"); - } -#endif - }},{{ EA = (Rs + disp) & ~3; }},mem_flags = NO_ALIGN_FAULT); - 0x3: sw({{ Mem.uw = Rt<31:0>; }}); - - 0x6: swr({{ - uint32_t mem_word = 0; - uint32_t aligned_addr = (Rs + disp) & ~3; - uint32_t unalign_addr = Rs + disp; - uint32_t offset = unalign_addr & 0x00000003; - - fault = xc->read(aligned_addr, (uint32_t&)mem_word, memAccessFlags); - -#if BYTE_ORDER == BIG_ENDIAN - switch(offset) - { - case 0: - mem_word &= 0x0FFF; - mem_word |= (Rt << 12); - Mem = mem_word; - break; - - case 1: - mem_word &= 0x00FF; - mem_word |= (Rt << 8); - Mem = mem_word; - break; - - case 2: - mem_word &= 0x000F; - mem_word |= (Rt << 4); - Mem = mem_word; - break; - - case 3: - Mem = Rt; - break; - - default: - panic("swr: bad offset"); - } -#elif BYTE_ORDER == LITTLE_ENDIAN - switch(offset) - { - case 0: - Mem = Rt; - break; - - case 1: - mem_word &= 0x000F; - mem_word |= (Rt << 4); - Mem = mem_word; - break; - - case 2: - mem_word &= 0x00FF; - mem_word |= (Rt << 8); - Mem = mem_word; - break; - - case 3: - mem_word &= 0x0FFF; - mem_word |= (Rt << 12); - Mem = mem_word; - break; - - default: - panic("swr: bad offset"); - } -#endif - }},{{ EA = (Rs + disp) & ~3;}},mem_flags = NO_ALIGN_FAULT); } - format WarnUnimpl { - 0x7: cache(); + format StoreUnalignedMemory { + 0x2: swl({{ uint32_t reg_shift = 24 - (8 * byte_offset); + uint32_t mem_shift = 32 - reg_shift; + mem_word = mem_word & (mask(reg_shift) << mem_shift) | + Rt.uw >> reg_shift; + }}); + 0x6: swr({{ uint32_t reg_shift = 8 * byte_offset; + mem_word = Rt.uw << reg_shift | + mem_word & (mask(reg_shift)); + }}); } + 0x7: FailUnimpl::cache(); } - 0x6: decode OPCODE_LO default FailUnimpl::reserved() { - 0x0: LoadMemory::ll({{Rt.uw = Mem.uw}},mem_flags=LOCKED); - - format LoadFloatMemory { - 0x1: lwc1({{ Ft.uw = Mem.uw; }}); + 0x6: decode OPCODE_LO { + format LoadMemory { + 0x0: ll({{ Rt.uw = Mem.uw; }}, mem_flags=LOCKED); + 0x1: lwc1({{ Ft.uw = Mem.uw; }}); 0x5: ldc1({{ Ft.ud = Mem.ud; }}); } + + 0x3: Prefetch::pref(); } - 0x7: decode OPCODE_LO default FailUnimpl::reserved() { - 0x0: StoreMemory::sc({{ Mem.uw = Rt.uw; Rt.uw = 1; }}); + 0x7: decode OPCODE_LO { + 0x0: StoreCond::sc({{ Mem.uw = Rt.uw;}}, + {{ uint64_t tmp = write_result; + Rt.uw = (tmp == 0 || tmp == 1) ? tmp : Rt.uw; + }}, mem_flags=LOCKED); - format StoreFloatMemory { + format StoreMemory { 0x1: swc1({{ Mem.uw = Ft.uw; }}); 0x5: sdc1({{ Mem.ud = Ft.ud; }}); } diff --git a/src/arch/mips/isa/formats/basic.isa b/src/arch/mips/isa/formats/basic.isa index c02af7ddc..35ce09205 100644 --- a/src/arch/mips/isa/formats/basic.isa +++ b/src/arch/mips/isa/formats/basic.isa @@ -1,5 +1,33 @@ // -*- mode:c++ -*- +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell + // Declarations for execute() methods. def template BasicExecDeclare {{ Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; @@ -12,11 +40,11 @@ def template BasicDeclare {{ */ class %(class_name)s : public %(base_class)s { - public: + public: /// Constructor. %(class_name)s(MachInst machInst); %(BasicExecDeclare)s - }; + }; }}; // Basic instruction class constructor template. @@ -27,6 +55,7 @@ def template BasicConstructor {{ } }}; + // Basic instruction class execute method template. def template BasicExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const diff --git a/src/arch/mips/isa/formats/branch.isa b/src/arch/mips/isa/formats/branch.isa index 8cfa37a20..827e3ccf0 100644 --- a/src/arch/mips/isa/formats/branch.isa +++ b/src/arch/mips/isa/formats/branch.isa @@ -1,5 +1,33 @@ // -*- mode:c++ -*- +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell + //////////////////////////////////////////////////////////////////// // // Control transfer instructions @@ -68,29 +96,6 @@ output header {{ }; /** - * Base class for branch likely branches (PC-relative control transfers), - */ - class BranchLikely : public PCDependentDisassembly - { - protected: - /// target address (signed) Displacement . - int32_t disp; - - /// Constructor. - BranchLikely(const char *mnem, MachInst _machInst, OpClass __opClass) - : PCDependentDisassembly(mnem, _machInst, __opClass), - disp(OFFSET << 2) - { - - } - - Addr branchTarget(Addr branchPC) const; - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; - - /** * Base class for jumps (register-indirect control transfers). In * the Mips ISA, these are always unconditional. */ @@ -111,7 +116,7 @@ output header {{ { } - Addr branchTarget(ExecContext *xc) const; + Addr branchTarget(ThreadContext *tc) const; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; @@ -126,16 +131,10 @@ output decoder {{ } Addr - BranchLikely::branchTarget(Addr branchPC) const - { - return branchPC + 4 + disp; - } - - Addr - Jump::branchTarget(ExecContext *xc) const + Jump::branchTarget(ThreadContext *tc) const { - Addr NPC = xc->readPC() + 4; - uint64_t Rb = xc->readIntReg(_srcRegIdx[0]); + Addr NPC = tc->readPC() + 4; + uint64_t Rb = tc->readIntReg(_srcRegIdx[0]); return (Rb & ~3) | (NPC & 1); } @@ -171,49 +170,12 @@ output decoder {{ // unconditional branches) if (_numSrcRegs == 1) { printReg(ss, _srcRegIdx[0]); - ss << ","; + ss << ", "; } else if(_numSrcRegs == 2) { printReg(ss, _srcRegIdx[0]); - ss << ","; + ss << ", "; printReg(ss, _srcRegIdx[1]); - ss << ","; - } - - Addr target = pc + 4 + disp; - - std::string str; - if (symtab && symtab->findSymbol(target, str)) - ss << str; - else - ccprintf(ss, "0x%x", target); - - string inst_name = mnemonic; - - if (inst_name.substr(inst_name.length()-2,inst_name.length()) == "al"){ - ccprintf(ss, " (r31=0x%x)",pc+8); - } - - return ss.str(); - } - - std::string - BranchLikely::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - // There's only one register arg (RA), but it could be - // either a source (the condition for conditional - // branches) or a destination (the link reg for - // unconditional branches) - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - ss << ","; - } - else if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); - ss << ","; + ss << ", "; } Addr target = pc + 4 + disp; @@ -247,72 +209,64 @@ output decoder {{ printReg(ss, _srcRegIdx[0]); } else if(_numSrcRegs == 2) { printReg(ss, _srcRegIdx[0]); - ss << ","; + ss << ", "; printReg(ss, _srcRegIdx[1]); - } else { - panic(">= 3 Source Registers!!!"); } return ss.str(); } }}; -def format Branch(code,*flags) {{ - #Add Link Code if Link instruction - strlen = len(name) - if name[strlen-2:] == 'al': - code += 'R31 = NNPC;\n' +def format Branch(code,*opt_flags) {{ + not_taken_code = ' NNPC = NNPC;\n' + not_taken_code += '} \n' + + #Build Instruction Flags + #Use Link & Likely Flags to Add Link/Condition Code + inst_flags = ('IsDirectControl', ) + for x in opt_flags: + if x == 'Link': + code += 'R31 = NNPC;\n' + elif x == 'Likely': + not_taken_code = ' NPC = NNPC;\n' + not_taken_code += ' NNPC = NNPC + 4;\n' + not_taken_code += '} \n' + inst_flags = ('IsCondDelaySlot', ) + else: + inst_flags += (x, ) + + if 'cond == 1' in code: + inst_flags += ('IsCondControl', ) + else: + inst_flags += ('IsUncondControl', ) #Condition code code = 'bool cond;\n' + code code += 'if (cond) {\n' code += ' NNPC = NPC + disp;\n' code += '} else {\n' - code += ' NNPC = NNPC;\n' - code += '} \n' - - iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), - ('IsDirectControl', 'IsCondControl')) - - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; - - -def format BranchLikely(code,*flags) {{ - #Add Link Code if Link instruction - strlen = len(name) - if name[strlen-3:] == 'all': - code += 'R31 = NNPC;\n' - - #Condition code - code = 'bool cond;\n' + code - code += 'if (cond) {' - code += 'NNPC = NPC + disp;\n' - code += '} \n' - - - iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), - ('IsDirectControl', 'IsCondControl','IsCondDelaySlot')) + code += not_taken_code + iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), inst_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) exec_output = BasicExecute.subst(iop) }}; -def format Jump(code,*flags) {{ - #Add Link Code if Link instruction - strlen = len(name) - if strlen > 1 and name[1:] == 'al': +def format Jump(code, *opt_flags) {{ + #Build Instruction Flags + #Use Link Flag to Add Link Code + inst_flags = ('IsIndirectControl', 'IsUncondControl') + for x in opt_flags: + if x == 'Link': code = 'R31 = NNPC;\n' + code + elif x == 'ClearHazards': + code += '/* Code Needed to Clear Execute & Inst Hazards */\n' + else: + inst_flags += (x, ) - - iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),\ - ('IsIndirectControl', 'IsUncondControl')) - + iop = InstObjParams(name, Name, 'Jump', CodeBlock(code), inst_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/mips/isa/formats/control.isa b/src/arch/mips/isa/formats/control.isa new file mode 100644 index 000000000..509ee7e87 --- /dev/null +++ b/src/arch/mips/isa/formats/control.isa @@ -0,0 +1,156 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell + +//////////////////////////////////////////////////////////////////// +// +// Integer operate instructions +// + +//Outputs to decoder.hh +output header {{ + + class Control : public MipsStaticInst + { + protected: + + /// Constructor + Control(const char *mnem, MachInst _machInst, OpClass __opClass) : + MipsStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + class CP0Control : public Control + { + protected: + + /// Constructor + CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) : + Control(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + class CP1Control : public Control + { + protected: + + /// Constructor + CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) : + Control(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + +}}; + +//Outputs to decoder.cc +output decoder {{ + std::string Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + if (mnemonic == "mfc0" || mnemonic == "mtc0") { + ccprintf(ss, "%-10s %d,%d,%d", mnemonic,RT,RD,SEL); + } else { + + // just print the first dest... if there's a second one, + // it's generally implicit + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + ss << ", "; + + // just print the first two source regs... if there's + // a third one, it's a read-modify-write dest (Rc), + // e.g. for CMOVxx + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + } + + if (_numSrcRegs > 1) { + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + } + + return ss.str(); + } + + std::string CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + ccprintf(ss, "%-10s r%d, r%d, %d", mnemonic, RT, RD, SEL); + return ss.str(); + } + + std::string CP1Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + ccprintf(ss, "%-10s r%d, f%d", mnemonic, RT, FS); + return ss.str(); + } + +}}; + +def format System(code, *flags) {{ + iop = InstObjParams(name, Name, 'Control', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format CP0Control(code, *flags) {{ + iop = InstObjParams(name, Name, 'CP0Control', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format CP1Control(code, *flags) {{ + iop = InstObjParams(name, Name, 'CP1Control', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + + diff --git a/src/arch/mips/isa/formats/formats.isa b/src/arch/mips/isa/formats/formats.isa index 7d493ffae..4c3eec132 100644 --- a/src/arch/mips/isa/formats/formats.isa +++ b/src/arch/mips/isa/formats/formats.isa @@ -1,5 +1,33 @@ // -*- mode:c++ -*- +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell + //Templates from this format are used later //Include the basic format ##include "basic.isa" @@ -10,8 +38,8 @@ //Include utility functions ##include "util.isa" -//Include the cop0 formats -##include "cop0.isa" +//Include the control/cp0/cp1 formats +##include "control.isa" //Include the integer formats ##include "int.isa" @@ -22,6 +50,9 @@ //Include the mem format ##include "mem.isa" +//Include the mem format +##include "mt.isa" + //Include the trap format ##include "trap.isa" diff --git a/src/arch/mips/isa/formats/fp.isa b/src/arch/mips/isa/formats/fp.isa index 9f2c24755..d05b04d0e 100644 --- a/src/arch/mips/isa/formats/fp.isa +++ b/src/arch/mips/isa/formats/fp.isa @@ -1,5 +1,33 @@ // -*- mode:c++ -*- +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell + //////////////////////////////////////////////////////////////////// // // Floating Point operate instructions @@ -18,49 +46,264 @@ output header {{ { } - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + //std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + //needs function to check for fpEnable or not + }; + + class FPCompareOp : public FPOp + { + protected: + FPCompareOp(const char *mnem, MachInst _machInst, OpClass __opClass) : FPOp(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; }}; output decoder {{ - std::string FPOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + std::string FPCompareOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - return "Disassembly of integer instruction\n"; + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + ccprintf(ss,"%d",CC); + + if(_numSrcRegs > 0) { + ss << ", "; + printReg(ss, _srcRegIdx[0]); + } + + if(_numSrcRegs > 1) { + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + + return ss.str(); } }}; +output exec {{ -// Primary format for float operate instructions: -def format FloatOp(code, *flags) {{ - iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) + //If any operand is Nan return the appropriate QNaN + template <class T> + bool + fpNanOperands(FPOp *inst, %(CPU_exec_context)s *xc, const T &src_type, + Trace::InstRecord *traceData) + { + uint64_t mips_nan = 0; + T src_op = 0; + int size = sizeof(src_op) * 8; + + for (int i = 0; i < inst->numSrcRegs(); i++) { + uint64_t src_bits = xc->readFloatRegBits(inst, 0, size); + + if (isNan(&src_bits, size) ) { + if (isSnan(&src_bits, size)) { + switch (size) + { + case 32: mips_nan = MIPS32_QNAN; break; + case 64: mips_nan = MIPS64_QNAN; break; + default: panic("Unsupported Floating Point Size (%d)", size); + } + } else { + mips_nan = src_bits; + } + + xc->setFloatRegBits(inst, 0, mips_nan, size); + if (traceData) { traceData->setData(mips_nan); } + return true; + } + } + return false; + } + + template <class T> + bool + fpInvalidOp(FPOp *inst, %(CPU_exec_context)s *cpu, const T dest_val, + Trace::InstRecord *traceData) + { + uint64_t mips_nan = 0; + T src_op = dest_val; + int size = sizeof(src_op) * 8; + + if (isNan(&src_op, size)) { + switch (size) + { + case 32: mips_nan = MIPS32_QNAN; break; + case 64: mips_nan = MIPS64_QNAN; break; + default: panic("Unsupported Floating Point Size (%d)", size); + } + + //Set value to QNAN + cpu->setFloatRegBits(inst, 0, mips_nan, size); + + //Read FCSR from FloatRegFile + uint32_t fcsr_bits = cpu->tc->readFloatRegBits(FCSR); + + //Write FCSR from FloatRegFile + cpu->tc->setFloatRegBits(FCSR, genInvalidVector(fcsr_bits)); + + if (traceData) { traceData->setData(mips_nan); } + return true; + } + + return false; + } + + void + fpResetCauseBits(%(CPU_exec_context)s *cpu) + { + //Read FCSR from FloatRegFile + uint32_t fcsr = cpu->tc->readFloatRegBits(FCSR); + + fcsr = bits(fcsr, 31, 18) << 18 | bits(fcsr, 11, 0); + + //Write FCSR from FloatRegFile + cpu->tc->setFloatRegBits(FCSR, fcsr); + } }}; -def format FloatCompareOp(code, *flags) {{ - code = 'bool cond;\n' + code - code += 'FCSR = makeCCVector(FCSR, CC,cond);\n' - iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) +def template FloatingPointExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + + %(fp_enable_check)s; + + //When is the right time to reset cause bits? + //start of every instruction or every cycle? + fpResetCauseBits(xc); + + %(op_decl)s; + %(op_rd)s; + + //Check if any FP operand is a NaN value + if (!fpNanOperands((FPOp*)this, xc, Fd, traceData)) { + %(code)s; + + //Change this code for Full-System/Sycall Emulation + //separation + //---- + //Should Full System-Mode throw a fault here? + //---- + //Check for IEEE 754 FP Exceptions + //fault = fpNanOperands((FPOp*)this, xc, Fd, traceData); + if (!fpInvalidOp((FPOp*)this, xc, Fd, traceData) && + fault == NoFault) + { + %(op_wb)s; + } + } + + return fault; + } }}; -def format FloatCompareWithXcptOp(code, *flags) {{ - code = 'bool cond;\n' + code - code += 'FCSR = makeCCVector(FCSR, CC,cond);\n' - iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) +// Primary format for float point operate instructions: +def format FloatOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) + exec_output = FloatingPointExecute.subst(iop) +}}; + +def format FloatCompareOp(cond_code, *flags) {{ + import sys + + code = 'bool cond;\n' + if '.sf' in cond_code or 'SinglePrecision' in flags: + if 'QnanException' in flags: + code += 'if (isQnan(&Fs.sf, 32) || isQnan(&Ft.sf, 32)) {\n' + code += '\tFCSR = genInvalidVector(FCSR);\n' + code += '\treturn NoFault;' + code += '}\n else ' + code += 'if (isNan(&Fs.sf, 32) || isNan(&Ft.sf, 32)) {\n' + elif '.df' in cond_code or 'DoublePrecision' in flags: + if 'QnanException' in flags: + code += 'if (isQnan(&Fs.df, 64) || isQnan(&Ft.df, 64)) {\n' + code += '\tFCSR = genInvalidVector(FCSR);\n' + code += '\treturn NoFault;' + code += '}\n else ' + code += 'if (isNan(&Fs.df, 64) || isNan(&Ft.df, 64)) {\n' + else: + sys.exit('Decoder Failed: Can\'t Determine Operand Type\n') + + if 'UnorderedTrue' in flags: + code += 'cond = 1;\n' + elif 'UnorderedFalse' in flags: + code += 'cond = 0;\n' + else: + sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n') + + code += '} else {\n' + code += cond_code + '}' + code += 'FCSR = genCCVector(FCSR, CC, cond);\n' + + iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code)) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) }}; def format FloatConvertOp(code, *flags) {{ - iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + import sys + + #Determine Source Type + convert = 'fpConvert(' + if '.sf' in code: + code = 'float ' + code + '\n' + convert += 'SINGLE_TO_' + elif '.df' in code: + code = 'double ' + code + '\n' + convert += 'DOUBLE_TO_' + elif '.uw' in code: + code = 'uint32_t ' + code + '\n' + convert += 'WORD_TO_' + elif '.ud' in code: + code = 'uint64_t ' + code + '\n' + convert += 'LONG_TO_' + else: + sys.exit("Error Determining Source Type for Conversion") + + #Determine Destination Type + if 'ToSingle' in flags: + code += 'Fd.uw = ' + convert + 'SINGLE, ' + elif 'ToDouble' in flags: + code += 'Fd.ud = ' + convert + 'DOUBLE, ' + elif 'ToWord' in flags: + code += 'Fd.uw = ' + convert + 'WORD, ' + elif 'ToLong' in flags: + code += 'Fd.ud = ' + convert + 'LONG, ' + else: + sys.exit("Error Determining Destination Type for Conversion") + + #Figure out how to round value + if 'Ceil' in flags: + code += 'ceil(val)); ' + elif 'Floor' in flags: + code += 'floor(val)); ' + elif 'Round' in flags: + code += 'roundFP(val, 0)); ' + elif 'Trunc' in flags: + code += 'truncFP(val));' + else: + code += 'val); ' + + iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code)) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format FloatAccOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -76,34 +319,51 @@ def format Float64Op(code, *flags) {{ exec_output = BasicExecute.subst(iop) }}; -def format Float64ConvertOp(code, *flags) {{ - code = 'bool cond;\n' + code - code += 'FCSR = makeCCVector(FCSR, CC,cond);\n' - iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; +def format FloatPSCompareOp(cond_code1, cond_code2, *flags) {{ + import sys -def format FloatPSCompareOp(code, *flags) {{ - code = 'bool cond1;\nbool cond2;\n' + code - code += 'FCSR = makeCCVector(FCSR, CC+1, cond1);\n' - code += 'FCSR = makeCCVector(FCSR, CC, cond2);\n' - iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; + code = 'bool cond1, cond2;\n' + code += 'bool code_block1, code_block2;\n' + code += 'code_block1 = code_block2 = true;\n' -def format FloatPSCompareWithXcptOp(code, *flags) {{ - code = 'bool cond1;\nbool cond2;\n' + code - code += 'FCSR = makeCCVector(FCSR, CC+1, cond1);\n' - code += 'FCSR = makeCCVector(FCSR, CC, cond2);\n' - iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) + if 'QnanException' in flags: + code += 'if (isQnan(&Fs1.sf, 32) || isQnan(&Ft1.sf, 32)) {\n' + code += '\tFCSR = genInvalidVector(FCSR);\n' + code += 'code_block1 = false;' + code += '}\n' + code += 'if (isQnan(&Fs2.sf, 32) || isQnan(&Ft2.sf, 32)) {\n' + code += '\tFCSR = genInvalidVector(FCSR);\n' + code += 'code_block2 = false;' + code += '}\n' + + code += 'if (code_block1) {' + code += '\tif (isNan(&Fs1.sf, 32) || isNan(&Ft1.sf, 32)) {\n' + if 'UnorderedTrue' in flags: + code += 'cond1 = 1;\n' + elif 'UnorderedFalse' in flags: + code += 'cond1 = 0;\n' + else: + sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n') + code += '} else {\n' + code += cond_code1 + code += 'FCSR = genCCVector(FCSR, CC, cond1);}\n}\n' + + code += 'if (code_block2) {' + code += '\tif (isNan(&Fs2.sf, 32) || isNan(&Ft2.sf, 32)) {\n' + if 'UnorderedTrue' in flags: + code += 'cond2 = 1;\n' + elif 'UnorderedFalse' in flags: + code += 'cond2 = 0;\n' + else: + sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n') + code += '} else {\n' + code += cond_code2 + code += 'FCSR = genCCVector(FCSR, CC, cond2);}\n}' + + iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code)) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) }}; + diff --git a/src/arch/mips/isa/formats/int.isa b/src/arch/mips/isa/formats/int.isa index 7d38b9ff5..7b5affb5c 100644 --- a/src/arch/mips/isa/formats/int.isa +++ b/src/arch/mips/isa/formats/int.isa @@ -1,11 +1,37 @@ // -*- mode:c++ -*- +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell + //////////////////////////////////////////////////////////////////// // // Integer operate instructions // - -//Outputs to decoder.hh output header {{ #include <iostream> using namespace std; @@ -25,6 +51,34 @@ output header {{ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; + + class HiLoOp: public IntOp + { + protected: + + /// Constructor + HiLoOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + IntOp(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + class HiLoMiscOp: public HiLoOp + { + protected: + + /// Constructor + HiLoMiscOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + HiLoOp(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + class IntImmOp : public MipsStaticInst { protected: @@ -52,6 +106,33 @@ output header {{ }}; +// HiLo<Misc> instruction class execute method template. +// Mainly to get instruction trace data to print out +// correctly +def template HiLoExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if(fault == NoFault) + { + %(op_wb)s; + //If there are 2 Destination Registers then + //concatenate the values for the traceData + if(traceData && _numDestRegs == 2) { + uint64_t hilo_final_val = (uint64_t)HI << 32 | LO; + traceData->setData(hilo_final_val); + } + } + return fault; + } +}}; + //Outputs to decoder.cc output decoder {{ std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const @@ -64,7 +145,7 @@ output decoder {{ // it's generally implicit if (_numDestRegs > 0) { printReg(ss, _destRegIdx[0]); - ss << ","; + ss << ", "; } // just print the first two source regs... if there's @@ -75,13 +156,47 @@ output decoder {{ } if (_numSrcRegs > 1) { - ss << ","; + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + + return ss.str(); + } + + std::string HiLoOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + //Destination Registers are implicit for HI/LO ops + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + } + + if (_numSrcRegs > 1) { + ss << ", "; printReg(ss, _srcRegIdx[1]); } return ss.str(); } + std::string HiLoMiscOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + if (_numDestRegs > 0 && _destRegIdx[0] < 32) { + printReg(ss, _destRegIdx[0]); + } else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) { + printReg(ss, _srcRegIdx[0]); + } + + return ss.str(); + } + std::string IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { std::stringstream ss; @@ -92,15 +207,15 @@ output decoder {{ printReg(ss, _destRegIdx[0]); } - ss << ","; + ss << ", "; if (_numSrcRegs > 0) { printReg(ss, _srcRegIdx[0]); - ss << ","; + ss << ", "; } if( mnemonic == "lui") - ccprintf(ss, "%08p ", sextImm); + ccprintf(ss, "0x%x ", sextImm); else ss << (int) sextImm; @@ -109,23 +224,47 @@ output decoder {{ }}; -//Used by decoder.isa def format IntOp(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - - # Figure out if we are creating a IntImmOp or a IntOp - # by looking at the instruction name - iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags) - strlen = len(name) - if name[strlen-1] == 'i' or name[strlen-2:] == 'iu': - iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags) - - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = OperateNopCheckDecode.subst(iop) - exec_output = BasicExecute.subst(iop) + iop = InstObjParams(name, Name, 'IntOp', CodeBlock(code), opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = OperateNopCheckDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format IntImmOp(code, *opt_flags) {{ + iop = InstObjParams(name, Name, 'IntImmOp', CodeBlock(code), opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = OperateNopCheckDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format HiLoOp(code, *opt_flags) {{ + if '.sd' in code: + code = 'int64_t ' + code + elif '.ud' in code: + code = 'uint64_t ' + code + + code += 'HI = val<63:32>;\n' + code += 'LO = val<31:0>;\n' + + iop = InstObjParams(name, Name, 'HiLoOp', CodeBlock(code), opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = OperateNopCheckDecode.subst(iop) + exec_output = HiLoExecute.subst(iop) }}; +def format HiLoMiscOp(code, *opt_flags) {{ + iop = InstObjParams(name, Name, 'HiLoMiscOp', CodeBlock(code), opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = OperateNopCheckDecode.subst(iop) + exec_output = HiLoExecute.subst(iop) +}}; + + + diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa index d5436b308..f52247056 100644 --- a/src/arch/mips/isa/formats/mem.isa +++ b/src/arch/mips/isa/formats/mem.isa @@ -31,7 +31,7 @@ //////////////////////////////////////////////////////////////////// // -// Memory-format instructions: LoadAddress, Load, Store +// Memory-format instructions // output header {{ @@ -90,15 +90,6 @@ output decoder {{ }}; -def format LoadAddress(code) {{ - iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code)) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; - - def template LoadStoreDeclare {{ /** * Static instruction class for "%(mnemonic)s". @@ -426,8 +417,70 @@ def template StoreCompleteAcc {{ } }}; + +def template MiscMemAccExecute {{ + Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + EA = xc->getEA(); + + if (fault == NoFault) { + %(code)s; + } + + return NoFault; + } +}}; + +def template MiscExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + %(memacc_code)s; + } + + return NoFault; + } +}}; + +def template MiscInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("Misc instruction does not support split access method!"); + return NoFault; + } +}}; + + +def template MiscCompleteAcc {{ + Fault %(class_name)s::completeAcc(uint8_t *data, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("Misc instruction does not support split access method!"); + + return NoFault; + } +}}; + // load instructions use Rt as dest, so check for -// Rt == 31 to detect nops +// Rt == 0 to detect nops def template LoadNopCheckDecode {{ { MipsStaticInst *i = new %(class_name)s(machInst); @@ -446,7 +499,6 @@ def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, exec_template_base = 'Load') }}; - def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, mem_flags = [], inst_flags = []) {{ (header_output, decoder_output, decode_block, exec_output) = \ @@ -454,26 +506,70 @@ def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, exec_template_base = 'Store') }}; -//FP loads are offloaded to these formats for now ... -def format LoadFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, +def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, mem_flags = [], inst_flags = []) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, - decode_template = BasicDecode, + decode_template = LoadNopCheckDecode, exec_template_base = 'Load') }}; +def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + exec_template_base = 'Store') +}}; + +def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }}, + mem_flags = [], inst_flags = []) {{ + decl_code = 'uint32_t mem_word = Mem.uw;\n' + decl_code += 'uint32_t unalign_addr = Rs + disp;\n' + decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n' + decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n' + decl_code += '\tbyte_offset ^= 3;\n' + decl_code += '#endif\n' + + memacc_code = decl_code + memacc_code + + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + decode_template = LoadNopCheckDecode, + exec_template_base = 'Load') +}}; -def format StoreFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, +def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }}, mem_flags = [], inst_flags = []) {{ + decl_code = 'uint32_t mem_word = 0;\n' + decl_code += 'uint32_t unaligned_addr = Rs + disp;\n' + decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n' + decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n' + decl_code += '\tbyte_offset ^= 3;\n' + decl_code += '#endif\n' + decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n' + memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n' + (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + decode_template = LoadNopCheckDecode, exec_template_base = 'Store') }}; +def format Prefetch(ea_code = {{ EA = Rs + disp; }}, + mem_flags = [], pf_flags = [], inst_flags = []) {{ + pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] + pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', + 'IsDataPrefetch', 'MemReadOp'] + + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, + 'xc->prefetch(EA, memAccessFlags);', + pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') + +}}; -def format UnalignedStore(memacc_code, postacc_code, - ea_code = {{ EA = Rb + disp; }}, +def format StoreCond(memacc_code, postacc_code, + ea_code = {{ EA = Rs + disp; }}, mem_flags = [], inst_flags = []) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, diff --git a/src/arch/mips/isa/formats/mt.isa b/src/arch/mips/isa/formats/mt.isa new file mode 100644 index 000000000..521b01123 --- /dev/null +++ b/src/arch/mips/isa/formats/mt.isa @@ -0,0 +1,81 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell + +//////////////////////////////////////////////////////////////////// +// +// MT instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class MT : public MipsStaticInst + { + protected: + + /// Constructor + MT(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + //Edit This Template When MT is Implemented + std::string MT::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of MT instruction\n"; + } +}}; + +def template MTExecute {{ + //Edit This Template When MT is Implemented + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //Write the resulting state to the execution context + %(op_wb)s; + + //Call into the trap handler with the appropriate fault + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format MipsMT() {{ + code = 'panic(\"Mips MT Is Currently Unimplemented.\");\n' + iop = InstObjParams(name, Name, 'MT', CodeBlock(code)) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/src/arch/mips/isa/formats/noop.isa b/src/arch/mips/isa/formats/noop.isa index 2aa4816e3..4fd8235e4 100644 --- a/src/arch/mips/isa/formats/noop.isa +++ b/src/arch/mips/isa/formats/noop.isa @@ -1,5 +1,33 @@ // -*- mode:c++ -*- +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell + //////////////////////////////////////////////////////////////////// // // Nop @@ -36,11 +64,7 @@ output decoder {{ std::string Nop::generateDisassembly(Addr pc, const SymbolTable *symtab) const { -#ifdef SS_COMPATIBLE_DISASSEMBLY - return originalDisassembly; -#else - return csprintf("%-10s (%s)", "nop", originalDisassembly); -#endif + return csprintf("%-10s %s", "nop", originalDisassembly); } /// Helper function for decoding nops. Substitute Nop object @@ -89,6 +113,6 @@ def format BasicOperateWithNopCheck(code, *opt_args) {{ }}; def format Nop() {{ - decode_block = 'return new Nop(\"sll r0,r0,0\",machInst);\n' + decode_block = 'return new Nop(\"\",machInst);\n' }}; diff --git a/src/arch/mips/isa/formats/tlbop.isa b/src/arch/mips/isa/formats/tlbop.isa index f5e4076f2..75ab71c48 100644 --- a/src/arch/mips/isa/formats/tlbop.isa +++ b/src/arch/mips/isa/formats/tlbop.isa @@ -1,3 +1,33 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell + //////////////////////////////////////////////////////////////////// // // TlbOp instructions @@ -30,13 +60,10 @@ output decoder {{ def template TlbOpExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - //Call into the trap handler with the appropriate fault - return No_Fault; - } - //Write the resulting state to the execution context %(op_wb)s; + //Call into the trap handler with the appropriate fault return No_Fault; } }}; diff --git a/src/arch/mips/isa/formats/trap.isa b/src/arch/mips/isa/formats/trap.isa index 6884d4fa8..574b808cc 100644 --- a/src/arch/mips/isa/formats/trap.isa +++ b/src/arch/mips/isa/formats/trap.isa @@ -1,3 +1,33 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell + //////////////////////////////////////////////////////////////////// // // Trap instructions @@ -23,27 +53,26 @@ output header {{ output decoder {{ std::string Trap::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - return "Disassembly of integer instruction\n"; + return "Disassembly of trap instruction\n"; } }}; def template TrapExecute {{ + //Edit This Template When Traps Are Implemented Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - //Call into the trap handler with the appropriate fault - return No_Fault; - } - //Write the resulting state to the execution context %(op_wb)s; + //Call into the trap handler with the appropriate fault return No_Fault; } }}; -// Primary format for integer operate instructions: def format Trap(code, *flags) {{ - code = 'bool cond;\n' + code; + code = 'panic(\"' + code += 'Trap Exception Handler Is Currently Not Implemented.' + code += '\");' iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) diff --git a/src/arch/mips/isa/formats/unimp.isa b/src/arch/mips/isa/formats/unimp.isa index 8e42da499..e17b5f832 100644 --- a/src/arch/mips/isa/formats/unimp.isa +++ b/src/arch/mips/isa/formats/unimp.isa @@ -1,5 +1,6 @@ // -*- mode:c++ -*- + // Copyright (c) 2003-2005 The Regents of The University of Michigan // All rights reserved. // @@ -103,11 +104,7 @@ output decoder {{ WarnUnimplemented::generateDisassembly(Addr pc, const SymbolTable *symtab) const { -#ifdef SS_COMPATIBLE_DISASSEMBLY - return csprintf("%-10s", mnemonic); -#else return csprintf("%-10s (unimplemented)", mnemonic); -#endif } }}; @@ -127,7 +124,7 @@ output exec {{ Trace::InstRecord *traceData) const { if (!warned) { - warn("instruction '%s' unimplemented\n", mnemonic); + warn("\tinstruction '%s' unimplemented\n", mnemonic); warned = true; } @@ -146,28 +143,3 @@ def format WarnUnimpl() {{ decode_block = BasicDecodeWithMnemonic.subst(iop) }}; -output header {{ - /** - * Static instruction class for unknown (illegal) instructions. - * These cause simulator termination if they are executed in a - * non-speculative mode. This is a leaf class. - */ - class Unknown : public MipsStaticInst - { - public: - /// Constructor - Unknown(MachInst _machInst) - : MipsStaticInst("unknown", _machInst, No_OpClass) - { - // don't call execute() (which panics) if we're on a - // speculative path - flags[IsNonSpeculative] = true; - } - - %(BasicExecDeclare)s - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - diff --git a/src/arch/mips/isa/formats/unknown.isa b/src/arch/mips/isa/formats/unknown.isa index 7c2275598..41387adca 100644 --- a/src/arch/mips/isa/formats/unknown.isa +++ b/src/arch/mips/isa/formats/unknown.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2003-2005 The Regents of The University of Michigan +// Copyright (c) 2003-2006 The Regents of The University of Michigan // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -34,28 +34,31 @@ // output header {{ - std::string inst2string(MachInst machInst); -}}; -output decoder {{ - -std::string inst2string(MachInst machInst) -{ - string str = ""; - uint32_t mask = 0x80000000; - - for(int i=0; i < 32; i++) { - if ((machInst & mask) == 0) { - str += "0"; - } else { - str += "1"; + /** + * Static instruction class for unknown (illegal) instructions. + * These cause simulator termination if they are executed in a + * non-speculative mode. This is a leaf class. + */ + class Unknown : public MipsStaticInst + { + public: + /// Constructor + Unknown(MachInst _machInst) + : MipsStaticInst("unknown", _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; } - mask = mask >> 1; - } + %(BasicExecDeclare)s - return str; -} + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; +output decoder {{ std::string Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const { diff --git a/src/arch/mips/isa/formats/util.isa b/src/arch/mips/isa/formats/util.isa index 615160931..b67a02d07 100644 --- a/src/arch/mips/isa/formats/util.isa +++ b/src/arch/mips/isa/formats/util.isa @@ -1,5 +1,34 @@ // -*- mode:c++ -*- +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Steve Reinhardt +// Korey Sewell + let {{ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, postacc_code = '', base_class = 'Memory', @@ -90,7 +119,31 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + completeAccTemplate.subst(completeacc_iop)) }}; +output header {{ + std::string inst2string(MachInst machInst); +}}; + +output decoder {{ + +std::string inst2string(MachInst machInst) +{ + string str = ""; + uint32_t mask = 0x80000000; + + for(int i=0; i < 32; i++) { + if ((machInst & mask) == 0) { + str += "0"; + } else { + str += "1"; + } + mask = mask >> 1; + } + + return str; +} + +}}; output exec {{ using namespace MipsISA; @@ -124,6 +177,7 @@ output exec {{ #endif + }}; diff --git a/src/arch/mips/isa/includes.isa b/src/arch/mips/isa/includes.isa index 9c370fbe3..555cec255 100644 --- a/src/arch/mips/isa/includes.isa +++ b/src/arch/mips/isa/includes.isa @@ -1,3 +1,33 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell + //////////////////////////////////////////////////////////////////// // // Output include file directives. @@ -16,9 +46,10 @@ output decoder {{ #include "arch/mips/isa_traits.hh" #include "base/cprintf.hh" #include "base/loader/symtab.hh" -#include "cpu/exec_context.hh" // for Jump::branchTarget() +#include "cpu/thread_context.hh" #include "arch/mips/faults.hh" #include "arch/mips/isa_traits.hh" +#include "arch/mips/utility.hh" #include <math.h> #if defined(linux) @@ -31,6 +62,8 @@ using namespace MipsISA; output exec {{ #include "arch/mips/faults.hh" #include "arch/mips/isa_traits.hh" +#include "arch/mips/utility.hh" + #include <math.h> #if defined(linux) #include <fenv.h> diff --git a/src/arch/mips/isa/operands.isa b/src/arch/mips/isa/operands.isa index 0f9c74b48..316552ef4 100644 --- a/src/arch/mips/isa/operands.isa +++ b/src/arch/mips/isa/operands.isa @@ -1,3 +1,33 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-2006 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Korey Sewell + def operand_types {{ 'sb' : ('signed int', 8), 'ub' : ('unsigned int', 8), diff --git a/src/arch/mips/isa_traits.cc b/src/arch/mips/isa_traits.cc index f577a1c94..9f3817a60 100644 --- a/src/arch/mips/isa_traits.cc +++ b/src/arch/mips/isa_traits.cc @@ -40,8 +40,9 @@ using namespace std; void -MipsISA::copyRegs(ExecContext *src, ExecContext *dest) +MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest) { + panic("Copy Regs Not Implemented Yet\n"); /*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag); uniq = xc->readMiscReg(MipsISA::Uniq_DepTag); lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag); @@ -53,8 +54,9 @@ MipsISA::copyRegs(ExecContext *src, ExecContext *dest) } void -MipsISA::MiscRegFile::copyMiscRegs(ExecContext *xc) +MipsISA::MiscRegFile::copyMiscRegs(ThreadContext *tc) { + panic("Copy Misc. Regs Not Implemented Yet\n"); /*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag); uniq = xc->readMiscReg(MipsISA::Uniq_DepTag); lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag); @@ -63,77 +65,6 @@ MipsISA::MiscRegFile::copyMiscRegs(ExecContext *xc) #endif*/ } -uint64_t -MipsISA::fpConvert(double fp_val, ConvertType cvt_type) -{ - - switch (cvt_type) - { - case SINGLE_TO_DOUBLE: - double sdouble_val = fp_val; - void *sdouble_ptr = &sdouble_val; - uint64_t sdp_bits = *(uint64_t *) sdouble_ptr; - return sdp_bits; - - case SINGLE_TO_WORD: - int32_t sword_val = (int32_t) fp_val; - void *sword_ptr = &sword_val; - uint64_t sword_bits= *(uint32_t *) sword_ptr; - return sword_bits; - - case WORD_TO_SINGLE: - float wfloat_val = fp_val; - void *wfloat_ptr = &wfloat_val; - uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr; - return wfloat_bits; - - case WORD_TO_DOUBLE: - double wdouble_val = fp_val; - void *wdouble_ptr = &wdouble_val; - uint64_t wdp_bits = *(uint64_t *) wdouble_ptr; - return wdp_bits; - - default: - panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type); - return 0; - } -} - -double -MipsISA::roundFP(double val, int digits) -{ - double digit_offset = pow(10.0,digits); - val = val * digit_offset; - val = val + 0.5; - val = floor(val); - val = val / digit_offset; - return val; -} - -double -MipsISA::truncFP(double val) -{ - int trunc_val = (int) val; - return (double) trunc_val; -} - -bool -MipsISA::getFPConditionCode(uint32_t fcsr_reg, int cc) -{ - //uint32_t cc_bits = xc->readFloatReg(35); - return false;//regFile.floatRegfile.getConditionCode(cc); -} - -uint32_t -MipsISA::makeCCVector(uint32_t fcsr, int num, bool val) -{ - int shift = (num == 0) ? 22 : num + 23; - - fcsr = fcsr | (val << shift); - - return fcsr; -} - #if FULL_SYSTEM static inline Addr diff --git a/src/arch/mips/isa_traits.hh b/src/arch/mips/isa_traits.hh index e99bc7395..dc8b6758a 100644 --- a/src/arch/mips/isa_traits.hh +++ b/src/arch/mips/isa_traits.hh @@ -48,7 +48,7 @@ class FastCPU; class FullCPU; class Checkpoint; -class ExecContext; +class ThreadContext; namespace LittleEndianGuest {}; @@ -131,14 +131,14 @@ namespace MipsISA /** * Function to insure ISA semantics about 0 registers. - * @param xc The execution context. + * @param tc The thread context. */ - template <class XC> - void zeroRegisters(XC *xc); + template <class TC> + void zeroRegisters(TC *tc); const Addr MaxAddr = (Addr)-1; - void copyRegs(ExecContext *src, ExecContext *dest); + void copyRegs(ThreadContext *src, ThreadContext *dest); uint64_t fpConvert(double fp_val, ConvertType cvt_type); double roundFP(double val, int digits); diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 1408dbac0..17e735527 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -33,7 +33,7 @@ #include "arch/mips/isa_traits.hh" #include "base/trace.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "kern/linux/linux.hh" #include "sim/process.hh" @@ -45,9 +45,9 @@ using namespace MipsISA; /// Target uname() handler. static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) + ThreadContext *tc) { - TypedBufferArg<Linux::utsname> name(xc->getSyscallArg(0)); + TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -55,7 +55,7 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process, strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); strcpy(name->machine, "mips"); - name.copyOut(xc->getMemPort()); + name.copyOut(tc->getMemPort()); return 0; } @@ -64,18 +64,18 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process, /// different in practice from those used by Tru64 processes. static SyscallReturn sys_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) + ThreadContext *tc) { - unsigned op = xc->getSyscallArg(0); - // unsigned nbytes = xc->getSyscallArg(2); + unsigned op = tc->getSyscallArg(0); + // unsigned nbytes = tc->getSyscallArg(2); switch (op) { case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1)); + TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1)); // I don't think this exactly matches the HW FPCR *fpcr = 0; - fpcr.copyOut(xc->getMemPort()); + fpcr.copyOut(tc->getMemPort()); return 0; } @@ -91,17 +91,17 @@ sys_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, /// Target sys_setsysinfo() handler. static SyscallReturn sys_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) + ThreadContext *tc) { - unsigned op = xc->getSyscallArg(0); - // unsigned nbytes = xc->getSyscallArg(2); + unsigned op = tc->getSyscallArg(0); + // unsigned nbytes = tc->getSyscallArg(2); switch (op) { case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1)); + TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1)); // I don't think this exactly matches the HW FPCR - fpcr.copyIn(xc->getMemPort()); + fpcr.copyIn(tc->getMemPort()); DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): " " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr)); return 0; @@ -135,7 +135,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", chmodFunc<MipsLinux>), /* 16 */ SyscallDesc("lchown", chownFunc), - /* 17 */ SyscallDesc("break", obreakFunc), /*obreak*/ + /* 17 */ SyscallDesc("break", obreakFunc), /* 18 */ SyscallDesc("unused#18", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getpid", getpidFunc), @@ -163,7 +163,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 42 */ SyscallDesc("pipe", unimplementedFunc), /* 43 */ SyscallDesc("times", unimplementedFunc), /* 44 */ SyscallDesc("prof", unimplementedFunc), - /* 45 */ SyscallDesc("brk", obreakFunc),/*openFunc<MipsLinux>*/ + /* 45 */ SyscallDesc("brk", obreakFunc), /* 46 */ SyscallDesc("setgid", unimplementedFunc), /* 47 */ SyscallDesc("getgid", getgidFunc), /* 48 */ SyscallDesc("signal", ignoreFunc), @@ -173,7 +173,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 52 */ SyscallDesc("umount2", unimplementedFunc), /* 53 */ SyscallDesc("lock", unimplementedFunc), /* 54 */ SyscallDesc("ioctl", ioctlFunc<MipsLinux>), - /* 55 */ SyscallDesc("fcntl", unimplementedFunc), + /* 55 */ SyscallDesc("fcntl", fcntlFunc), /* 56 */ SyscallDesc("mpx", unimplementedFunc), /* 57 */ SyscallDesc("setpgid", unimplementedFunc), /* 58 */ SyscallDesc("ulimit", unimplementedFunc), @@ -210,8 +210,8 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 89 */ SyscallDesc("readdir", unimplementedFunc), /* 90 */ SyscallDesc("mmap", mmapFunc<MipsLinux>), /* 91 */ SyscallDesc("munmap",munmapFunc), - /* 92 */ SyscallDesc("truncate", fcntlFunc), - /* 93 */ SyscallDesc("ftruncate", unimplementedFunc), + /* 92 */ SyscallDesc("truncate", truncateFunc), + /* 93 */ SyscallDesc("ftruncate", ftruncateFunc), /* 94 */ SyscallDesc("fchmod", unimplementedFunc), /* 95 */ SyscallDesc("fchown", unimplementedFunc), /* 96 */ SyscallDesc("getpriority", unimplementedFunc), @@ -262,7 +262,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 141 */ SyscallDesc("getdents", unimplementedFunc), /* 142 */ SyscallDesc("newselect", unimplementedFunc), /* 143 */ SyscallDesc("flock", unimplementedFunc), - /* 144 */ SyscallDesc("msync", unimplementedFunc),/*getrlimitFunc<MipsLinux>*/ + /* 144 */ SyscallDesc("msync", unimplementedFunc), /* 145 */ SyscallDesc("readv", unimplementedFunc), /* 146 */ SyscallDesc("writev", writevFunc<MipsLinux>), /* 147 */ SyscallDesc("cacheflush", unimplementedFunc), @@ -338,7 +338,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 217 */ SyscallDesc("mincore", unimplementedFunc), /* 218 */ SyscallDesc("madvise", unimplementedFunc), /* 219 */ SyscallDesc("getdents64", unimplementedFunc), - /* 220 */ SyscallDesc("fcntl64", fcntlFunc), + /* 220 */ SyscallDesc("fcntl64", fcntl64Func), /* 221 */ SyscallDesc("reserved#221", unimplementedFunc), /* 222 */ SyscallDesc("gettid", unimplementedFunc), /* 223 */ SyscallDesc("readahead", unimplementedFunc), @@ -414,9 +414,7 @@ MipsLinuxProcess::MipsLinuxProcess(const std::string &name, : MipsLiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd, argv, envp), Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) -{ - //init_regs->intRegFile[0] = 0; -} +{ } SyscallDesc* MipsLinuxProcess::getDesc(int callnum) diff --git a/src/arch/mips/linux/process.hh b/src/arch/mips/linux/process.hh index 2c2dadc8b..68da3227b 100644 --- a/src/arch/mips/linux/process.hh +++ b/src/arch/mips/linux/process.hh @@ -24,8 +24,6 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Korey Sewell */ #ifndef __MIPS_LINUX_PROCESS_HH__ diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index 13d8ac3a8..6f2c88f69 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -27,6 +27,7 @@ * * Authors: Gabe Black * Ali Saidi + * Korey Sewell */ #include "arch/mips/isa_traits.hh" @@ -34,7 +35,7 @@ #include "arch/mips/linux/process.hh" #include "base/loader/object_file.hh" #include "base/misc.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "sim/builder.hh" #include "sim/system.hh" @@ -56,7 +57,8 @@ MipsLiveProcess::create(const std::string &nm, System *system, int stdin_fd, if (objFile->getArch() != ObjectFile::Mips) - fatal("Object file does not match architecture."); + fatal("Object file does not match MIPS architecture."); + switch (objFile->getOpSys()) { case ObjectFile::Linux: process = new MipsLinuxProcess(nm, objFile, system, @@ -79,22 +81,19 @@ MipsLiveProcess::MipsLiveProcess(const std::string &nm, ObjectFile *objFile, : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd, argv, envp) { + // Set up stack. On MIPS, stack starts at the top of kuseg + // user address space. MIPS stack grows down from here + stack_base = 0x7FFFFFFF; - // XXX all the below need to be updated for SPARC - Ali + // Set pointer for next thread stack. Reserve 8M for main stack. + next_thread_stack_base = stack_base - (8 * 1024 * 1024); + + // Set up break point (Top of Heap) brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize(); brk_point = roundUp(brk_point, VMPageSize); - // Set up stack. On Alpha, stack goes below text section. This - // code should get moved to some architecture-specific spot. - stack_base = objFile->textBase() - (409600+4096); - - // Set up region for mmaps. Tru64 seems to start just above 0 and - // grow up from there. + // Set up region for mmaps. For now, start at bottom of kuseg space. mmap_start = mmap_end = 0x10000; - - // Set pointer for next thread stack. Reserve 8M for main stack. - next_thread_stack_base = stack_base - (8 * 1024 * 1024); - } void diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh index 45513af46..dae891125 100644 --- a/src/arch/mips/process.hh +++ b/src/arch/mips/process.hh @@ -27,6 +27,7 @@ * * Authors: Gabe Black * Ali Saidi + * Korey Sewell */ #ifndef __MIPS_PROCESS_HH__ diff --git a/src/arch/mips/regfile/float_regfile.hh b/src/arch/mips/regfile/float_regfile.hh index 3781a91f3..d1a60298a 100644 --- a/src/arch/mips/regfile/float_regfile.hh +++ b/src/arch/mips/regfile/float_regfile.hh @@ -40,7 +40,7 @@ #include "sim/host.hh" class Checkpoint; -class ExecContext; +class ThreadContext; class Regfile; namespace MipsISA @@ -62,13 +62,17 @@ namespace MipsISA switch(width) { case SingleWidth: - void *float_ptr = ®s[floatReg]; - return *(float *) float_ptr; + { + void *float_ptr = ®s[floatReg]; + return *(float *) float_ptr; + } case DoubleWidth: - uint64_t double_val = (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg]; - void *double_ptr = &double_val; - return *(double *) double_ptr; + { + uint64_t double_val = (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg]; + void *double_ptr = &double_val; + return *(double *) double_ptr; + } default: panic("Attempted to read a %d bit floating point register!", width); @@ -99,21 +103,24 @@ namespace MipsISA Fault setReg(int floatReg, const FloatReg &val, int width) { - switch(width) { case SingleWidth: - float temp = val; - void *float_ptr = &temp; - regs[floatReg] = *(FloatReg32 *) float_ptr; - break; + { + float temp = val; + void *float_ptr = &temp; + regs[floatReg] = *(FloatReg32 *) float_ptr; + break; + } case DoubleWidth: - const void *double_ptr = &val; - FloatReg64 temp_double = *(FloatReg64 *) double_ptr; - regs[floatReg + 1] = temp_double >> 32; - regs[floatReg] = temp_double; - break; + { + const void *double_ptr = &val; + FloatReg64 temp_double = *(FloatReg64 *) double_ptr; + regs[floatReg + 1] = temp_double >> 32; + regs[floatReg] = 0x0000FFFF & temp_double; + break; + } default: panic("Attempted to read a %d bit floating point register!", width); @@ -148,14 +155,6 @@ namespace MipsISA void unserialize(Checkpoint *cp, const std::string §ion); }; - enum MiscFloatRegNums { - FIR = NumFloatArchRegs, - FCCR, - FEXR, - FENR, - FCSR - }; - } // namespace MipsISA #endif diff --git a/src/arch/mips/regfile/int_regfile.hh b/src/arch/mips/regfile/int_regfile.hh index 2a0db38a4..dc82a3c26 100644 --- a/src/arch/mips/regfile/int_regfile.hh +++ b/src/arch/mips/regfile/int_regfile.hh @@ -37,7 +37,7 @@ #include "sim/faults.hh" class Checkpoint; -class ExecContext; +class ThreadContext; class Regfile; namespace MipsISA diff --git a/src/arch/mips/regfile/misc_regfile.hh b/src/arch/mips/regfile/misc_regfile.hh index 72aa17424..f8aeab8cb 100644 --- a/src/arch/mips/regfile/misc_regfile.hh +++ b/src/arch/mips/regfile/misc_regfile.hh @@ -36,7 +36,7 @@ #include "sim/faults.hh" class Checkpoint; -class ExecContext; +class ThreadContext; class Regfile; namespace MipsISA @@ -57,14 +57,14 @@ namespace MipsISA int getInstAsid(); int getDataAsid(); - void copyMiscRegs(ExecContext *xc); + void copyMiscRegs(ThreadContext *tc); MiscReg readReg(int misc_reg) { return miscRegFile[misc_reg]; } - MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc) + MiscReg readRegWithEffect(int misc_reg, Fault &fault, ThreadContext *tc) { return miscRegFile[misc_reg]; } @@ -75,7 +75,7 @@ namespace MipsISA } Fault setRegWithEffect(int misc_reg, const MiscReg &val, - ExecContext *xc) + ThreadContext *tc) { miscRegFile[misc_reg] = val; return NoFault; } @@ -87,9 +87,9 @@ namespace MipsISA InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs private: - MiscReg readIpr(int idx, Fault &fault, ExecContext *xc) { } + MiscReg readIpr(int idx, Fault &fault, ThreadContext *tc) { } - Fault setIpr(int idx, uint64_t val, ExecContext *xc) { } + Fault setIpr(int idx, uint64_t val, ThreadContext *tc) { } #endif friend class RegFile; }; diff --git a/src/arch/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh index e1b834568..af61e62cd 100644 --- a/src/arch/mips/regfile/regfile.hh +++ b/src/arch/mips/regfile/regfile.hh @@ -39,7 +39,7 @@ #include "sim/faults.hh" class Checkpoint; -class ExecContext; +class ThreadContext; namespace MipsISA { @@ -64,10 +64,10 @@ namespace MipsISA } MiscReg readMiscRegWithEffect(int miscReg, - Fault &fault, ExecContext *xc) + Fault &fault, ThreadContext *tc) { fault = NoFault; - return miscRegFile.readRegWithEffect(miscReg, fault, xc); + return miscRegFile.readRegWithEffect(miscReg, fault, tc); } Fault setMiscReg(int miscReg, const MiscReg &val) @@ -76,9 +76,9 @@ namespace MipsISA } Fault setMiscRegWithEffect(int miscReg, const MiscReg &val, - ExecContext * xc) + ThreadContext * tc) { - return miscRegFile.setRegWithEffect(miscReg, val, xc); + return miscRegFile.setRegWithEffect(miscReg, val, tc); } FloatReg readFloatReg(int floatReg) @@ -189,12 +189,12 @@ namespace MipsISA } }; - void copyRegs(ExecContext *src, ExecContext *dest); + void copyRegs(ThreadContext *src, ThreadContext *dest); - void copyMiscRegs(ExecContext *src, ExecContext *dest); + void copyMiscRegs(ThreadContext *src, ThreadContext *dest); #if FULL_SYSTEM - void copyIprs(ExecContext *src, ExecContext *dest); + void copyIprs(ThreadContext *src, ThreadContext *dest); #endif } // namespace MipsISA diff --git a/src/arch/mips/stacktrace.hh b/src/arch/mips/stacktrace.hh index 3516b1d19..38767cef7 100644 --- a/src/arch/mips/stacktrace.hh +++ b/src/arch/mips/stacktrace.hh @@ -34,13 +34,13 @@ #include "base/trace.hh" #include "cpu/static_inst.hh" -class ExecContext; +class ThreadContext; class StackTrace; class ProcessInfo { private: - ExecContext *xc; + ThreadContext *tc; int thread_info_size; int task_struct_size; @@ -49,7 +49,7 @@ class ProcessInfo int name_off; public: - ProcessInfo(ExecContext *_xc); + ProcessInfo(ThreadContext *_tc); Addr task(Addr ksp) const; int pid(Addr ksp) const; @@ -61,7 +61,7 @@ class StackTrace protected: typedef TheISA::MachInst MachInst; private: - ExecContext *xc; + ThreadContext *tc; std::vector<Addr> stack; private: @@ -70,21 +70,21 @@ class StackTrace bool decodeSave(MachInst inst, int ®, int &disp); bool decodeStack(MachInst inst, int &disp); - void trace(ExecContext *xc, bool is_call); + void trace(ThreadContext *tc, bool is_call); public: StackTrace(); - StackTrace(ExecContext *xc, StaticInstPtr inst); + StackTrace(ThreadContext *tc, StaticInstPtr inst); ~StackTrace(); void clear() { - xc = 0; + tc = 0; stack.clear(); } - bool valid() const { return xc != NULL; } - bool trace(ExecContext *xc, StaticInstPtr inst); + bool valid() const { return tc != NULL; } + bool trace(ThreadContext *tc, StaticInstPtr inst); public: const std::vector<Addr> &getstack() const { return stack; } @@ -106,7 +106,7 @@ class StackTrace }; inline bool -StackTrace::trace(ExecContext *xc, StaticInstPtr inst) +StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) { if (!inst->isCall() && !inst->isReturn()) return false; @@ -114,7 +114,7 @@ StackTrace::trace(ExecContext *xc, StaticInstPtr inst) if (valid()) clear(); - trace(xc, !inst->isReturn()); + trace(tc, !inst->isReturn()); return true; } diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc new file mode 100644 index 000000000..e7455fdbf --- /dev/null +++ b/src/arch/mips/utility.cc @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2003-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Korey Sewell + */ + +#include "arch/mips/isa_traits.hh" +#include "arch/mips/utility.hh" +#include "config/full_system.hh" +#include "cpu/static_inst.hh" +#include "sim/serialize.hh" +#include "base/bitfield.hh" + +using namespace MipsISA; +using namespace std; + +uint64_t +MipsISA::fpConvert(ConvertType cvt_type, double fp_val) +{ + + switch (cvt_type) + { + case SINGLE_TO_DOUBLE: + { + double sdouble_val = fp_val; + void *sdouble_ptr = &sdouble_val; + uint64_t sdp_bits = *(uint64_t *) sdouble_ptr; + return sdp_bits; + } + + case SINGLE_TO_WORD: + { + int32_t sword_val = (int32_t) fp_val; + void *sword_ptr = &sword_val; + uint64_t sword_bits= *(uint32_t *) sword_ptr; + return sword_bits; + } + + case WORD_TO_SINGLE: + { + float wfloat_val = fp_val; + void *wfloat_ptr = &wfloat_val; + uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr; + return wfloat_bits; + } + + case WORD_TO_DOUBLE: + { + double wdouble_val = fp_val; + void *wdouble_ptr = &wdouble_val; + uint64_t wdp_bits = *(uint64_t *) wdouble_ptr; + return wdp_bits; + } + + default: + panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type); + return 0; + } +} + +double +MipsISA::roundFP(double val, int digits) +{ + double digit_offset = pow(10.0,digits); + val = val * digit_offset; + val = val + 0.5; + val = floor(val); + val = val / digit_offset; + return val; +} + +double +MipsISA::truncFP(double val) +{ + int trunc_val = (int) val; + return (double) trunc_val; +} + +bool +MipsISA::getCondCode(uint32_t fcsr, int cc_idx) +{ + int shift = (cc_idx == 0) ? 23 : cc_idx + 24; + bool cc_val = (fcsr >> shift) & 0x00000001; + return cc_val; +} + +uint32_t +MipsISA::genCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val) +{ + int cc_idx = (cc_num == 0) ? 23 : cc_num + 24; + + fcsr = bits(fcsr, 31, cc_idx + 1) << cc_idx + 1 | + cc_val << cc_idx | + bits(fcsr, cc_idx - 1, 0); + + return fcsr; +} + +uint32_t +MipsISA::genInvalidVector(uint32_t fcsr_bits) +{ + //Set FCSR invalid in "flag" field + int invalid_offset = Invalid + Flag_Field; + fcsr_bits = fcsr_bits | (1 << invalid_offset); + + //Set FCSR invalid in "cause" flag + int cause_offset = Invalid + Cause_Field; + fcsr_bits = fcsr_bits | (1 << cause_offset); + + return fcsr_bits; +} + +bool +MipsISA::isNan(void *val_ptr, int size) +{ + switch (size) + { + case 32: + { + uint32_t val_bits = *(uint32_t *) val_ptr; + return (bits(val_bits, 30, 23) == 0xFF); + } + + case 64: + { + uint64_t val_bits = *(uint64_t *) val_ptr; + return (bits(val_bits, 62, 52) == 0x7FF); + } + + default: + panic("Type unsupported. Size mismatch\n"); + } +} + + +bool +MipsISA::isQnan(void *val_ptr, int size) +{ + switch (size) + { + case 32: + { + uint32_t val_bits = *(uint32_t *) val_ptr; + return (bits(val_bits, 30, 22) == 0x1FE); + } + + case 64: + { + uint64_t val_bits = *(uint64_t *) val_ptr; + return (bits(val_bits, 62, 51) == 0xFFE); + } + + default: + panic("Type unsupported. Size mismatch\n"); + } +} + +bool +MipsISA::isSnan(void *val_ptr, int size) +{ + switch (size) + { + case 32: + { + uint32_t val_bits = *(uint32_t *) val_ptr; + return (bits(val_bits, 30, 22) == 0x1FF); + } + + case 64: + { + uint64_t val_bits = *(uint64_t *) val_ptr; + return (bits(val_bits, 62, 51) == 0xFFF); + } + + default: + panic("Type unsupported. Size mismatch\n"); + } +} diff --git a/src/arch/mips/utility.hh b/src/arch/mips/utility.hh index 5c7dc3ea4..c5c69ddcd 100644 --- a/src/arch/mips/utility.hh +++ b/src/arch/mips/utility.hh @@ -39,6 +39,19 @@ namespace MipsISA { + //Floating Point Utility Functions + uint64_t fpConvert(ConvertType cvt_type, double fp_val); + double roundFP(double val, int digits); + double truncFP(double val); + + bool getCondCode(uint32_t fcsr, int cc); + uint32_t genCCVector(uint32_t fcsr, int num, uint32_t cc_val); + uint32_t genInvalidVector(uint32_t fcsr); + + bool isNan(void *val_ptr, int size); + bool isQnan(void *val_ptr, int size); + bool isSnan(void *val_ptr, int size); }; + #endif diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 09fdf230a..57b4d4d86 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -30,7 +30,7 @@ */ #include "arch/sparc/faults.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "cpu/base.hh" #include "base/trace.hh" @@ -220,36 +220,36 @@ FaultStat TrapInstruction::_count; #if FULL_SYSTEM -void SparcFault::invoke(ExecContext * xc) +void SparcFault::invoke(ThreadContext * tc) { - FaultBase::invoke(xc); + FaultBase::invoke(tc); countStat()++; //Use the SPARC trap state machine /*// exception restart address - if (setRestartAddress() || !xc->inPalMode()) - xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->regs.pc); + if (setRestartAddress() || !tc->inPalMode()) + tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, tc->regs.pc); if (skipFaultingInstruction()) { // traps... skip faulting instruction. - xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, - xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); + tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, + tc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); } - if (!xc->inPalMode()) - AlphaISA::swap_palshadow(&(xc->regs), true); + if (!tc->inPalMode()) + AlphaISA::swap_palshadow(&(tc->regs), true); - xc->regs.pc = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect(); - xc->regs.npc = xc->regs.pc + sizeof(MachInst);*/ + tc->regs.pc = tc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect(); + tc->regs.npc = tc->regs.pc + sizeof(MachInst);*/ } #endif #if !FULL_SYSTEM -void TrapInstruction::invoke(ExecContext * xc) +void TrapInstruction::invoke(ThreadContext * tc) { - xc->syscall(syscall_num); + tc->syscall(syscall_num); } #endif diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index 88efe2eee..9f595a28b 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -46,7 +46,7 @@ class SparcFault : public FaultBase { public: #if FULL_SYSTEM - void invoke(ExecContext * xc); + void invoke(ThreadContext * tc); #endif virtual TrapType trapType() = 0; virtual FaultPriority priority() = 0; @@ -585,7 +585,7 @@ class TrapInstruction : public EnumeratedFault FaultPriority priority() {return _priority;} FaultStat & countStat() {return _count;} #if !FULL_SYSTEM - void invoke(ExecContext * xc); + void invoke(ThreadContext * tc); #endif }; diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index d4fcbb522..346f7b730 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -36,7 +36,7 @@ #include "config/full_system.hh" #include "sim/host.hh" -class ExecContext; +class ThreadContext; class FastCPU; //class FullCPU; class Checkpoint; diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc index db9a32c28..e27255e67 100644 --- a/src/arch/sparc/linux/process.cc +++ b/src/arch/sparc/linux/process.cc @@ -35,7 +35,7 @@ #include "arch/sparc/regfile.hh" #include "base/trace.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "kern/linux/linux.hh" #include "sim/process.hh" @@ -48,9 +48,9 @@ using namespace SparcISA; /// Target uname() handler. static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) + ThreadContext *tc) { - TypedBufferArg<Linux::utsname> name(xc->getSyscallArg(0)); + TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -58,40 +58,40 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process, strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); strcpy(name->machine, "sparc"); - name.copyOut(xc->getMemPort()); + name.copyOut(tc->getMemPort()); return 0; } SyscallReturn SparcISA::getresuidFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc) + Process *p, ThreadContext *tc) { const IntReg id = htog(100); - Addr ruid = xc->getSyscallArg(0); - Addr euid = xc->getSyscallArg(1); - Addr suid = xc->getSyscallArg(2); + Addr ruid = tc->getSyscallArg(0); + Addr euid = tc->getSyscallArg(1); + Addr suid = tc->getSyscallArg(2); //Handle the EFAULT case //Set the ruid if(ruid) { BufferArg ruidBuff(ruid, sizeof(IntReg)); memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg)); - ruidBuff.copyOut(xc->getMemPort()); + ruidBuff.copyOut(tc->getMemPort()); } //Set the euid if(euid) { BufferArg euidBuff(euid, sizeof(IntReg)); memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg)); - euidBuff.copyOut(xc->getMemPort()); + euidBuff.copyOut(tc->getMemPort()); } //Set the suid if(suid) { BufferArg suidBuff(suid, sizeof(IntReg)); memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg)); - suidBuff.copyOut(xc->getMemPort()); + suidBuff.copyOut(tc->getMemPort()); } return 0; } diff --git a/src/arch/sparc/linux/process.hh b/src/arch/sparc/linux/process.hh index cd59e4fd2..f4819ba84 100644 --- a/src/arch/sparc/linux/process.hh +++ b/src/arch/sparc/linux/process.hh @@ -61,7 +61,7 @@ class SparcLinuxProcess : public SparcLiveProcess }; SyscallReturn getresuidFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); + Process *p, ThreadContext *tc); } // namespace SparcISA #endif // __ALPHA_LINUX_PROCESS_HH__ diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 4b18dcca9..633c202ca 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -35,7 +35,7 @@ #include "arch/sparc/solaris/process.hh" #include "base/loader/object_file.hh" #include "base/misc.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "mem/page_table.hh" #include "mem/translating_port.hh" #include "sim/builder.hh" @@ -113,27 +113,27 @@ SparcLiveProcess::startup() //From the SPARC ABI //The process runs in user mode - execContexts[0]->setMiscRegWithEffect(MISCREG_PSTATE, 0x02); + threadContexts[0]->setMiscRegWithEffect(MISCREG_PSTATE, 0x02); //Setup default FP state - execContexts[0]->setMiscReg(MISCREG_FSR, 0); + threadContexts[0]->setMiscReg(MISCREG_FSR, 0); - execContexts[0]->setMiscReg(MISCREG_TICK, 0); + threadContexts[0]->setMiscReg(MISCREG_TICK, 0); // /* * Register window management registers */ //No windows contain info from other programs - execContexts[0]->setMiscRegWithEffect(MISCREG_OTHERWIN, 0); + threadContexts[0]->setMiscRegWithEffect(MISCREG_OTHERWIN, 0); //There are no windows to pop - execContexts[0]->setMiscRegWithEffect(MISCREG_CANRESTORE, 0); + threadContexts[0]->setMiscRegWithEffect(MISCREG_CANRESTORE, 0); //All windows are available to save into - execContexts[0]->setMiscRegWithEffect(MISCREG_CANSAVE, NWindows - 2); + threadContexts[0]->setMiscRegWithEffect(MISCREG_CANSAVE, NWindows - 2); //All windows are "clean" - execContexts[0]->setMiscRegWithEffect(MISCREG_CLEANWIN, NWindows); + threadContexts[0]->setMiscRegWithEffect(MISCREG_CLEANWIN, NWindows); //Start with register window 0 - execContexts[0]->setMiscRegWithEffect(MISCREG_CWP, 0); + threadContexts[0]->setMiscRegWithEffect(MISCREG_CWP, 0); } m5_auxv_t buildAuxVect(int64_t type, int64_t val) @@ -311,14 +311,14 @@ SparcLiveProcess::argsInit(int intSize, int pageSize) initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize); - execContexts[0]->setIntReg(ArgumentReg0, argc); - execContexts[0]->setIntReg(ArgumentReg1, argv_array_base); - execContexts[0]->setIntReg(StackPointerReg, stack_min - StackBias); + threadContexts[0]->setIntReg(ArgumentReg0, argc); + threadContexts[0]->setIntReg(ArgumentReg1, argv_array_base); + threadContexts[0]->setIntReg(StackPointerReg, stack_min - StackBias); Addr prog_entry = objFile->entryPoint(); - execContexts[0]->setPC(prog_entry); - execContexts[0]->setNextPC(prog_entry + sizeof(MachInst)); - execContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst))); + threadContexts[0]->setPC(prog_entry); + threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst)); + threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst))); // num_processes++; } diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index 2739048eb..aaf1fcf24 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -563,9 +563,9 @@ namespace SparcISA #if FULL_SYSTEM /** Process a tick compare event and generate an interrupt on the cpu if * appropriate. */ - void processTickCompare(ExecContext *xc); - void processSTickCompare(ExecContext *xc); - void processHSTickCompare(ExecContext *xc); + void processTickCompare(ThreadContext *tc); + void processSTickCompare(ThreadContext *tc); + void processHSTickCompare(ThreadContext *tc); typedef CpuEventWrapper<MiscRegFile, &MiscRegFile::processTickCompare> TickCompareEvent; @@ -580,10 +580,10 @@ namespace SparcISA HSTickCompareEvent *hSTickCompare; /** Fullsystem only register version of ReadRegWithEffect() */ - MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ExecContext *xc); + MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc); /** Fullsystem only register version of SetRegWithEffect() */ Fault setFSRegWithEffect(int miscReg, const MiscReg &val, - ExecContext * xc); + ThreadContext * tc); #endif public: @@ -657,7 +657,7 @@ namespace SparcISA * are are readFSRegWithEffect (which is called by readRegWithEffect()). * Checking is done for permission based on state bits in the miscreg * file. */ - MiscReg readRegWithEffect(int miscReg, Fault &fault, ExecContext *xc); + MiscReg readRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc); /** write a value into an either an SE or FS IPR. No checking is done * about SE vs. FS as this is mostly used to copy the regfile. Thus more @@ -671,13 +671,13 @@ namespace SparcISA * Checking is done for permission based on state bits in the miscreg * file. */ Fault setRegWithEffect(int miscReg, - const MiscReg &val, ExecContext * xc); + const MiscReg &val, ThreadContext * tc); void serialize(std::ostream & os); void unserialize(Checkpoint * cp, const std::string & section); - void copyMiscRegs(ExecContext * xc); + void copyMiscRegs(ThreadContext * tc); bool isHyperPriv() { return hpstateFields.hpriv; } bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; } @@ -753,9 +753,9 @@ namespace SparcISA } MiscReg readMiscRegWithEffect(int miscReg, - Fault &fault, ExecContext *xc) + Fault &fault, ThreadContext *tc) { - return miscRegFile.readRegWithEffect(miscReg, fault, xc); + return miscRegFile.readRegWithEffect(miscReg, fault, tc); } Fault setMiscReg(int miscReg, const MiscReg &val) @@ -764,9 +764,9 @@ namespace SparcISA } Fault setMiscRegWithEffect(int miscReg, const MiscReg &val, - ExecContext * xc) + ThreadContext * tc) { - return miscRegFile.setRegWithEffect(miscReg, val, xc); + return miscRegFile.setRegWithEffect(miscReg, val, tc); } FloatReg readFloatReg(int floatReg, int width) @@ -853,9 +853,9 @@ namespace SparcISA } }; - void copyRegs(ExecContext *src, ExecContext *dest); + void copyRegs(ThreadContext *src, ThreadContext *dest); - void copyMiscRegs(ExecContext *src, ExecContext *dest); + void copyMiscRegs(ThreadContext *src, ThreadContext *dest); int InterruptLevel(uint64_t softint); diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc index 74f77991d..af0550910 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -33,7 +33,7 @@ #include "arch/sparc/regfile.hh" #include "base/trace.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "kern/solaris/solaris.hh" #include "sim/process.hh" @@ -46,9 +46,9 @@ using namespace SparcISA; /// Target uname() handler. static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) + ThreadContext *tc) { - TypedBufferArg<Solaris::utsname> name(xc->getSyscallArg(0)); + TypedBufferArg<Solaris::utsname> name(tc->getSyscallArg(0)); strcpy(name->sysname, "SunOS"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -56,7 +56,7 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process, strcpy(name->version, "Generic_118558-21"); strcpy(name->machine, "sun4u"); - name.copyOut(xc->getMemPort()); + name.copyOut(tc->getMemPort()); return 0; } diff --git a/src/arch/sparc/stacktrace.hh b/src/arch/sparc/stacktrace.hh index dd86a1553..d12aee211 100644 --- a/src/arch/sparc/stacktrace.hh +++ b/src/arch/sparc/stacktrace.hh @@ -34,13 +34,13 @@ #include "base/trace.hh" #include "cpu/static_inst.hh" -class ExecContext; +class ThreadContext; class StackTrace; class ProcessInfo { private: - ExecContext *xc; + ThreadContext *tc; int thread_info_size; int task_struct_size; @@ -49,7 +49,7 @@ class ProcessInfo int name_off; public: - ProcessInfo(ExecContext *_xc); + ProcessInfo(ThreadContext *_tc); Addr task(Addr ksp) const; int pid(Addr ksp) const; @@ -61,7 +61,7 @@ class StackTrace protected: typedef TheISA::MachInst MachInst; private: - ExecContext *xc; + ThreadContext *tc; std::vector<Addr> stack; private: @@ -70,21 +70,21 @@ class StackTrace bool decodeSave(MachInst inst, int ®, int &disp); bool decodeStack(MachInst inst, int &disp); - void trace(ExecContext *xc, bool is_call); + void trace(ThreadContext *tc, bool is_call); public: StackTrace(); - StackTrace(ExecContext *xc, StaticInstPtr inst); + StackTrace(ThreadContext *tc, StaticInstPtr inst); ~StackTrace(); void clear() { - xc = 0; + tc = 0; stack.clear(); } - bool valid() const { return xc != NULL; } - bool trace(ExecContext *xc, StaticInstPtr inst); + bool valid() const { return tc != NULL; } + bool trace(ThreadContext *tc, StaticInstPtr inst); public: const std::vector<Addr> &getstack() const { return stack; } @@ -106,7 +106,7 @@ class StackTrace }; inline bool -StackTrace::trace(ExecContext *xc, StaticInstPtr inst) +StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) { if (!inst->isCall() && !inst->isReturn()) return false; @@ -114,7 +114,7 @@ StackTrace::trace(ExecContext *xc, StaticInstPtr inst) if (valid()) clear(); - trace(xc, !inst->isReturn()); + trace(tc, !inst->isReturn()); return true; } diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 9f4805058..b89d48663 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -32,7 +32,7 @@ Fault SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, - ExecContext *xc) + ThreadContext *tc) { int64_t time; SparcSystem *sys; @@ -47,25 +47,25 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, setReg(miscReg, val); if (newLevel > oldLevel) ; // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX - //xc->getCpuPtr()->checkInterrupts = true; + //tc->getCpuPtr()->checkInterrupts = true; return NoFault; case MISCREG_SOFTINT_CLR: - return setRegWithEffect(miscReg, ~val & softint, xc); + return setRegWithEffect(miscReg, ~val & softint, tc); case MISCREG_SOFTINT_SET: - return setRegWithEffect(miscReg, val | softint, xc); + return setRegWithEffect(miscReg, val | softint, tc); case MISCREG_TICK_CMPR: if (isNonPriv()) return new PrivilegedOpcode; if (tickCompare == NULL) - tickCompare = new TickCompareEvent(this, xc); + tickCompare = new TickCompareEvent(this, tc); setReg(miscReg, val); if (tick_cmprFields.int_dis && tickCompare.scheduled()) tickCompare.deschedule(); time = tick_cmprFields.tick_cmpr - tickFields.counter; if (!tick_cmprFields.int_dis && time > 0) - tickCompare.schedule(time * xc->getCpuPtr()->cycles(1)); + tickCompare.schedule(time * tc->getCpuPtr()->cycles(1)); return NoFault; case MISCREG_STICK: @@ -73,7 +73,7 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, return new PrivilegedOpcode; if (isPriv()) return new PrivilegedAction; - sys = dynamic_cast<SparcSystem*>(xc->getSystemPtr()); + sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr()); assert(sys != NULL); sys->sysTick = curTick/Clock::Int::ns - val & ~Bit64; stickFields.npt = val & Bit64 ? 1 : 0; @@ -83,8 +83,8 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, if (isNonPriv()) return new PrivilegedOpcode; if (sTickCompare == NULL) - sTickCompare = new STickCompareEvent(this, xc); - sys = dynamic_cast<SparcSystem*>(xc->getSystemPtr()); + sTickCompare = new STickCompareEvent(this, tc); + sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr()); assert(sys != NULL); setReg(miscReg, val); if (stick_cmprFields.int_dis && sTickCompare.scheduled()) @@ -98,7 +98,7 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, case MISCREG_PIL: if (FULL_SYSTEM) { setReg(miscReg, val); - //xc->getCpuPtr()->checkInterrupts; + //tc->getCpuPtr()->checkInterrupts; // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX return NoFault; } else @@ -127,8 +127,8 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, if (isNonPriv()) return new PrivilegedOpcode; if (hSTickCompare == NULL) - hSTickCompare = new HSTickCompareEvent(this, xc); - sys = dynamic_cast<SparcSystem*>(xc->getSystemPtr()); + hSTickCompare = new HSTickCompareEvent(this, tc); + sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr()); assert(sys != NULL); setReg(miscReg, val); if (hstick_cmprFields.int_dis && hSTickCompare.scheduled()) @@ -143,7 +143,7 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, } MiscReg -MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ExecContext * xc) +MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext * tc) { switch (miscReg) { @@ -166,7 +166,7 @@ MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ExecContext * xc) fault = new PrivilegedAction; return 0; } - sys = dynamic_cast<SparcSystem*>(xc->getSystemPtr()); + sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr()); assert(sys != NULL); return curTick/Clock::Int::ns - sys->sysTick | stickFields.npt << 63; case MISCREG_STICK_CMPR: @@ -204,19 +204,19 @@ MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ExecContext * xc) } void -MiscRegFile::processTickCompare(ExecContext *xc) +MiscRegFile::processTickCompare(ThreadContext *tc) { panic("tick compare not implemented\n"); } void -MiscRegFile::processSTickCompare(ExecContext *xc) +MiscRegFile::processSTickCompare(ThreadContext *tc) { panic("tick compare not implemented\n"); } void -MiscRegFile::processHSTickCompare(ExecContext *xc) +MiscRegFile::processHSTickCompare(ThreadContext *tc) { panic("tick compare not implemented\n"); } diff --git a/src/arch/sparc/utility.hh b/src/arch/sparc/utility.hh index f75beb04a..f1c071148 100644 --- a/src/arch/sparc/utility.hh +++ b/src/arch/sparc/utility.hh @@ -81,10 +81,10 @@ namespace SparcISA /** * Function to insure ISA semantics about 0 registers. - * @param xc The execution context. + * @param tc The thread context. */ - template <class XC> - void zeroRegisters(XC *xc); + template <class TC> + void zeroRegisters(TC *tc); } // namespace SparcISA diff --git a/src/arch/sparc/vtophys.cc b/src/arch/sparc/vtophys.cc index 0c69ea0a9..f7fd92c15 100644 --- a/src/arch/sparc/vtophys.cc +++ b/src/arch/sparc/vtophys.cc @@ -36,7 +36,7 @@ #include "arch/alpha/vtophys.hh" #include "base/chunk_generator.hh" #include "base/trace.hh" -#include "cpu/exec_context.hh" +#include "cpu/thread_context.hh" #include "mem/vport.hh" using namespace std; @@ -85,10 +85,10 @@ AlphaISA::vtophys(Addr vaddr) } Addr -AlphaISA::vtophys(ExecContext *xc, Addr addr) +AlphaISA::vtophys(ThreadContext *tc, Addr addr) { AlphaISA::VAddr vaddr = addr; - Addr ptbr = xc->readMiscReg(AlphaISA::IPR_PALtemp20); + Addr ptbr = tc->readMiscReg(AlphaISA::IPR_PALtemp20); Addr paddr = 0; //@todo Andrew couldn't remember why he commented some of this code //so I put it back in. Perhaps something to do with gdb debugging? @@ -101,7 +101,7 @@ AlphaISA::vtophys(ExecContext *xc, Addr addr) paddr = vaddr; } else { AlphaISA::PageTableEntry pte = - kernel_pte_lookup(xc->getPhysPort(), ptbr, vaddr); + kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr); if (pte.valid()) paddr = pte.paddr() | vaddr.offset(); } @@ -115,52 +115,52 @@ AlphaISA::vtophys(ExecContext *xc, Addr addr) void -AlphaISA::CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen) +AlphaISA::CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen) { uint8_t *dst = (uint8_t *)dest; - VirtualPort *vp = xc->getVirtPort(xc); + VirtualPort *vp = tc->getVirtPort(tc); vp->readBlob(src, dst, cplen); - xc->delVirtPort(vp); + tc->delVirtPort(vp); } void -AlphaISA::CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen) +AlphaISA::CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen) { uint8_t *src = (uint8_t *)source; - VirtualPort *vp = xc->getVirtPort(xc); + VirtualPort *vp = tc->getVirtPort(tc); vp->writeBlob(dest, src, cplen); - xc->delVirtPort(vp); + tc->delVirtPort(vp); } void -AlphaISA::CopyStringOut(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen) +AlphaISA::CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen) { int len = 0; - VirtualPort *vp = xc->getVirtPort(xc); + VirtualPort *vp = tc->getVirtPort(tc); do { vp->readBlob(vaddr++, (uint8_t*)dst++, 1); len++; } while (len < maxlen && dst[len] != 0 ); - xc->delVirtPort(vp); + tc->delVirtPort(vp); dst[len] = 0; } void -AlphaISA::CopyStringIn(ExecContext *xc, char *src, Addr vaddr) +AlphaISA::CopyStringIn(ThreadContext *tc, char *src, Addr vaddr) { - VirtualPort *vp = xc->getVirtPort(xc); + VirtualPort *vp = tc->getVirtPort(tc); for (ChunkGenerator gen(vaddr, strlen(src), AlphaISA::PageBytes); !gen.done(); gen.next()) { vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size()); src += gen.size(); } - xc->delVirtPort(vp); + tc->delVirtPort(vp); } diff --git a/src/arch/sparc/vtophys.hh b/src/arch/sparc/vtophys.hh index d9b1a25c9..bf2b757d6 100644 --- a/src/arch/sparc/vtophys.hh +++ b/src/arch/sparc/vtophys.hh @@ -34,7 +34,7 @@ #include "arch/sparc/isa_traits.hh" -class ExecContext; +class ThreadContext; class FunctionalPort; namespace SparcISA { @@ -43,12 +43,12 @@ PageTableEntry kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, SparcISA::VAddr vaddr); Addr vtophys(Addr vaddr); -Addr vtophys(ExecContext *xc, Addr vaddr); +Addr vtophys(ThreadContext *tc, Addr vaddr); -void CopyOut(ExecContext *xc, void *dst, Addr src, size_t len); -void CopyIn(ExecContext *xc, Addr dst, void *src, size_t len); -void CopyStringOut(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen); -void CopyStringIn(ExecContext *xc, char *src, Addr vaddr); +void CopyOut(ThreadContext *tc, void *dst, Addr src, size_t len); +void CopyIn(ThreadContext *tc, Addr dst, void *src, size_t len); +void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen); +void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr); }; #endif // __ARCH_SPARC_VTOPHYS_H__ |