arch,cpu: Stop using TheISA::Decoder in most places.
The only places that still use that indirection are where the decoder itself is instantiated with "new". Also, add an "as" method which makes casting to an ISA specific decoder type easier and less error prone. Change-Id: Ib4a9cce7f96da2a9a8fe19113628694904893b17 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/52079 Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Maintainer: Gabe Black <gabe.black@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -211,7 +211,7 @@ class ThreadContext : public gem5::ThreadContext
|
||||
}
|
||||
|
||||
CheckerCPU *getCheckerCpuPtr() override { return nullptr; }
|
||||
ArmISA::Decoder *
|
||||
InstDecoder *
|
||||
getDecoderPtr() override
|
||||
{
|
||||
panic("%s not implemented.", __FUNCTION__);
|
||||
|
||||
@@ -964,7 +964,8 @@ ISA::setMiscReg(int misc_reg, RegVal val)
|
||||
pc.illegalExec(cpsr.il == 1);
|
||||
selfDebug->setDebugMask(cpsr.d == 1);
|
||||
|
||||
tc->getDecoderPtr()->setSveLen((getCurSveVecLenInBits() >> 7) - 1);
|
||||
tc->getDecoderPtr()->as<Decoder>().setSveLen(
|
||||
(getCurSveVecLenInBits() >> 7) - 1);
|
||||
|
||||
// Follow slightly different semantics if a CheckerCPU object
|
||||
// is connected
|
||||
@@ -1130,7 +1131,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
|
||||
newVal = (newVal & (uint32_t)fpscrMask) |
|
||||
(readMiscRegNoEffect(MISCREG_FPSCR) &
|
||||
~(uint32_t)fpscrMask);
|
||||
tc->getDecoderPtr()->setContext(newVal);
|
||||
tc->getDecoderPtr()->as<Decoder>().setContext(newVal);
|
||||
}
|
||||
break;
|
||||
case MISCREG_FPSR:
|
||||
@@ -2492,7 +2493,8 @@ ISA::setMiscReg(int misc_reg, RegVal val)
|
||||
case MISCREG_ZCR_EL3:
|
||||
case MISCREG_ZCR_EL2:
|
||||
case MISCREG_ZCR_EL1:
|
||||
tc->getDecoderPtr()->setSveLen((getCurSveVecLenInBits() >> 7) - 1);
|
||||
tc->getDecoderPtr()->as<Decoder>().setSveLen(
|
||||
(getCurSveVecLenInBits() >> 7) - 1);
|
||||
break;
|
||||
}
|
||||
setMiscRegNoEffect(misc_reg, newVal);
|
||||
|
||||
@@ -63,6 +63,20 @@ class InstDecoder
|
||||
outOfBytes = true;
|
||||
}
|
||||
|
||||
template <class Type>
|
||||
Type &
|
||||
as()
|
||||
{
|
||||
return *static_cast<Type *>(this);
|
||||
}
|
||||
|
||||
template <class Type>
|
||||
const Type &
|
||||
as() const
|
||||
{
|
||||
return *static_cast<const Type *>(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take over the state from an old decoder when switching CPUs.
|
||||
*
|
||||
|
||||
@@ -749,7 +749,7 @@ ISA::setMiscReg(int miscReg, RegVal val)
|
||||
|
||||
switch (miscReg) {
|
||||
case MISCREG_ASI:
|
||||
tc->getDecoderPtr()->setContext(val);
|
||||
tc->getDecoderPtr()->as<Decoder>().setContext(val);
|
||||
break;
|
||||
case MISCREG_STICK:
|
||||
case MISCREG_TICK:
|
||||
|
||||
@@ -103,7 +103,7 @@ ISA::updateHandyM5Reg(Efer efer, CR0 cr0,
|
||||
|
||||
regVal[MISCREG_M5_REG] = m5reg;
|
||||
if (tc)
|
||||
tc->getDecoderPtr()->setM5Reg(m5reg);
|
||||
tc->getDecoderPtr()->as<Decoder>().setM5Reg(m5reg);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -479,7 +479,7 @@ void
|
||||
ISA::setThreadContext(ThreadContext *_tc)
|
||||
{
|
||||
BaseISA::setThreadContext(_tc);
|
||||
tc->getDecoderPtr()->setM5Reg(regVal[MISCREG_M5_REG]);
|
||||
tc->getDecoderPtr()->as<Decoder>().setM5Reg(regVal[MISCREG_M5_REG]);
|
||||
}
|
||||
|
||||
std::string
|
||||
|
||||
@@ -69,7 +69,7 @@ Checker<DynInstPtr>::advancePC(const Fault &fault)
|
||||
if (fault != NoFault) {
|
||||
curMacroStaticInst = nullStaticInstPtr;
|
||||
fault->invoke(tc, curStaticInst);
|
||||
thread->decoder.reset();
|
||||
thread->decoder->reset();
|
||||
} else {
|
||||
if (curStaticInst) {
|
||||
if (curStaticInst->isLastMicroop())
|
||||
@@ -111,7 +111,7 @@ Checker<DynInstPtr>::handlePendingInt()
|
||||
"a non-interuptable instruction!", curTick());
|
||||
}
|
||||
boundaryInst = NULL;
|
||||
thread->decoder.reset();
|
||||
thread->decoder->reset();
|
||||
curMacroStaticInst = nullStaticInstPtr;
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ Checker<DynInstPtr>::verify(const DynInstPtr &completed_inst)
|
||||
inst = NULL;
|
||||
|
||||
auto &decoder = thread->decoder;
|
||||
const Addr pc_mask = decoder.pcMask();
|
||||
const Addr pc_mask = decoder->pcMask();
|
||||
|
||||
// Try to check all instructions that are completed, ending if we
|
||||
// run out of instructions to check or if an instruction is not
|
||||
@@ -235,10 +235,10 @@ Checker<DynInstPtr>::verify(const DynInstPtr &completed_inst)
|
||||
if (!curMacroStaticInst) {
|
||||
// set up memory request for instruction fetch
|
||||
auto mem_req = std::make_shared<Request>(
|
||||
fetch_PC, decoder.moreBytesSize(), 0, requestorId,
|
||||
fetch_PC, decoder->moreBytesSize(), 0, requestorId,
|
||||
fetch_PC, thread->contextId());
|
||||
|
||||
mem_req->setVirt(fetch_PC, decoder.moreBytesSize(),
|
||||
mem_req->setVirt(fetch_PC, decoder->moreBytesSize(),
|
||||
Request::INST_FETCH, requestorId,
|
||||
thread->pcState().instAddr());
|
||||
|
||||
@@ -272,7 +272,7 @@ Checker<DynInstPtr>::verify(const DynInstPtr &completed_inst)
|
||||
} else {
|
||||
PacketPtr pkt = new Packet(mem_req, MemCmd::ReadReq);
|
||||
|
||||
pkt->dataStatic(decoder.moreBytesPtr());
|
||||
pkt->dataStatic(decoder->moreBytesPtr());
|
||||
icachePort->sendFunctional(pkt);
|
||||
|
||||
delete pkt;
|
||||
@@ -285,7 +285,7 @@ Checker<DynInstPtr>::verify(const DynInstPtr &completed_inst)
|
||||
|
||||
if (isRomMicroPC(pc_state->microPC())) {
|
||||
fetchDone = true;
|
||||
curStaticInst = decoder.fetchRomMicroop(
|
||||
curStaticInst = decoder->fetchRomMicroop(
|
||||
pc_state->microPC(), nullptr);
|
||||
} else if (!curMacroStaticInst) {
|
||||
//We're not in the middle of a macro instruction
|
||||
@@ -295,18 +295,18 @@ Checker<DynInstPtr>::verify(const DynInstPtr &completed_inst)
|
||||
//If more fetch data is needed, pass it in.
|
||||
Addr fetch_pc =
|
||||
(pc_state->instAddr() & pc_mask) + fetchOffset;
|
||||
decoder.moreBytes(*pc_state, fetch_pc);
|
||||
decoder->moreBytes(*pc_state, fetch_pc);
|
||||
|
||||
//If an instruction is ready, decode it.
|
||||
//Otherwise, we'll have to fetch beyond the
|
||||
//memory chunk at the current pc.
|
||||
if (decoder.instReady()) {
|
||||
if (decoder->instReady()) {
|
||||
fetchDone = true;
|
||||
instPtr = decoder.decode(*pc_state);
|
||||
instPtr = decoder->decode(*pc_state);
|
||||
thread->pcState(*pc_state);
|
||||
} else {
|
||||
fetchDone = false;
|
||||
fetchOffset += decoder.moreBytesSize();
|
||||
fetchOffset += decoder->moreBytesSize();
|
||||
}
|
||||
|
||||
//If we decoded an instruction and it's microcoded,
|
||||
@@ -327,7 +327,7 @@ Checker<DynInstPtr>::verify(const DynInstPtr &completed_inst)
|
||||
}
|
||||
}
|
||||
// reset decoder on Checker
|
||||
decoder.reset();
|
||||
decoder->reset();
|
||||
|
||||
// Check Checker and CPU get same instruction, and record
|
||||
// any faults the CPU may have had.
|
||||
|
||||
@@ -155,7 +155,7 @@ class CheckerThreadContext : public ThreadContext
|
||||
|
||||
BaseISA *getIsaPtr() override { return actualTC->getIsaPtr(); }
|
||||
|
||||
TheISA::Decoder *
|
||||
InstDecoder *
|
||||
getDecoderPtr() override
|
||||
{
|
||||
return actualTC->getDecoderPtr();
|
||||
|
||||
@@ -98,7 +98,7 @@ Fetch1::Fetch1(const std::string &name_,
|
||||
maxLineWidth);
|
||||
}
|
||||
|
||||
size_t inst_size = cpu.threads[0]->decoder.moreBytesSize();
|
||||
size_t inst_size = cpu.threads[0]->decoder->moreBytesSize();
|
||||
|
||||
/* These assertions should be copied to the Python config. as well */
|
||||
if ((lineSnap % inst_size) != 0) {
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "arch/decoder.hh"
|
||||
#include "arch/generic/decoder.hh"
|
||||
#include "base/logging.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/minor/pipeline.hh"
|
||||
@@ -313,7 +313,7 @@ Fetch2::evaluate()
|
||||
prediction.isBubble() /* No predicted branch */)
|
||||
{
|
||||
ThreadContext *thread = cpu.getContext(line_in->id.threadId);
|
||||
TheISA::Decoder *decoder = thread->getDecoderPtr();
|
||||
InstDecoder *decoder = thread->getDecoderPtr();
|
||||
|
||||
/* Discard line due to prediction sequence number being wrong but
|
||||
* without the streamSeqNum number having changed */
|
||||
|
||||
@@ -356,7 +356,7 @@ class Fetch
|
||||
}
|
||||
|
||||
/** The decoder. */
|
||||
TheISA::Decoder *decoder[MaxThreads];
|
||||
InstDecoder *decoder[MaxThreads];
|
||||
|
||||
RequestPort &getInstPort() { return icachePort; }
|
||||
|
||||
|
||||
@@ -58,8 +58,8 @@ ThreadContext::takeOverFrom(gem5::ThreadContext *old_context)
|
||||
|
||||
getIsaPtr()->takeOverFrom(this, old_context);
|
||||
|
||||
TheISA::Decoder *newDecoder = getDecoderPtr();
|
||||
TheISA::Decoder *oldDecoder = old_context->getDecoderPtr();
|
||||
InstDecoder *newDecoder = getDecoderPtr();
|
||||
InstDecoder *oldDecoder = old_context->getDecoderPtr();
|
||||
newDecoder->takeOverFrom(oldDecoder);
|
||||
|
||||
thread->noSquashFromTC = false;
|
||||
|
||||
@@ -112,7 +112,7 @@ class ThreadContext : public gem5::ThreadContext
|
||||
return cpu->isa[thread->threadId()];
|
||||
}
|
||||
|
||||
TheISA::Decoder *
|
||||
InstDecoder *
|
||||
getDecoderPtr() override
|
||||
{
|
||||
return cpu->fetch.decoder[thread->threadId()];
|
||||
|
||||
@@ -748,7 +748,7 @@ AtomicSimpleCPU::fetchInstMem()
|
||||
|
||||
// ifetch_req is initialized to read the instruction
|
||||
// directly into the CPU object's inst field.
|
||||
pkt.dataStatic(decoder.moreBytesPtr());
|
||||
pkt.dataStatic(decoder->moreBytesPtr());
|
||||
|
||||
Tick latency = sendPacket(icachePort, &pkt);
|
||||
assert(!pkt.isError());
|
||||
|
||||
@@ -269,7 +269,7 @@ BaseSimpleCPU::checkForInterrupts()
|
||||
t_info.fetchOffset = 0;
|
||||
interrupts[curThread]->updateIntrInfo();
|
||||
interrupt->invoke(tc);
|
||||
thread->decoder.reset();
|
||||
thread->decoder->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -283,12 +283,12 @@ BaseSimpleCPU::setupFetchRequest(const RequestPtr &req)
|
||||
|
||||
auto &decoder = thread->decoder;
|
||||
Addr instAddr = thread->pcState().instAddr();
|
||||
Addr fetchPC = (instAddr & decoder.pcMask()) + t_info.fetchOffset;
|
||||
Addr fetchPC = (instAddr & decoder->pcMask()) + t_info.fetchOffset;
|
||||
|
||||
// set up memory request for instruction fetch
|
||||
DPRINTF(Fetch, "Fetch: Inst PC:%08p, Fetch PC:%08p\n", instAddr, fetchPC);
|
||||
|
||||
req->setVirt(fetchPC, decoder.moreBytesSize(), Request::INST_FETCH,
|
||||
req->setVirt(fetchPC, decoder->moreBytesSize(), Request::INST_FETCH,
|
||||
instRequestorId(), instAddr);
|
||||
}
|
||||
|
||||
@@ -320,7 +320,7 @@ BaseSimpleCPU::preExecute()
|
||||
|
||||
if (isRomMicroPC(pc_state.microPC())) {
|
||||
t_info.stayAtPC = false;
|
||||
curStaticInst = decoder.fetchRomMicroop(
|
||||
curStaticInst = decoder->fetchRomMicroop(
|
||||
pc_state.microPC(), curMacroStaticInst);
|
||||
} else if (!curMacroStaticInst) {
|
||||
//We're not in the middle of a macro instruction
|
||||
@@ -329,19 +329,19 @@ BaseSimpleCPU::preExecute()
|
||||
//Predecode, ie bundle up an ExtMachInst
|
||||
//If more fetch data is needed, pass it in.
|
||||
Addr fetch_pc =
|
||||
(pc_state.instAddr() & decoder.pcMask()) + t_info.fetchOffset;
|
||||
(pc_state.instAddr() & decoder->pcMask()) + t_info.fetchOffset;
|
||||
|
||||
decoder.moreBytes(pc_state, fetch_pc);
|
||||
decoder->moreBytes(pc_state, fetch_pc);
|
||||
|
||||
//Decode an instruction if one is ready. Otherwise, we'll have to
|
||||
//fetch beyond the MachInst at the current pc.
|
||||
instPtr = decoder.decode(pc_state);
|
||||
instPtr = decoder->decode(pc_state);
|
||||
if (instPtr) {
|
||||
t_info.stayAtPC = false;
|
||||
thread->pcState(pc_state);
|
||||
} else {
|
||||
t_info.stayAtPC = true;
|
||||
t_info.fetchOffset += decoder.moreBytesSize();
|
||||
t_info.fetchOffset += decoder->moreBytesSize();
|
||||
}
|
||||
|
||||
//If we decoded an instruction and it's microcoded, start pulling
|
||||
@@ -469,7 +469,7 @@ BaseSimpleCPU::advancePC(const Fault &fault)
|
||||
if (fault != NoFault) {
|
||||
curMacroStaticInst = nullStaticInstPtr;
|
||||
fault->invoke(threadContexts[curThread], curStaticInst);
|
||||
thread->decoder.reset();
|
||||
thread->decoder->reset();
|
||||
} else {
|
||||
if (curStaticInst) {
|
||||
if (curStaticInst->isLastMicroop())
|
||||
|
||||
@@ -95,7 +95,7 @@ NonCachingSimpleCPU::fetchInstMem()
|
||||
|
||||
auto *bd = bd_it->second;
|
||||
Addr offset = ifetch_req->getPaddr() - bd->range().start();
|
||||
memcpy(decoder.moreBytesPtr(), bd->ptr() + offset, ifetch_req->getSize());
|
||||
memcpy(decoder->moreBytesPtr(), bd->ptr() + offset, ifetch_req->getSize());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -725,7 +725,7 @@ TimingSimpleCPU::sendFetch(const Fault &fault, const RequestPtr &req,
|
||||
DPRINTF(SimpleCPU, "Sending fetch for addr %#x(pa: %#x)\n",
|
||||
req->getVaddr(), req->getPaddr());
|
||||
ifetch_pkt = new Packet(req, MemCmd::ReadReq);
|
||||
ifetch_pkt->dataStatic(decoder.moreBytesPtr());
|
||||
ifetch_pkt->dataStatic(decoder->moreBytesPtr());
|
||||
DPRINTF(SimpleCPU, " -- pkt addr: %#x\n", ifetch_pkt->getAddr());
|
||||
|
||||
if (!icachePort.sendTimingReq(ifetch_pkt)) {
|
||||
|
||||
@@ -72,7 +72,7 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
|
||||
isa(dynamic_cast<TheISA::ISA *>(_isa)),
|
||||
predicate(true), memAccPredicate(true),
|
||||
comInstEventQueue("instruction-based event queue"),
|
||||
system(_sys), mmu(_mmu), decoder(isa),
|
||||
system(_sys), mmu(_mmu), decoder(new TheISA::Decoder(isa)),
|
||||
htmTransactionStarts(0), htmTransactionStops(0)
|
||||
{
|
||||
assert(isa);
|
||||
@@ -95,7 +95,7 @@ void
|
||||
SimpleThread::takeOverFrom(ThreadContext *oldContext)
|
||||
{
|
||||
gem5::takeOverFrom(*this, *oldContext);
|
||||
decoder.takeOverFrom(oldContext->getDecoderPtr());
|
||||
decoder->takeOverFrom(oldContext->getDecoderPtr());
|
||||
|
||||
isa->takeOverFrom(this, oldContext);
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
|
||||
BaseMMU *mmu;
|
||||
|
||||
TheISA::Decoder decoder;
|
||||
InstDecoder *decoder;
|
||||
|
||||
// hardware transactional memory
|
||||
int64_t htmTransactionStarts;
|
||||
@@ -213,7 +213,7 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
|
||||
BaseISA *getIsaPtr() override { return isa; }
|
||||
|
||||
TheISA::Decoder *getDecoderPtr() override { return &decoder; }
|
||||
InstDecoder *getDecoderPtr() override { return decoder; }
|
||||
|
||||
System *getSystemPtr() override { return system; }
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ class BaseMMU;
|
||||
class BaseTLB;
|
||||
class CheckerCPU;
|
||||
class Checkpoint;
|
||||
class InstDecoder;
|
||||
class PortProxy;
|
||||
class Process;
|
||||
class System;
|
||||
@@ -143,7 +144,7 @@ class ThreadContext : public PCEventScope
|
||||
|
||||
virtual BaseISA *getIsaPtr() = 0;
|
||||
|
||||
virtual TheISA::Decoder *getDecoderPtr() = 0;
|
||||
virtual InstDecoder *getDecoderPtr() = 0;
|
||||
|
||||
virtual System *getSystemPtr() = 0;
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
#include <csignal>
|
||||
|
||||
#include "arch/decoder.hh"
|
||||
#include "arch/generic/decoder.hh"
|
||||
#include "base/logging.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
@@ -114,7 +114,7 @@ void GenericHtmFailureFault::invoke(ThreadContext *tc,
|
||||
const StaticInstPtr &inst)
|
||||
{
|
||||
// reset decoder
|
||||
TheISA::Decoder* dcdr = tc->getDecoderPtr();
|
||||
InstDecoder* dcdr = tc->getDecoderPtr();
|
||||
dcdr->reset();
|
||||
|
||||
// restore transaction checkpoint
|
||||
|
||||
Reference in New Issue
Block a user