style: change C/C++ source permissions to noexec
[gem5.git] / src / cpu / o3 / thread_context_impl.hh
old mode 100755 (executable)
new mode 100644 (file)
index d2acc62..d9f84fb
@@ -1,4 +1,17 @@
 /*
+ * Copyright (c) 2010-2012, 2016-2017 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2004-2006 The Regents of The University of Michigan
  * All rights reserved.
  *
  *          Korey Sewell
  */
 
-#include "arch/regfile.hh"
+#ifndef __CPU_O3_THREAD_CONTEXT_IMPL_HH__
+#define __CPU_O3_THREAD_CONTEXT_IMPL_HH__
+
+#include "arch/kernel_stats.hh"
+#include "arch/registers.hh"
+#include "config/the_isa.hh"
 #include "cpu/o3/thread_context.hh"
 #include "cpu/quiesce_event.hh"
+#include "debug/O3CPU.hh"
 
-#if FULL_SYSTEM
 template <class Impl>
-VirtualPort *
-O3ThreadContext<Impl>::getVirtPort(ThreadContext *src_tc)
+FSTranslatingPortProxy&
+O3ThreadContext<Impl>::getVirtProxy()
 {
-    if (!src_tc)
-        return thread->getVirtPort();
-
-    VirtualPort *vp;
-
-    vp = new VirtualPort("tc-vport", src_tc);
-    thread->connectToMemFunc(vp);
-    return vp;
+    return thread->getVirtProxy();
 }
 
 template <class Impl>
@@ -54,84 +65,38 @@ O3ThreadContext<Impl>::dumpFuncProfile()
 {
     thread->dumpFuncProfile();
 }
-#endif
 
 template <class Impl>
 void
 O3ThreadContext<Impl>::takeOverFrom(ThreadContext *old_context)
 {
-    // some things should already be set up
-#if FULL_SYSTEM
-    assert(getSystemPtr() == old_context->getSystemPtr());
-#else
-    assert(getProcessPtr() == old_context->getProcessPtr());
-#endif
-
-    // copy over functional state
-    setStatus(old_context->status());
-    copyArchRegs(old_context);
-    setCpuId(old_context->readCpuId());
-
-#if !FULL_SYSTEM
-    thread->funcExeInst = old_context->readFuncExeInst();
-#else
-    EndQuiesceEvent *other_quiesce = old_context->getQuiesceEvent();
-    if (other_quiesce) {
-        // Point the quiesce event's TC at this TC so that it wakes up
-        // the proper CPU.
-        other_quiesce->tc = this;
-    }
-    if (thread->quiesceEvent) {
-        thread->quiesceEvent->tc = this;
-    }
+    ::takeOverFrom(*this, *old_context);
+    TheISA::Decoder *newDecoder = getDecoderPtr();
+    TheISA::Decoder *oldDecoder = old_context->getDecoderPtr();
+    newDecoder->takeOverFrom(oldDecoder);
 
-    // Transfer kernel stats from one CPU to the other.
     thread->kernelStats = old_context->getKernelStats();
-//    storeCondFailures = 0;
-    cpu->lockFlag = false;
-#endif
-
-    old_context->setStatus(ThreadContext::Unallocated);
+    thread->funcExeInst = old_context->readFuncExeInst();
 
-    thread->inSyscall = false;
+    thread->noSquashFromTC = false;
     thread->trapPending = false;
 }
 
-#if FULL_SYSTEM
 template <class Impl>
 void
-O3ThreadContext<Impl>::delVirtPort(VirtualPort *vp)
-{
-    if (vp != thread->getVirtPort()) {
-        delete vp->getPeer();
-        delete vp;
-    }
-}
-#endif
-
-template <class Impl>
-void
-O3ThreadContext<Impl>::activate(int delay)
+O3ThreadContext<Impl>::activate()
 {
     DPRINTF(O3CPU, "Calling activate on Thread Context %d\n",
-            getThreadNum());
+            threadId());
 
     if (thread->status() == ThreadContext::Active)
         return;
 
-#if FULL_SYSTEM
-    thread->lastActivate = curTick;
-#endif
-
-    if (thread->status() == ThreadContext::Unallocated) {
-        cpu->activateWhenReady(thread->readTid());
-        return;
-    }
-
+    thread->lastActivate = curTick();
     thread->setStatus(ThreadContext::Active);
 
     // status() == Suspended
-    cpu->activateContext(thread->readTid(), delay);
+    cpu->activateContext(thread->threadId());
 }
 
 template <class Impl>
