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
This commit is contained in:
Andrew Burgess
2019-11-18 16:00:59 +00:00
parent 1296bc99b1
commit 4762fe621e
6 changed files with 574 additions and 3 deletions

View File

@@ -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