arch: Add instruction size and PC set methods (#357)

Add the instruction size of a static instruction. x86 and arm decoders
add now the instruction size to the macro instruction. However, microops
are still handled by the fetch stage which is not nice.
Furthermore, we add a set method to the PC state. It allows setting a PC
state to acertain address.
Both methods are required for the decoupled front-end.

Change-Id: I311fe3f637e867c42dee7781f5373ea2e69e2072
This commit is contained in:
Andreas Sandberg
2023-10-04 10:49:30 +01:00
committed by GitHub
8 changed files with 69 additions and 5 deletions

View File

@@ -138,6 +138,7 @@ class Decoder : public InstDecoder
StaticInstPtr si = defaultCache.decode(this, mach_inst, addr);
DPRINTF(Decode, "Decode: Decoded %s instruction: %#x\n",
si->getName(), mach_inst);
si->size((!emi.thumb || emi.bigThumb) ? 4 : 2);
return si;
}

View File

@@ -378,6 +378,15 @@ class PredMacroOp : public PredOp
std::string generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const override;
void size(size_t newSize) override
{
for (int i = 0; i < numMicroops; i++) {
microOps[i]->size(newSize);
}
_size = newSize;
}
};
/**

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2020 ARM Limited
* Copyright (c) 2023 The University of Edinburgh
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -126,6 +127,13 @@ class PCStateBase : public Serializable
_upc = 0;
}
virtual void
set(Addr val)
{
_pc = val;
_upc = 0;
}
virtual void advance() = 0;
virtual bool branching() const = 0;
@@ -309,6 +317,14 @@ class PCStateWithNext : public PCStateBase
_npc == ps._npc && _nupc == ps._nupc;
}
void
set(Addr val) override
{
PCStateBase::set(val);
_npc = 0;
_nupc = 1;
}
void
serialize(CheckpointOut &cp) const override
{
@@ -359,9 +375,9 @@ class SimplePCState : public PCStateWithNext
* @param val The value to set the PC to.
*/
void
set(Addr val)
set(Addr val) override
{
this->pc(val);
Base::set(val);
this->npc(val + InstWidth);
};
@@ -402,7 +418,7 @@ class UPCState : public SimplePCState<InstWidth>
}
void
set(Addr val)
set(Addr val) override
{
Base::set(val);
this->upc(0);

View File

@@ -96,6 +96,8 @@ Decoder::decode(ExtMachInst mach_inst, Addr addr)
if (!si)
si = decodeInst(mach_inst);
si->size(compressed(mach_inst) ? 2 : 4);
DPRINTF(Decode, "Decode: Decoded %s instruction: %#x\n",
si->getName(), mach_inst);
return si;
@@ -122,6 +124,7 @@ Decoder::decode(PCStateBase &_next_pc)
emi.vtype8 = next_pc.vtype() & 0xff;
emi.vill = next_pc.vtype().vill;
emi.rv_type = static_cast<int>(next_pc.rvType());
return decode(emi, next_pc.instAddr());
}

View File

@@ -146,6 +146,15 @@ class RiscvMacroInst : public RiscvStaticInst
{
panic("Tried to execute a macroop directly!\n");
}
void size(size_t newSize) override
{
for (int i = 0; i < microops.size(); i++) {
microops[i]->size(newSize);
}
_size = newSize;
}
};
/**

View File

@@ -687,6 +687,8 @@ Decoder::decode(ExtMachInst mach_inst, Addr addr)
(*instMap)[mach_inst] = si;
}
si->size(basePC + offset - origPC);
DPRINTF(Decode, "Decode: Decoded %s instruction: %#x\n",
si->getName(), mach_inst);
return si;
@@ -732,8 +734,7 @@ Decoder::decode(PCStateBase &next_pc)
start = 0;
}
si = decode(emi, origPC);
return si;
return decode(emi, origPC);
}
StaticInstPtr

View File

@@ -103,6 +103,14 @@ class MacroopBase : public X86StaticInst
{
return env;
}
void size(size_t newSize) override
{
for (int i = 0; i < numMicroops; i++) {
microops[i]->size(newSize);
}
_size = newSize;
}
};
} // namespace X86ISA

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2017, 2020 ARM Limited
* Copyright (c) 2022-2023 The University of Edinburgh
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -250,6 +251,11 @@ class StaticInst : public RefCounted, public StaticInstFlags
_destRegIdxPtr = dest;
}
/**
* Instruction size in bytes. Necessary for dynamic instruction sizes
*/
size_t _size = 0;
/**
* Base mnemonic (e.g., "add"). Used by generateDisassembly()
* methods. Also useful to readily identify instructions from
@@ -307,6 +313,17 @@ class StaticInst : public RefCounted, public StaticInstFlags
panic("buildRetPC not defined!");
}
size_t size() const
{
if (_size == 0) fatal(
"Instruction size for this instruction not set! It's size is "
"required for the decoupled front-end. Either use the standard "
"front-end or this ISA needs to be extended with the instruction "
"size. Refer to the X86, Arm or RiscV decoders for an example.");
return _size;
}
virtual void size(size_t newSize) { _size = newSize; }
/**
* Return the microop that goes with a particular micropc. This should
* only be defined/used in macroops which will contain microops