@@ -139,89 +104,46 @@ void
 O3ThreadContext<Impl>::suspend()
 {
     DPRINTF(O3CPU, "Calling suspend on Thread Context %d\n",
-            getThreadNum());
+            threadId());
 
     if (thread->status() == ThreadContext::Suspended)
         return;
 
-#if FULL_SYSTEM
-    thread->lastActivate = curTick;
-    thread->lastSuspend = curTick;
-#endif
-/*
-#if FULL_SYSTEM
-    // Don't change the status from active if there are pending interrupts
-    if (cpu->check_interrupts()) {
-        assert(status() == ThreadContext::Active);
+    if (cpu->isDraining()) {
+        DPRINTF(O3CPU, "Ignoring suspend on TC due to pending drain\n");
         return;
     }
-#endif
-*/
-    thread->setStatus(ThreadContext::Suspended);
-    cpu->suspendContext(thread->readTid());
-}
-
-template <class Impl>
-void
-O3ThreadContext<Impl>::deallocate(int delay)
-{
-    DPRINTF(O3CPU, "Calling deallocate on Thread Context %d delay %d\n",
-            getThreadNum(), delay);
 
-    if (thread->status() == ThreadContext::Unallocated)
-        return;
+    thread->lastActivate = curTick();
+    thread->lastSuspend = curTick();
 
-    thread->setStatus(ThreadContext::Unallocated);
-    cpu->deallocateContext(thread->readTid(), true, delay);
+    thread->setStatus(ThreadContext::Suspended);
+    cpu->suspendContext(thread->threadId());
 }
 
 template <class Impl>
 void
 O3ThreadContext<Impl>::halt()
 {
-    DPRINTF(O3CPU, "Calling halt on Thread Context %d\n",
-            getThreadNum());
+    DPRINTF(O3CPU, "Calling halt on Thread Context %d\n", threadId());
 
     if (thread->status() == ThreadContext::Halted)
         return;
 
     thread->setStatus(ThreadContext::Halted);
-    cpu->haltContext(thread->readTid());
+    cpu->haltContext(thread->threadId());
 }
 
 template <class Impl>
 void
 O3ThreadContext<Impl>::regStats(const std::string &name)
 {
-#if FULL_SYSTEM
-    thread->kernelStats = new TheISA::Kernel::Statistics(cpu->system);
-    thread->kernelStats->regStats(name + ".kern");
-#endif
-}
-
-template <class Impl>
-void
-O3ThreadContext<Impl>::serialize(std::ostream &os)
-{
-#if FULL_SYSTEM
-    if (thread->kernelStats)
-        thread->kernelStats->serialize(os);
-#endif
-
-}
-
-template <class Impl>
-void
-O3ThreadContext<Impl>::unserialize(Checkpoint *cp, const std::string &section)
-{
-#if FULL_SYSTEM
-    if (thread->kernelStats)
-        thread->kernelStats->unserialize(cp, section);
-#endif
-
+    if (FullSystem) {
+        thread->kernelStats = new TheISA::Kernel::Statistics();
+        thread->kernelStats->regStats(name + ".kern");
+    }
 }
 
-#if FULL_SYSTEM
 template <class Impl>
 Tick
 O3ThreadContext<Impl>::readLastActivate()
@@ -249,244 +171,172 @@ O3ThreadContext<Impl>::profileSample()
 {
     thread->profileSample();
 }
-#endif
-
-template <class Impl>
-TheISA::MachInst
-O3ThreadContext<Impl>:: getInst()
-{
-    return thread->getInst();
-}
 
 template <class Impl>
 void
 O3ThreadContext<Impl>::copyArchRegs(ThreadContext *tc)
 {
-    // This function will mess things up unless the ROB is empty and
-    // there are no instructions in the pipeline.
-    unsigned tid = thread->readTid();
-    PhysRegIndex renamed_reg;
-
-    // First loop through the integer registers.
-    for (int i = 0; i < TheISA::NumIntRegs; ++i) {
-        renamed_reg = cpu->renameMap[tid].lookup(i);
-
-        DPRINTF(O3CPU, "Copying over register %i, had data %lli, "
-                "now has data %lli.\n",
-                renamed_reg, cpu->readIntReg(renamed_reg),
-                tc->readIntReg(i));
-
-        cpu->setIntReg(renamed_reg, tc->readIntReg(i));
-    }
-
-    // Then loop through the floating point registers.
-    for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
-        renamed_reg = cpu->renameMap[tid].lookup(i + TheISA::FP_Base_DepTag);
-        cpu->setFloatRegBits(renamed_reg,
-                             tc->readFloatRegBits(i));
-    }
-
-    // Copy the misc regs.
-    TheISA::copyMiscRegs(tc, this);
+    // Prevent squashing
+    thread->noSquashFromTC = true;
+    TheISA::copyRegs(tc, this);
+    thread->noSquashFromTC = false;
 
