diff --git a/src/arch/arm/decoder.hh b/src/arch/arm/decoder.hh index 83690936c0..75488b6750 100644 --- a/src/arch/arm/decoder.hh +++ b/src/arch/arm/decoder.hh @@ -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; } diff --git a/src/arch/arm/insts/pred_inst.hh b/src/arch/arm/insts/pred_inst.hh index da3db6c6a5..6f46831edb 100644 --- a/src/arch/arm/insts/pred_inst.hh +++ b/src/arch/arm/insts/pred_inst.hh @@ -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; + } }; /** diff --git a/src/arch/generic/pcstate.hh b/src/arch/generic/pcstate.hh index f1df6e7c39..5c278a4233 100644 --- a/src/arch/generic/pcstate.hh +++ b/src/arch/generic/pcstate.hh @@ -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 } void - set(Addr val) + set(Addr val) override { Base::set(val); this->upc(0); diff --git a/src/arch/riscv/decoder.cc b/src/arch/riscv/decoder.cc index d225871241..b1e2948e93 100644 --- a/src/arch/riscv/decoder.cc +++ b/src/arch/riscv/decoder.cc @@ -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(next_pc.rvType()); + return decode(emi, next_pc.instAddr()); } diff --git a/src/arch/riscv/insts/static_inst.hh b/src/arch/riscv/insts/static_inst.hh index 74f9ddb452..2e4d94864a 100644 --- a/src/arch/riscv/insts/static_inst.hh +++ b/src/arch/riscv/insts/static_inst.hh @@ -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; + } + }; /** diff --git a/src/arch/x86/decoder.cc b/src/arch/x86/decoder.cc index ef87ff37c4..af2456d6ab 100644 --- a/src/arch/x86/decoder.cc +++ b/src/arch/x86/decoder.cc @@ -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 diff --git a/src/arch/x86/insts/macroop.hh b/src/arch/x86/insts/macroop.hh index 36718f77fd..071037b173 100644 --- a/src/arch/x86/insts/macroop.hh +++ b/src/arch/x86/insts/macroop.hh @@ -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 diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index 7ecc57d2f0..b98c01f872 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -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