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:
Gabe Black
2021-10-25 03:04:33 -07:00
parent 3d52a0ea97
commit 3e766837b0
20 changed files with 63 additions and 46 deletions

View File

@@ -211,7 +211,7 @@ class ThreadContext : public gem5::ThreadContext
}
CheckerCPU *getCheckerCpuPtr() override { return nullptr; }
ArmISA::Decoder *
InstDecoder *
getDecoderPtr() override
{
panic("%s not implemented.", __FUNCTION__);

View File

@@ -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);

View File

@@ -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.
*

View File

@@ -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:

View File

@@ -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

View File

@@ -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.

View File

@@ -155,7 +155,7 @@ class CheckerThreadContext : public ThreadContext
BaseISA *getIsaPtr() override { return actualTC->getIsaPtr(); }
TheISA::Decoder *
InstDecoder *
getDecoderPtr() override
{
return actualTC->getDecoderPtr();

View File

@@ -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) {

View File

@@ -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 */

View File

@@ -356,7 +356,7 @@ class Fetch
}
/** The decoder. */
TheISA::Decoder *decoder[MaxThreads];
InstDecoder *decoder[MaxThreads];
RequestPort &getInstPort() { return icachePort; }

View File

@@ -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;

View File

@@ -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()];

View File

@@ -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());

View File

@@ -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())

View File

@@ -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;
}

View File

@@ -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)) {

View File

@@ -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);

View File

@@ -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; }

View File

@@ -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;

View File

@@ -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