diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 07e0893709..b4c77180a4 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -334,15 +334,15 @@ FullO3CPU::FullO3CPU(const DerivO3CPUParams ¶ms) ThreadContext *tc; // Setup the TC that will serve as the interface to the threads/CPU. - O3ThreadContext *o3_tc = new O3ThreadContext; + O3ThreadContext *o3_tc = new O3ThreadContext; tc = o3_tc; // If we're using a checker, then the TC should be the // CheckerThreadContext. if (params.checker) { - tc = new CheckerThreadContext >( - o3_tc, this->checker); + tc = new CheckerThreadContext( + o3_tc, this->checker); } o3_tc->cpu = this; diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index ca5d7bea48..ff7e0ab66b 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -76,7 +76,6 @@ template class Checker; class ThreadContext; -template class O3ThreadContext; class Checkpoint; @@ -106,7 +105,7 @@ class FullO3CPU : public BaseO3CPU typedef typename std::list::iterator ListIt; - friend class O3ThreadContext; + friend class O3ThreadContext; public: enum Status diff --git a/src/cpu/o3/thread_context.cc b/src/cpu/o3/thread_context.cc index db071621b9..c4f53660d0 100644 --- a/src/cpu/o3/thread_context.cc +++ b/src/cpu/o3/thread_context.cc @@ -1,4 +1,17 @@ /* + * Copyright (c) 2010-2012, 2016-2017, 2019 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. * @@ -28,8 +41,277 @@ #include "cpu/o3/thread_context.hh" -#include "cpu/o3/impl.hh" -#include "cpu/o3/thread_context_impl.hh" +#include "arch/vecregs.hh" +#include "config/the_isa.hh" +#include "debug/O3CPU.hh" -template class O3ThreadContext; +PortProxy& +O3ThreadContext::getVirtProxy() +{ + return thread->getVirtProxy(); +} +void +O3ThreadContext::takeOverFrom(ThreadContext *old_context) +{ + ::takeOverFrom(*this, *old_context); + + getIsaPtr()->takeOverFrom(this, old_context); + + TheISA::Decoder *newDecoder = getDecoderPtr(); + TheISA::Decoder *oldDecoder = old_context->getDecoderPtr(); + newDecoder->takeOverFrom(oldDecoder); + + thread->funcExeInst = old_context->readFuncExeInst(); + + thread->noSquashFromTC = false; + thread->trapPending = false; +} + +void +O3ThreadContext::activate() +{ + DPRINTF(O3CPU, "Calling activate on Thread Context %d\n", + threadId()); + + if (thread->status() == ThreadContext::Active) + return; + + thread->lastActivate = curTick(); + thread->setStatus(ThreadContext::Active); + + // status() == Suspended + cpu->activateContext(thread->threadId()); +} + +void +O3ThreadContext::suspend() +{ + DPRINTF(O3CPU, "Calling suspend on Thread Context %d\n", + threadId()); + + if (thread->status() == ThreadContext::Suspended) + return; + + if (cpu->isDraining()) { + DPRINTF(O3CPU, "Ignoring suspend on TC due to pending drain\n"); + return; + } + + thread->lastActivate = curTick(); + thread->lastSuspend = curTick(); + + thread->setStatus(ThreadContext::Suspended); + cpu->suspendContext(thread->threadId()); +} + +void +O3ThreadContext::halt() +{ + DPRINTF(O3CPU, "Calling halt on Thread Context %d\n", threadId()); + + if (thread->status() == ThreadContext::Halting || + thread->status() == ThreadContext::Halted) + return; + + // the thread is not going to halt/terminate immediately in this cycle. + // The thread will be removed after an exit trap is processed + // (e.g., after trapLatency cycles). Until then, the thread's status + // will be Halting. + thread->setStatus(ThreadContext::Halting); + + // add this thread to the exiting list to mark that it is trying to exit. + cpu->addThreadToExitingList(thread->threadId()); +} + +Tick +O3ThreadContext::readLastActivate() +{ + return thread->lastActivate; +} + +Tick +O3ThreadContext::readLastSuspend() +{ + return thread->lastSuspend; +} + +void +O3ThreadContext::copyArchRegs(ThreadContext *tc) +{ + // Set vector renaming mode before copying registers + cpu->vecRenameMode(tc->getIsaPtr()->vecRegRenameMode(tc)); + + // Prevent squashing + thread->noSquashFromTC = true; + getIsaPtr()->copyRegsFrom(tc); + thread->noSquashFromTC = false; + + if (!FullSystem) + thread->funcExeInst = tc->readFuncExeInst(); +} + +void +O3ThreadContext::clearArchRegs() +{ + cpu->isa[thread->threadId()]->clear(); +} + +RegVal +O3ThreadContext::readIntRegFlat(RegIndex reg_idx) const +{ + return cpu->readArchIntReg(reg_idx, thread->threadId()); +} + +RegVal +O3ThreadContext::readFloatRegFlat(RegIndex reg_idx) const +{ + return cpu->readArchFloatReg(reg_idx, thread->threadId()); +} + +const TheISA::VecRegContainer& +O3ThreadContext::readVecRegFlat(RegIndex reg_id) const +{ + return cpu->readArchVecReg(reg_id, thread->threadId()); +} + +TheISA::VecRegContainer& +O3ThreadContext::getWritableVecRegFlat(RegIndex reg_id) +{ + return cpu->getWritableArchVecReg(reg_id, thread->threadId()); +} + +const TheISA::VecElem& +O3ThreadContext::readVecElemFlat(RegIndex idx, + const ElemIndex& elemIndex) const +{ + return cpu->readArchVecElem(idx, elemIndex, thread->threadId()); +} + +const TheISA::VecPredRegContainer& +O3ThreadContext::readVecPredRegFlat(RegIndex reg_id) const +{ + return cpu->readArchVecPredReg(reg_id, thread->threadId()); +} + +TheISA::VecPredRegContainer& +O3ThreadContext::getWritableVecPredRegFlat(RegIndex reg_id) +{ + return cpu->getWritableArchVecPredReg(reg_id, thread->threadId()); +} + +RegVal +O3ThreadContext::readCCRegFlat(RegIndex reg_idx) const +{ + return cpu->readArchCCReg(reg_idx, thread->threadId()); +} + +void +O3ThreadContext::setIntRegFlat(RegIndex reg_idx, RegVal val) +{ + cpu->setArchIntReg(reg_idx, val, thread->threadId()); + + conditionalSquash(); +} + +void +O3ThreadContext::setFloatRegFlat(RegIndex reg_idx, RegVal val) +{ + cpu->setArchFloatReg(reg_idx, val, thread->threadId()); + + conditionalSquash(); +} + +void +O3ThreadContext::setVecRegFlat( + RegIndex reg_idx, const TheISA::VecRegContainer& val) +{ + cpu->setArchVecReg(reg_idx, val, thread->threadId()); + + conditionalSquash(); +} + +void +O3ThreadContext::setVecElemFlat(RegIndex idx, + const ElemIndex& elemIndex, const TheISA::VecElem& val) +{ + cpu->setArchVecElem(idx, elemIndex, val, thread->threadId()); + conditionalSquash(); +} + +void +O3ThreadContext::setVecPredRegFlat(RegIndex reg_idx, + const TheISA::VecPredRegContainer& val) +{ + cpu->setArchVecPredReg(reg_idx, val, thread->threadId()); + + conditionalSquash(); +} + +void +O3ThreadContext::setCCRegFlat(RegIndex reg_idx, RegVal val) +{ + cpu->setArchCCReg(reg_idx, val, thread->threadId()); + + conditionalSquash(); +} + +void +O3ThreadContext::pcState(const TheISA::PCState &val) +{ + cpu->pcState(val, thread->threadId()); + + conditionalSquash(); +} + +void +O3ThreadContext::pcStateNoRecord(const TheISA::PCState &val) +{ + cpu->pcState(val, thread->threadId()); + + conditionalSquash(); +} + +RegId +O3ThreadContext::flattenRegId(const RegId& regId) const +{ + return cpu->isa[thread->threadId()]->flattenRegId(regId); +} + +void +O3ThreadContext::setMiscRegNoEffect(RegIndex misc_reg, RegVal val) +{ + cpu->setMiscRegNoEffect(misc_reg, val, thread->threadId()); + + conditionalSquash(); +} + +void +O3ThreadContext::setMiscReg(RegIndex misc_reg, RegVal val) +{ + cpu->setMiscReg(misc_reg, val, thread->threadId()); + + conditionalSquash(); +} + +// hardware transactional memory +void +O3ThreadContext::htmAbortTransaction(uint64_t htmUid, + HtmFailureFaultCause cause) +{ + cpu->htmSendAbortSignal(thread->threadId(), htmUid, cause); + + conditionalSquash(); +} + +BaseHTMCheckpointPtr& +O3ThreadContext::getHtmCheckpointPtr() +{ + return thread->htmCheckpoint; +} + +void +O3ThreadContext::setHtmCheckpointPtr(BaseHTMCheckpointPtr new_cpt) +{ + thread->htmCheckpoint = std::move(new_cpt); +} diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index 5a63641aa5..99ba67a7b4 100644 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -43,6 +43,7 @@ #define __CPU_O3_THREAD_CONTEXT_HH__ #include "config/the_isa.hh" +#include "cpu/o3/impl.hh" #include "cpu/o3/isa_specific.hh" #include "cpu/thread_context.hh" @@ -59,12 +60,11 @@ * must be taken when using this interface (such as squashing all * in-flight instructions when doing a write to this interface). */ -template class O3ThreadContext : public ThreadContext { public: /** Pointer to the CPU. */ - FullO3CPU *cpu; + FullO3CPU *cpu; bool schedule(PCEvent *e) override @@ -94,7 +94,7 @@ class O3ThreadContext : public ThreadContext } /** Pointer to the thread state that this TC corrseponds to. */ - O3ThreadState *thread; + O3ThreadState *thread; /** Returns a pointer to the MMU. */ BaseMMU *getMMUPtr() override { return cpu->mmu; } @@ -361,7 +361,7 @@ class O3ThreadContext : public ThreadContext * similar is currently writing to the thread context and doesn't want * reset all the state (see noSquashFromTC). */ - inline void + void conditionalSquash() { if (!thread->trapPending && !thread->noSquashFromTC) diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh deleted file mode 100644 index c3a6b52af0..0000000000 --- a/src/cpu/o3/thread_context_impl.hh +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2010-2012, 2016-2017, 2019 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. - * - * 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. - */ - -#ifndef __CPU_O3_THREAD_CONTEXT_IMPL_HH__ -#define __CPU_O3_THREAD_CONTEXT_IMPL_HH__ - -#include "arch/vecregs.hh" -#include "config/the_isa.hh" -#include "cpu/o3/thread_context.hh" -#include "debug/O3CPU.hh" - -template -PortProxy& -O3ThreadContext::getVirtProxy() -{ - return thread->getVirtProxy(); -} - -template -void -O3ThreadContext::takeOverFrom(ThreadContext *old_context) -{ - ::takeOverFrom(*this, *old_context); - - this->getIsaPtr()->takeOverFrom(this, old_context); - - TheISA::Decoder *newDecoder = getDecoderPtr(); - TheISA::Decoder *oldDecoder = old_context->getDecoderPtr(); - newDecoder->takeOverFrom(oldDecoder); - - thread->funcExeInst = old_context->readFuncExeInst(); - - thread->noSquashFromTC = false; - thread->trapPending = false; -} - -template -void -O3ThreadContext::activate() -{ - DPRINTF(O3CPU, "Calling activate on Thread Context %d\n", - threadId()); - - if (thread->status() == ThreadContext::Active) - return; - - thread->lastActivate = curTick(); - thread->setStatus(ThreadContext::Active); - - // status() == Suspended - cpu->activateContext(thread->threadId()); -} - -template -void -O3ThreadContext::suspend() -{ - DPRINTF(O3CPU, "Calling suspend on Thread Context %d\n", - threadId()); - - if (thread->status() == ThreadContext::Suspended) - return; - - if (cpu->isDraining()) { - DPRINTF(O3CPU, "Ignoring suspend on TC due to pending drain\n"); - return; - } - - thread->lastActivate = curTick(); - thread->lastSuspend = curTick(); - - thread->setStatus(ThreadContext::Suspended); - cpu->suspendContext(thread->threadId()); -} - -template -void -O3ThreadContext::halt() -{ - DPRINTF(O3CPU, "Calling halt on Thread Context %d\n", threadId()); - - if (thread->status() == ThreadContext::Halting || - thread->status() == ThreadContext::Halted) - return; - - // the thread is not going to halt/terminate immediately in this cycle. - // The thread will be removed after an exit trap is processed - // (e.g., after trapLatency cycles). Until then, the thread's status - // will be Halting. - thread->setStatus(ThreadContext::Halting); - - // add this thread to the exiting list to mark that it is trying to exit. - cpu->addThreadToExitingList(thread->threadId()); -} - -template -Tick -O3ThreadContext::readLastActivate() -{ - return thread->lastActivate; -} - -template -Tick -O3ThreadContext::readLastSuspend() -{ - return thread->lastSuspend; -} - -template -void -O3ThreadContext::copyArchRegs(ThreadContext *tc) -{ - // Set vector renaming mode before copying registers - cpu->vecRenameMode(tc->getIsaPtr()->vecRegRenameMode(tc)); - - // Prevent squashing - thread->noSquashFromTC = true; - getIsaPtr()->copyRegsFrom(tc); - thread->noSquashFromTC = false; - - if (!FullSystem) - this->thread->funcExeInst = tc->readFuncExeInst(); -} - -template -void -O3ThreadContext::clearArchRegs() -{ - cpu->isa[thread->threadId()]->clear(); -} - -template -RegVal -O3ThreadContext::readIntRegFlat(RegIndex reg_idx) const -{ - return cpu->readArchIntReg(reg_idx, thread->threadId()); -} - -template -RegVal -O3ThreadContext::readFloatRegFlat(RegIndex reg_idx) const -{ - return cpu->readArchFloatReg(reg_idx, thread->threadId()); -} - -template -const TheISA::VecRegContainer& -O3ThreadContext::readVecRegFlat(RegIndex reg_id) const -{ - return cpu->readArchVecReg(reg_id, thread->threadId()); -} - -template -TheISA::VecRegContainer& -O3ThreadContext::getWritableVecRegFlat(RegIndex reg_id) -{ - return cpu->getWritableArchVecReg(reg_id, thread->threadId()); -} - -template -const TheISA::VecElem& -O3ThreadContext::readVecElemFlat(RegIndex idx, - const ElemIndex& elemIndex) const -{ - return cpu->readArchVecElem(idx, elemIndex, thread->threadId()); -} - -template -const TheISA::VecPredRegContainer& -O3ThreadContext::readVecPredRegFlat(RegIndex reg_id) const -{ - return cpu->readArchVecPredReg(reg_id, thread->threadId()); -} - -template -TheISA::VecPredRegContainer& -O3ThreadContext::getWritableVecPredRegFlat(RegIndex reg_id) -{ - return cpu->getWritableArchVecPredReg(reg_id, thread->threadId()); -} - -template -RegVal -O3ThreadContext::readCCRegFlat(RegIndex reg_idx) const -{ - return cpu->readArchCCReg(reg_idx, thread->threadId()); -} - -template -void -O3ThreadContext::setIntRegFlat(RegIndex reg_idx, RegVal val) -{ - cpu->setArchIntReg(reg_idx, val, thread->threadId()); - - conditionalSquash(); -} - -template -void -O3ThreadContext::setFloatRegFlat(RegIndex reg_idx, RegVal val) -{ - cpu->setArchFloatReg(reg_idx, val, thread->threadId()); - - conditionalSquash(); -} - -template -void -O3ThreadContext::setVecRegFlat( - RegIndex reg_idx, const TheISA::VecRegContainer& val) -{ - cpu->setArchVecReg(reg_idx, val, thread->threadId()); - - conditionalSquash(); -} - -template -void -O3ThreadContext::setVecElemFlat(RegIndex idx, - const ElemIndex& elemIndex, const TheISA::VecElem& val) -{ - cpu->setArchVecElem(idx, elemIndex, val, thread->threadId()); - conditionalSquash(); -} - -template -void -O3ThreadContext::setVecPredRegFlat(RegIndex reg_idx, - const TheISA::VecPredRegContainer& val) -{ - cpu->setArchVecPredReg(reg_idx, val, thread->threadId()); - - conditionalSquash(); -} - -template -void -O3ThreadContext::setCCRegFlat(RegIndex reg_idx, RegVal val) -{ - cpu->setArchCCReg(reg_idx, val, thread->threadId()); - - conditionalSquash(); -} - -template -void -O3ThreadContext::pcState(const TheISA::PCState &val) -{ - cpu->pcState(val, thread->threadId()); - - conditionalSquash(); -} - -template -void -O3ThreadContext::pcStateNoRecord(const TheISA::PCState &val) -{ - cpu->pcState(val, thread->threadId()); - - conditionalSquash(); -} - -template -RegId -O3ThreadContext::flattenRegId(const RegId& regId) const -{ - return cpu->isa[thread->threadId()]->flattenRegId(regId); -} - -template -void -O3ThreadContext::setMiscRegNoEffect(RegIndex misc_reg, RegVal val) -{ - cpu->setMiscRegNoEffect(misc_reg, val, thread->threadId()); - - conditionalSquash(); -} - -template -void -O3ThreadContext::setMiscReg(RegIndex misc_reg, RegVal val) -{ - cpu->setMiscReg(misc_reg, val, thread->threadId()); - - conditionalSquash(); -} - -// hardware transactional memory -template -void -O3ThreadContext::htmAbortTransaction(uint64_t htmUid, - HtmFailureFaultCause cause) -{ - cpu->htmSendAbortSignal(thread->threadId(), htmUid, cause); - - conditionalSquash(); -} - -template -BaseHTMCheckpointPtr& -O3ThreadContext::getHtmCheckpointPtr() -{ - return thread->htmCheckpoint; -} - -template -void -O3ThreadContext::setHtmCheckpointPtr(BaseHTMCheckpointPtr new_cpt) -{ - thread->htmCheckpoint = std::move(new_cpt); -} - -#endif //__CPU_O3_THREAD_CONTEXT_IMPL_HH__