I'm seeking for help concerning the extensions I'm trying to add to riscv
.
My working baseline is a clone of the riscv-tools
repo, containing the usual tools, among which are:
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.
I duck-ducked-go-ed a while and found the this tutorial, which is a bit old.
So, I:
riscv-tools/riscv-opcodes/
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
from there, I rebuild the necessary .h
files:
make install
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.
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.
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 :)
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.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With