-    // Then finally set the PC and the next PC.
-    cpu->setPC(tc->readPC(), tid);
-    cpu->setNextPC(tc->readNextPC(), tid);
-#if !FULL_SYSTEM
-    this->thread->funcExeInst = tc->readFuncExeInst();
-#endif
+    if (!FullSystem)
+        this->thread->funcExeInst = tc->readFuncExeInst();
 }
 
 template <class Impl>
 void
 O3ThreadContext<Impl>::clearArchRegs()
-{}
+{
+    cpu->isa[thread->threadId()]->clear();
+}
 
 template <class Impl>
 uint64_t
-O3ThreadContext<Impl>::readIntReg(int reg_idx)
+O3ThreadContext<Impl>::readIntRegFlat(int reg_idx)
 {
-    reg_idx = TheISA::flattenIntIndex(this, reg_idx);
-    return cpu->readArchIntReg(reg_idx, thread->readTid());
+    return cpu->readArchIntReg(reg_idx, thread->threadId());
 }
 
 template <class Impl>
 TheISA::FloatReg
-O3ThreadContext<Impl>::readFloatReg(int reg_idx, int width)
+O3ThreadContext<Impl>::readFloatRegFlat(int reg_idx)
 {
-    switch(width) {
-      case 32:
-        return cpu->readArchFloatRegSingle(reg_idx, thread->readTid());
-      case 64:
-        return cpu->readArchFloatRegDouble(reg_idx, thread->readTid());
-      default:
-        panic("Unsupported width!");
-        return 0;
-    }
+    return cpu->readArchFloatReg(reg_idx, thread->threadId());
 }
 
 template <class Impl>
-TheISA::FloatReg
-O3ThreadContext<Impl>::readFloatReg(int reg_idx)
+TheISA::FloatRegBits
+O3ThreadContext<Impl>::readFloatRegBitsFlat(int reg_idx)
 {
-    return cpu->readArchFloatRegSingle(reg_idx, thread->readTid());
+    return cpu->readArchFloatRegInt(reg_idx, thread->threadId());
 }
 
 template <class Impl>
-TheISA::FloatRegBits
-O3ThreadContext<Impl>::readFloatRegBits(int reg_idx, int width)
+const TheISA::VecRegContainer&
+O3ThreadContext<Impl>::readVecRegFlat(int reg_id) const
 {
-    DPRINTF(Fault, "Reading floatint register through the TC!\n");
-    return cpu->readArchFloatRegInt(reg_idx, thread->readTid());
+    return cpu->readArchVecReg(reg_id, thread->threadId());
 }
 
 template <class Impl>
-TheISA::FloatRegBits
-O3ThreadContext<Impl>::readFloatRegBits(int reg_idx)
+TheISA::VecRegContainer&
+O3ThreadContext<Impl>::getWritableVecRegFlat(int reg_id)
 {
-    return cpu->readArchFloatRegInt(reg_idx, thread->readTid());
+    return cpu->getWritableArchVecReg(reg_id, thread->threadId());
 }
 
 template <class Impl>
-void
-O3ThreadContext<Impl>::setIntReg(int reg_idx, uint64_t val)
+const TheISA::VecElem&
+O3ThreadContext<Impl>::readVecElemFlat(const RegIndex& idx,
+                                           const ElemIndex& elemIndex) const
 {
-    reg_idx = TheISA::flattenIntIndex(this, reg_idx);
-    cpu->setArchIntReg(reg_idx, val, thread->readTid());
+    return cpu->readArchVecElem(idx, elemIndex, thread->threadId());
+}
 
-    // Squash if we're not already in a state update mode.
-    if (!thread->trapPending && !thread->inSyscall) {
-        cpu->squashFromTC(thread->readTid());
-    }
+template <class Impl>
+TheISA::CCReg
+O3ThreadContext<Impl>::readCCRegFlat(int reg_idx)
+{
+    return cpu->readArchCCReg(reg_idx, thread->threadId());
 }
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val, int width)
+O3ThreadContext<Impl>::setIntRegFlat(int reg_idx, uint64_t val)
 {
-    switch(width) {
-      case 32:
-        cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid());
-        break;
-      case 64:
-        cpu->setArchFloatRegDouble(reg_idx, val, thread->readTid());
-        break;
-    }
+    cpu->setArchIntReg(reg_idx, val, thread->threadId());
 
