Closed mortbopet closed 10 months ago
@mortbopet What are your thoughts on the following re-implementation? I used the B-Type RISC-V instruction format as an example. Function definitions are excluded for brevity.
template <typename Reg_T>
class RVInstruction : public Instruction<Reg_T> {
public:
RVInstruction(const Opcode<Reg_T> &opcode,
const std::vector<std::shared_ptr<Field<Reg_T>>> &fields);
};
// A B-Type RISC-V instruction
template <typename Reg_T>
class BTypeInstr : public RVInstruction<Reg_T> {
public:
BTypeInstr(const Token &name, unsigned funct3, const ISAInfoBase *isa);
static std::shared_ptr<Instruction<Reg_T>> defineInstr(const QString &name, unsigned funct3,
const ISAInfoBase *isa);
};
I tried to use the same parameters as the current macros to keep things similar to the current implementation. With this, you can then define an instruction as such:
// old method
instructions.push_back(BType(Token("beq"), 0b000));
// new method
instructions.push_back(BTypeInstr<Reg__T>::defineInstr("beq", 0b000, isa));
I implemented this change for B-Type instructions in a fresh branch, and it seemed to work without needing to change much. The disassembler was still able to successfully disassemble B-Type instructions.
Currently, defining instructions for the assembler is heavily dependent on macro usage (https://github.com/mortbopet/Ripes/blob/master/src/assembler/rvassembler_common.h#L12-L108):
In most cases, classes and templates can replace macros - i certainly think that could be the case here. I'd imagine that instead of having macros here, we'd have some hierarchy of classes that inherit from Instruction. Most likely, this would result in a class hierarchy of
possibly with templates sprinkled in to denote the register width that the assembler is being initialized with.
The intention of this change is to