Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding new instruction to RISCV-32ima: "bad RISCV-opcode"

Tags:

binutils

riscv

I'm seeking for help concerning the extensions I'm trying to add to riscv.

GLOBAL SETTING

My working baseline is a clone of the riscv-tools repo, containing the usual tools, among which are:

  • riscv-fesvr
  • riscv-gnu-toolchain
  • riscv-isa-sim
  • riscv-opcodes
  • riscv-pk

nb: the last commit I cloned from was c6d58cecb3862deb742e1a5cc9d1c682f2c50ba9 (2018-04-24).

I base my work on a riscv32-ima core. I want to add one instruction to this processor's ISA that will activate a particular component within my processor.

From the behavior of the proc itself, I have no problem: I modified spike and my instruction (as well as the component I add to the processor) work perfectly well.

In assembler, the instruction would look like:

addi a0, a0, 0
...            // other code
setupcomp      // activate my component ... 
...            // other code

See that this instruction has no operands whatsoever.

WHAT I DO

I duck-ducked-go-ed a while and found the this tutorial, which is a bit old.

So, I:

  1. go to riscv-tools/riscv-opcodes/
  2. add the opcode and its mask to riscv-tools/riscv-opcodes/opcodes. Mine look like this:

    setupcomp 31..28=ignore 27..20=ignore 19..15=ignore 14..12=0 11..7=ignore 6..2=0x1a 1..0=3
    
  3. from there, I rebuild the necessary .h files:

    make install
    
  4. Now, I add the necessary stucts to riscv-tools/riscv-gnu-toolchain/riscv-binutils-gdb/include/opcode/riscv-opc.h, and I also declare the instruction officially:

    #define MATCH_SETUPCOMP 0x6b
    #define MASK_SETUPCOMP  0x707f
    DECLARE_INSN(setupcomp, MATCH_SETUPCOMP, MASK_SETUPCOMP)
    

    These values, I got from what was generated from the opcodes project.

  5. I also add the necessary definitions to: riscv-tools/riscv-gnu-toolchain/riscv-binutils-gdb/opcodes/riscv-opc.c:

    {"setupcomp", "I", "", MATCH_SETUPCOMP, MASK_SETUPCOMP, match_opcode, 0 },
    

Now, up to here, I believe I've done everything necessary. I still have a doubt on the opcode I want, but I don't believe this has an impact on the behavior I observe and which I describe now.

PROBLEM I HAVE

When I build everything with the riscv-tools/build-rv32ima.sh script, near the end of the process (I believe in something like a test suite) I get a message complaining that:

Assembler messages:
Error: internal: bad RISC-V opcode (bits 0xffffffffffff8f80 undefined): setupcomp 
Fatal error: Broken assembler.  No assembly attempted.
make[6]: *** [lib_a-dummy.o] Error 1

I think I'm missing something in the declaration of the instruction, probably that this declaration is not "forwarded" properly to every part of the toolchain that actually needs it. But I can't find where/what/how/when and I would very much appreciate any input on this.

Of course, I'm most probably missing something obvious, so be gentle :)

like image 225
Lionel Morel Avatar asked Aug 13 '18 15:08

Lionel Morel


2 Answers

Your best bet for adding custom instructions to the toolchain is to use our .insn assembler directive. While this doesn't give you pretty syntax (you're expected to use a preprocessor macro or C wrapper function), it does let you avoid touching the toolchain as that's fraught with issues.

The best documentation for this is the GAS testsuite for .insn. Essentially users can emit instructions of any format defined by the RISC-V ISA manuals, with options to fill out each bit pattern directly. This integrates with GCC's inline-assembly register allocation framework cleanly, where it works just like any other instruction.

like image 136
Palmer Dabbelt Avatar answered Sep 30 '22 02:09

Palmer Dabbelt


Just run following command to parse MASK/MATCH:

cat opcodes-pseudo opcodes opcodes-rvc opcodes-rvc-pseudo opcodes-custom | ./parse-opcodes -c > ~/temp.h

It gives you correct MASK and MATCH for riscv-gnu-toolchain/riscv-binutils-gdb/include/opcode/riscv-opc.h Now recompile and you`ve done!

like image 31
Алексей Хилаев Avatar answered Sep 30 '22 03:09

Алексей Хилаев