-    // Squash if we're not already in a state update mode.
-    if (!thread->trapPending && !thread->inSyscall) {
-        cpu->squashFromTC(thread->readTid());
-    }
+    conditionalSquash();
 }
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val)
+O3ThreadContext<Impl>::setFloatRegFlat(int reg_idx, FloatReg val)
 {
-    cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid());
+    cpu->setArchFloatReg(reg_idx, val, thread->threadId());
 
-    if (!thread->trapPending && !thread->inSyscall) {
-        cpu->squashFromTC(thread->readTid());
-    }
+    conditionalSquash();
 }
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val,
-                                             int width)
+O3ThreadContext<Impl>::setFloatRegBitsFlat(int reg_idx, FloatRegBits val)
 {
-    DPRINTF(Fault, "Setting floatint register through the TC!\n");
-    cpu->setArchFloatRegInt(reg_idx, val, thread->readTid());
+    cpu->setArchFloatRegInt(reg_idx, val, thread->threadId());
 
-    // Squash if we're not already in a state update mode.
-    if (!thread->trapPending && !thread->inSyscall) {
-        cpu->squashFromTC(thread->readTid());
-    }
+    conditionalSquash();
 }
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
+O3ThreadContext<Impl>::setVecRegFlat(int reg_idx, const VecRegContainer& val)
 {
-    cpu->setArchFloatRegInt(reg_idx, val, thread->readTid());
+    cpu->setArchVecReg(reg_idx, val, thread->threadId());
 
-    // Squash if we're not already in a state update mode.
-    if (!thread->trapPending && !thread->inSyscall) {
-        cpu->squashFromTC(thread->readTid());
-    }
+    conditionalSquash();
 }
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setPC(uint64_t val)
+O3ThreadContext<Impl>::setVecElemFlat(const RegIndex& idx,
+        const ElemIndex& elemIndex, const VecElem& val)
 {
-    cpu->setPC(val, thread->readTid());
-
-    // Squash if we're not already in a state update mode.
-    if (!thread->trapPending && !thread->inSyscall) {
-        cpu->squashFromTC(thread->readTid());
-    }
+    cpu->setArchVecElem(idx, elemIndex, val, thread->threadId());
+    conditionalSquash();
 }
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setNextPC(uint64_t val)
+O3ThreadContext<Impl>::setCCRegFlat(int reg_idx, TheISA::CCReg val)
 {
-    cpu->setNextPC(val, thread->readTid());
+    cpu->setArchCCReg(reg_idx, val, thread->threadId());
 
-    // Squash if we're not already in a state update mode.
-    if (!thread->trapPending && !thread->inSyscall) {
-        cpu->squashFromTC(thread->readTid());
-    }
+    conditionalSquash();
 }
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
+O3ThreadContext<Impl>::pcState(const TheISA::PCState &val)
 {
-    cpu->setMiscRegNoEffect(misc_reg, val, thread->readTid());
+    cpu->pcState(val, thread->threadId());
 
-    // Squash if we're not already in a state update mode.
-    if (!thread->trapPending && !thread->inSyscall) {
-        cpu->squashFromTC(thread->readTid());
-    }
+    conditionalSquash();
 }
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setMiscReg(int misc_reg,
-                                                const MiscReg &val)
+O3ThreadContext<Impl>::pcStateNoRecord(const TheISA::PCState &val)
 {
-    cpu->setMiscReg(misc_reg, val, thread->readTid());
+    cpu->pcState(val, thread->threadId());
 
-    // Squash if we're not already in a state update mode.
-    if (!thread->trapPending && !thread->inSyscall) {
-        cpu->squashFromTC(thread->readTid());
-    }
+    conditionalSquash();
 }
 
-#if !FULL_SYSTEM
-
 template <class Impl>
-TheISA::IntReg
-O3ThreadContext<Impl>::getSyscallArg(int i)
+RegId
+O3ThreadContext<Impl>::flattenRegId(const RegId& regId) const
 {
-    return cpu->getSyscallArg(i, thread->readTid());
+    return cpu->isa[thread->threadId()]->flattenRegId(regId);
 }
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setSyscallArg(int i, IntReg val)
+O3ThreadContext<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
 {
-    cpu->setSyscallArg(i, val, thread->readTid());
+    cpu->setMiscRegNoEffect(misc_reg, val, thread->threadId());
+
+    conditionalSquash();
 }
 
+#endif//__CPU_O3_THREAD_CONTEXT_IMPL_HH__
 template <class Impl>
 void
-O3ThreadContext<Impl>::setSyscallReturn(SyscallReturn return_value)
+O3ThreadContext<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
 {
-    cpu->setSyscallReturn(return_value, thread->readTid());
-}
+    cpu->setMiscReg(misc_reg, val, thread->threadId());
 
-#endif // FULL_SYSTEM
+    conditionalSquash();
+}