diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2019-11-18 16:00:59 +0000 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2019-11-28 00:03:05 +0000 |
commit | 4762fe621e84347b6e1ad1f2d16d2bc6cd28495e (patch) | |
tree | fde8d0eaf6ccacdd25c11b29283328ad3956ee2c /binutils/dwarf.c | |
parent | 1296bc99b1bf5da38be18ac1fdf6ad8d1b697e6b (diff) | |
download | binutils-4762fe621e84347b6e1ad1f2d16d2bc6cd28495e.zip binutils-4762fe621e84347b6e1ad1f2d16d2bc6cd28495e.tar.gz binutils-4762fe621e84347b6e1ad1f2d16d2bc6cd28495e.tar.bz2 |
binutils/gas/riscv: Add DWARF register numbers for CSRs
This commit gives DWARF register numbers to the RISC-V CSRs inline
with the RISC-V ELF specification here:
https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md
The CSRs are defined being numbered from 4096 to 8191.
This adds support to the assembler, required in order to reference
CSRs in, for example .cfi directives.
I have then extended dwarf.c in order to support printing CSR names in
the dumped DWARF output. As the CSR name space is quite large and
only sparsely populated, I have provided a new function to perform
RISC-V DWARF register name lookup which uses a switch statement rather
than the table base approach that other architectures use.
Any CSR that does not have a known name will return a name based on
'csr%d' with the %d being replaced by the offset of the CSR from 4096.
gas/ChangeLog:
* config/tc-riscv.c (tc_riscv_regname_to_dw2regnum): Lookup CSR
names too.
* testsuite/gas/riscv/csr-dw-regnums.d: New file.
* testsuite/gas/riscv/csr-dw-regnums.s: New file.
binutils/ChangeLog:
* dwarf.c (regname_internal_riscv): New function.
(init_dwarf_regnames_riscv): Use new function.
Change-Id: I3f70bc24fa8b3c75744e6775eeeb87db70c7ecfb
Diffstat (limited to 'binutils/dwarf.c')
-rw-r--r-- | binutils/dwarf.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 483d7c0..06ef1f7 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -7591,12 +7591,47 @@ static const char *const dwarf_regnames_riscv[] = "ft8", "ft9", "ft10", "ft11" /* 60 - 63 */ }; +/* A RISC-V replacement for REGNAME_INTERNAL_BY_TABLE_ONLY which handles + the large number of CSRs. */ + +static const char * +regname_internal_riscv (unsigned int regno) +{ + const char *name = NULL; + + /* Lookup in the table first, this covers GPR and FPR. */ + if (regno < ARRAY_SIZE (dwarf_regnames_riscv)) + name = dwarf_regnames_riscv [regno]; + else if (regno >= 4096 && regno <= 8191) + { + /* This might be a CSR, these live in a sparse number space from 4096 + to 8191 These numbers are defined in the RISC-V ELF ABI + document. */ + switch (regno) + { +#define DECLARE_CSR(NAME,VALUE) case VALUE + 4096: name = #NAME; break; +#include "opcode/riscv-opc.h" +#undef DECLARE_CSR + + default: + { + static char csr_name[10]; + snprintf (csr_name, sizeof (csr_name), "csr%d", (regno - 4096)); + name = csr_name; + } + break; + } + } + + return name; +} + static void init_dwarf_regnames_riscv (void) { - dwarf_regnames = dwarf_regnames_riscv; - dwarf_regnames_count = ARRAY_SIZE (dwarf_regnames_riscv); - dwarf_regnames_lookup_func = regname_internal_by_table_only; + dwarf_regnames = NULL; + dwarf_regnames_count = 8192; + dwarf_regnames_lookup_func = regname_internal_riscv; } void |