Skip to content

Adding Custom RiscV Instructions

Philip Bedoukian edited this page Mar 1, 2023 · 1 revision

The easiest way to create a custom instruction is to make a custom flag and attach it to a new instruction. Then you can just check for this flag when evaluating an instruction and do a custom operation.

To add a flag and propagate it to the cpu model.

  • Add "MyFlag" to list in cpu/StaticInstFlags.py
  • Add lookup in cpu/static_inst.hh (bool isMyFlag { return flags[MyFlag]; } )
  • Add lookup in cpu/io/dyn_inst.hh (return static_inst_p->isMyFlag());
  • Finally add a new instruction in arch/riscv/isa/decoder.isa (needs to have different opcode/funct code from existing riscv instructions). And put "MyFlag" after the body.

Note if you want to use certain registers the format of the custom instruction needs to support them and be referenced in the compute body.

To invoke this instruction is C code, it is recommended to make a macro that encapsulates the inline assembly see programs-spad/common/bind_defs.h

  • Use .insn inline assembly to avoid having to modify the compiler or assembler. As long as you provide a valid riscv format the compiler will pass the instruction along to the binary.
  • The opcode in decoder.isa and the opcode after .insn will appear different. This is because you will probably adding the custom instruction in quadrant 0b11. So the opcode in decoder.isa will be left shifted by two spots and the first two bits will be 0b11 to get what should be the inline assembly opcode.
Clone this wiki locally