riscvarchive / riscv-binutils-gdb

RISC-V backports for binutils-gdb. Development is done upstream at the FSF.
GNU General Public License v2.0
148 stars 233 forks source link

Add instruction from P-Extension to binutils #231

Closed MykolaMoshak closed 3 years ago

MykolaMoshak commented 3 years ago

I'm trying to add add8 instruction from P-Extension to binutils, but after recompiling the toolchain I am getting an error: Error: internal: bad RISC-V opcode (mask error): add8 d,s,t

Encoding of the instruction i took from here: https://github.com/riscv/riscv-p-spec/blob/master/P-ext-proposal.adoc#51-add8-simd-8-bit-addition

This what i did:

Add following lines into riscv-binutils-gdb/include/opcode/riscv-ops.h #define MATCH_ADD8 0x4800007f #define MASK_ADD8 0xfe00707f DECLARE_INSN(add8, MATCH_ADD8, MASK_ADD8)

Add following line into riscv-binutils-gdb/opcodes/riscv-opc.c: {"add8", 0, INSN_CLASS_I, "d,s,t", MATCH_ADD8, MASK_ADD8, match_opcode, 0 },

Recompile toolchain and call as. My configuration is arch - rv32imac, abi - ilp32

How i can fix this error? Many thanks.

stuarch commented 3 years ago

This is because gas not yet get length of P-ext instructions correctly, you can fix this by doing workaround in riscv-binutils-gdb/include/opcode/riscv.h:

static inline unsigned int riscv_insn_length (insn_t insn)
{
  if ((insn & 0x3) != 0x3) /* RVC.  */
    return 2;
  if ((insn & 0x1f) != 0x1f) /* Base ISA and extensions in 32-bit space.  */
    return 4;
  if ((insn & 0x3f) == 0x1f) /* 48-bit extensions.  */
    return 6;
  if ((insn & 0x7f) == 0x3f) /* 64-bit extensions.  */
    return 8;
  if ((insn & 0x7f) == 0x7f) /* For P-ext instructions. */
    return 4;
  /* Longer instructions not supported at the moment.  */
  return 2;
}
MykolaMoshak commented 3 years ago

Thank you very much for the quick response. I have changed the recommended line and it helped.