How to add a custom instruction to the RISC-V GCC tools?(转)

On Fri, Aug 3, 2018 at 5:41 AM, Tommy Murphy <tommy_...@hotmail.com> wrote: 
> I know that this (or something similar) has been asked a few times before 
> but I have never seen a clear and authoritative answer. 
> (If one exists and has been posted then apologies for overlooking it and 
> please just point me at it). 
> Is there any clear and authoritative guide to how to add a custom RISC-V 
> instruction to the GCC (bare metal/newlib) toolchain? 
> If not then are there any specific links to help along the way to achieving 
> that? 

It is easier to add instructions to binutils than gcc.  For binutils, 
we have the .insn support that Kito Cheng added that lets you specify 
each instruction field individually, and can be used for custom 
instructions.  If you want something more programmer friendly, then 
you can add a line to opcodes/riscv-opc.c to add an instruction.  Just 
copy a similar instruction and modify the fields as appropriate.  You 
can find the match/mask patterns in include/opcode/riscv-opc.h.  For 
the operand letters, you can look at the code in gas/config/tc-riscv.c 
riscv_ip() that handles them, e.g. search for 'p' to find the p 
support, and note that the first one is for compressed support 'Cp' 
and the second one is the plain 'p'.  Adding instructions this way 
will require some understanding of how binutils works, but the 
assemble/disassemble stuff is pretty easy.  It is the linker stuff 
that is complicated.  If you have your own instruction formats, and 
need new relocations and/or relaxations, then that can get very 
complicated very quickly, and I'm not going to try to explain that 
here.  The simulator is also pretty easy, though we have two of them, 
the gdb simulator which is not upstream, and the QEMU simulator which 
is upstream.  Both should be pretty easy to modify.  Oh, and I suppose 
we also have spike, but I haven't looked at that one much. 

There is a binutils tool called cgen that lets you construct an 
assembler from an architecture description file.  This is an easier 
way to go if you want to do a lot of architecture experimenting, but 
it is not how the current assembler is written, and changing to a new 
assembler design at this point would likely be painful.  Embecosm 
incidentally has a cgen risc-v assembler port.  I don't know if they 
plan to release the sources for it, and I don't know how many existing 
RISC-V binutils features are supported in it. 

For gcc, the first question is what do you mean by gcc support.  Are 
you OK using an extended asm to hand code in the instruction?  That is 
trivial.  Do you want an intrinsic that will generate the instruction 
for you?  This is not very hard.  Do you want the compiler optimizer 
to automatically generate the instruction?  This is harder.  You need 
to add a pattern to the gcc/config/riscv/riscv.md file to describe the 
instruction.  If the instruction is performing a common operation, 
then just adding the instruction pattern may be enough to get it 
generated.  You will have to spend some timing debugging the compiler 
to get the pattern details right so that it gets generated when 
appropriate, but this is generally not too hard.  If the instruction 
is performing a less common operation, then you may have to do work on 
target independent and/or target dependent optimization passes to get 
the instruction to be generated, and this will require a lot of gcc 
internals knowledge, and possibly a lot of time. 

There are a number of GCC internals tutorials that have been written 
by various people over the years.  We have a link to some of them on 
the gcc web site. 
    https://gcc.gnu.org/wiki/GettingStarted#Tutorials.2C_HOWTOs 
GCC internals is always changing as development progresses, so some of 
the info in these will be out-of-date.  And of course there are lots 
of text books that talk about compiler design and implementation if 
you need a general introduction to compilers. 

For binutils, it is a much smaller development community than gcc, and 
the core developers tend to stay with it longer, so there is less 
tutorial type info available.  There is one on the web site 
    https://sourceware.org/binutils/binutils-porting-guide.txt 
but it appears to be a brief high level description and maybe not very 
useful to you.  There aren't many textbooks that cover what binutils 
does, but the linker part is the only part worthy of a textbook.  For 
that, I would suggest "Linkers and Loaders" by John R Levine.  I 
haven't actually read this, but I know a number of the people 
mentioned in the Acknowledgements section and have heard good things 
about the book. 

Both binutils and gcc have mailing lists where you can ask questions 
if you are serious about getting involved in development, and need 
help understanding something.  Usually the best way to get started is 
to just pick a bug report or enhancement request, start reading 
sources, try various ways to fix or implement it until you find 
solution, then asking on the mailing lists if you have a good 
solution, and iterate until it is right, learning how the sources work 
along the way.  Then pick another one and repeat for a few years until 
you are an expert. 

Jim 

posted @ 2019-01-28 17:15  wuhh123  阅读(420)  评论(0编辑  收藏  举报