From: Andrew Burgess Date: Mon, 29 Oct 2018 15:10:52 +0000 (+0000) Subject: gdb/riscv: Add target description support X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b5ffee3181d157a4d964f62344ac827142e37bde;p=binutils-gdb.git gdb/riscv: Add target description support This commit adds target description support for riscv. I've used the split feature approach for specifying the architectural features, and the CSR feature is auto-generated from the riscv-opc.h header file. If the target doesn't provide a suitable target description then GDB will build one by looking at the bfd headers. This commit does not implement target description creation for the Linux or FreeBSD native targets, both of these will need to add read_description methods into their respective target classes, which probe the target features, and then call riscv_create_target_description to build a suitable target description. Until this is done Linux and FreeBSD will get the same default target description based on the bfd that bare-metal targets get. I've only added feature descriptions for 32 and 64 bit registers, 128 bit registers (for RISC-V) are not supported in the reset of GDB yet. This commit removes the special reading of the MISA register in order to establish the target features, this was only used for figuring out the f-register size, and even that wasn't done consistently. We now rely on the target to tell us what size of registers it has (or look in the BFD as a last resort). The result of this is that we should now support RV64 targets with 32-bit float, though I have not extensively tested this combination yet. * Makefile.in (ALL_TARGET_OBS): Add arch/riscv.o. (HFILES_NO_SRCDIR): Add arch/riscv.h. * arch/riscv.c: New file. * arch/riscv.h: New file. * configure.tgt: Add cpu_obs list of riscv, move riscv-tdep.o into this list, and add arch/riscv.o. * features/Makefile: Add riscv features. * features/riscv/32bit-cpu.c: New file. * features/riscv/32bit-cpu.xml: New file. * features/riscv/32bit-csr.c: New file. * features/riscv/32bit-csr.xml: New file. * features/riscv/32bit-fpu.c: New file. * features/riscv/32bit-fpu.xml: New file. * features/riscv/64bit-cpu.c: New file. * features/riscv/64bit-cpu.xml: New file. * features/riscv/64bit-csr.c: New file. * features/riscv/64bit-csr.xml: New file. * features/riscv/64bit-fpu.c: New file. * features/riscv/64bit-fpu.xml: New file. * features/riscv/rebuild-csr-xml.sh: New file. * riscv-tdep.c: Add 'arch/riscv.h' include. (riscv_gdb_reg_names): Delete. (csr_reggroup): New global. (struct riscv_register_alias): Delete. (struct riscv_register_feature): New structure. (riscv_register_aliases): Delete. (riscv_xreg_feature): New global. (riscv_freg_feature): New global. (riscv_virtual_feature): New global. (riscv_csr_feature): New global. (riscv_create_csr_aliases): New function. (riscv_read_misa_reg): Delete. (riscv_has_feature): Delete. (riscv_isa_xlen): Simplify, just return cached xlen. (riscv_isa_flen): Simplify, just return cached flen. (riscv_has_fp_abi): Update for changes in struct gdbarch_tdep. (riscv_register_name): Update to make use of tdesc_register_name. Look up xreg and freg names in the new globals riscv_xreg_feature and riscv_freg_feature. Don't supply csr aliases here. (riscv_fpreg_q_type): Delete. (riscv_register_type): Use tdesc_register_type in almost all cases, override the returned type in a few specific cases only. (riscv_print_one_register_info): Handle errors reading registers. (riscv_register_reggroup_p): Use tdesc_register_in_reggroup_p for registers that are otherwise unknown to GDB. Also check the csr_reggroup. (riscv_print_registers_info): Remove assert about upper register number, and use gdbarch_register_reggroup_p instead of short-cutting. (riscv_find_default_target_description): New function. (riscv_check_tdesc_feature): New function. (riscv_add_reggroups): New function. (riscv_setup_register_aliases): New function. (riscv_init_reggroups): New function. (_initialize_riscv_tdep): Add calls to setup CSR aliases, and setup register groups. Register new riscv debug variable. * riscv-tdep.h: Add 'arch/riscv.h' include. (struct gdbarch_tdep): Remove abi union, and add riscv_gdbarch_features field. Remove cached quad floating point type, and provide initialisation for double type field. * target-descriptions.c (maint_print_c_tdesc_cmd): Add riscv to the list of targets using the feature based target descriptions. * NEWS: Mention target description support. gdb/doc/ChangeLog: * gdb.texinfo (Standard Target Features): Add RISC-V Features sub-section. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d81d5003194..1630bd87a0d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,69 @@ +2018-11-21 Andrew Burgess + + * Makefile.in (ALL_TARGET_OBS): Add arch/riscv.o. + (HFILES_NO_SRCDIR): Add arch/riscv.h. + * arch/riscv.c: New file. + * arch/riscv.h: New file. + * configure.tgt: Add cpu_obs list of riscv, move riscv-tdep.o into + this list, and add arch/riscv.o. + * features/Makefile: Add riscv features. + * features/riscv/32bit-cpu.c: New file. + * features/riscv/32bit-cpu.xml: New file. + * features/riscv/32bit-csr.c: New file. + * features/riscv/32bit-csr.xml: New file. + * features/riscv/32bit-fpu.c: New file. + * features/riscv/32bit-fpu.xml: New file. + * features/riscv/64bit-cpu.c: New file. + * features/riscv/64bit-cpu.xml: New file. + * features/riscv/64bit-csr.c: New file. + * features/riscv/64bit-csr.xml: New file. + * features/riscv/64bit-fpu.c: New file. + * features/riscv/64bit-fpu.xml: New file. + * features/riscv/rebuild-csr-xml.sh: New file. + * riscv-tdep.c: Add 'arch/riscv.h' include. + (riscv_gdb_reg_names): Delete. + (csr_reggroup): New global. + (struct riscv_register_alias): Delete. + (struct riscv_register_feature): New structure. + (riscv_register_aliases): Delete. + (riscv_xreg_feature): New global. + (riscv_freg_feature): New global. + (riscv_virtual_feature): New global. + (riscv_csr_feature): New global. + (riscv_create_csr_aliases): New function. + (riscv_read_misa_reg): Delete. + (riscv_has_feature): Delete. + (riscv_isa_xlen): Simplify, just return cached xlen. + (riscv_isa_flen): Simplify, just return cached flen. + (riscv_has_fp_abi): Update for changes in struct gdbarch_tdep. + (riscv_register_name): Update to make use of tdesc_register_name. + Look up xreg and freg names in the new globals riscv_xreg_feature + and riscv_freg_feature. Don't supply csr aliases here. + (riscv_fpreg_q_type): Delete. + (riscv_register_type): Use tdesc_register_type in almost all + cases, override the returned type in a few specific cases only. + (riscv_print_one_register_info): Handle errors reading registers. + (riscv_register_reggroup_p): Use tdesc_register_in_reggroup_p for + registers that are otherwise unknown to GDB. Also check the + csr_reggroup. + (riscv_print_registers_info): Remove assert about upper register + number, and use gdbarch_register_reggroup_p instead of + short-cutting. + (riscv_find_default_target_description): New function. + (riscv_check_tdesc_feature): New function. + (riscv_add_reggroups): New function. + (riscv_setup_register_aliases): New function. + (riscv_init_reggroups): New function. + (_initialize_riscv_tdep): Add calls to setup CSR aliases, and + setup register groups. Register new riscv debug variable. + * riscv-tdep.h: Add 'arch/riscv.h' include. + (struct gdbarch_tdep): Remove abi union, and add + riscv_gdbarch_features field. Remove cached quad floating point + type, and provide initialisation for double type field. + * target-descriptions.c (maint_print_c_tdesc_cmd): Add riscv to + the list of targets using the feature based target descriptions. + * NEWS: Mention target description support. + 2018-11-21 Pedro Alves * valops.c (find_method_list, value_find_oload_method_list) diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 8bd78a6b84a..4001bcbc07c 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -667,6 +667,7 @@ ALL_TARGET_OBS = \ arch/arm-linux.o \ arch/i386.o \ arch/ppc-linux-common.o \ + arch/riscv.o \ arm-bsd-tdep.o \ arm-fbsd-tdep.o \ arm-linux-tdep.o \ @@ -1418,6 +1419,7 @@ HFILES_NO_SRCDIR = \ arch/i386.h \ arch/ppc-linux-common.h \ arch/ppc-linux-tdesc.h \ + arch/riscv.h \ cli/cli-cmds.h \ cli/cli-decode.h \ cli/cli-script.h \ diff --git a/gdb/NEWS b/gdb/NEWS index ef037dee4a2..9ecbb83d99c 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -38,6 +38,8 @@ requires the use of a keyword. Selecting a frame by level is unchanged. The MI comment "-stack-select-frame" is unchanged. +* The RISC-V target now supports target descriptions. + * New targets NXP S12Z s12z-*-elf diff --git a/gdb/arch/riscv.c b/gdb/arch/riscv.c new file mode 100644 index 00000000000..ca2238d5d70 --- /dev/null +++ b/gdb/arch/riscv.c @@ -0,0 +1,69 @@ +/* Copyright (C) 2018 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "common-defs.h" +#include "riscv.h" +#include + +#include "../features/riscv/32bit-cpu.c" +#include "../features/riscv/64bit-cpu.c" +#include "../features/riscv/32bit-fpu.c" +#include "../features/riscv/64bit-fpu.c" + +/* See arch/riscv.h. */ + +target_desc * +riscv_create_target_description (struct riscv_gdbarch_features features) +{ + target_desc *tdesc = allocate_target_description (); + +#ifndef IN_PROCESS_AGENT + std::string arch_name = "riscv"; + + if (features.xlen == 4) + arch_name.append (":rv32i"); + else if (features.xlen == 8) + arch_name.append (":rv64i"); + else if (features.xlen == 16) + arch_name.append (":rv128i"); + + if (features.flen == 4) + arch_name.append ("f"); + else if (features.flen == 8) + arch_name.append ("d"); + else if (features.flen == 16) + arch_name.append ("q"); + + set_tdesc_architecture (tdesc, arch_name.c_str ()); +#endif + + long regnum = 0; + + /* For now we only support creating 32-bit or 64-bit x-registers. */ + if (features.xlen == 4) + regnum = create_feature_riscv_32bit_cpu (tdesc, regnum); + else if (features.xlen == 8) + regnum = create_feature_riscv_64bit_cpu (tdesc, regnum); + + /* For now we only support creating 32-bit or 64-bit f-registers. */ + if (features.flen == 4) + regnum = create_feature_riscv_32bit_fpu (tdesc, regnum); + else if (features.flen == 8) + regnum = create_feature_riscv_64bit_fpu (tdesc, regnum); + + return tdesc; +} diff --git a/gdb/arch/riscv.h b/gdb/arch/riscv.h new file mode 100644 index 00000000000..007944019a9 --- /dev/null +++ b/gdb/arch/riscv.h @@ -0,0 +1,64 @@ +/* Common target-dependent functionality for RISC-V + + Copyright (C) 2018 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef ARCH_RISCV_H +#define ARCH_RISCV_H + +#include "common/tdesc.h" + +/* The set of RISC-V architectural features that we track that impact how + we configure the actual gdbarch instance. We hold one of these in the + gdbarch_tdep structure, and use it to distinguish between different + RISC-V gdbarch instances. + + The information in here ideally comes from the target description, + however, if the target doesn't provide a target description then we will + create a default target description by first populating one of these + based on what we know about the binary being executed, and using that to + drive default target description creation. */ + +struct riscv_gdbarch_features +{ + /* The size of the x-registers in bytes. This is either 4 (RV32), 8 + (RV64), or 16 (RV128). No other value is valid. Initialise to the + invalid 0 value so we can spot if one of these is used + uninitialised. */ + int xlen = 0; + + /* The size of the f-registers in bytes. This is either 4 (RV32), 8 + (RV64), or 16 (RV128). This can also hold the value 0 to indicate + that there are no f-registers. No other value is valid. */ + int flen = 0; + + /* This indicates if hardware floating point abi is in use. If the FLEN + field is 0 then this value _must_ be false. If the FLEN field is + non-zero and this field is false then this indicates the target has + floating point registers, but is still using the soft-float abi. If + this field is true then the hardware floating point abi is in use, and + values are passed in f-registers matching the size of FLEN. */ + bool hw_float_abi = false; +}; + +/* Create and return a target description that is compatible with + FEATURES. */ + +target_desc *riscv_create_target_description + (struct riscv_gdbarch_features features); + +#endif /* ARCH_RISCV_H */ diff --git a/gdb/configure.tgt b/gdb/configure.tgt index e1f5e31f547..9b646fa1a21 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -81,6 +81,9 @@ ia64*-*-*) cpu_obs="ia64-tdep.o" ;; +riscv*-*-*) + cpu_obs="riscv-tdep.o arch/riscv.o";; + x86_64-*-*) cpu_obs="${i386_tobjs} ${amd64_tobjs}";; @@ -532,18 +535,18 @@ s390*-*-linux*) riscv*-*-freebsd*) # Target: FreeBSD/riscv - gdb_target_obs="riscv-fbsd-tdep.o riscv-tdep.o" + gdb_target_obs="riscv-fbsd-tdep.o" ;; riscv*-*-linux*) # Target: Linux/RISC-V - gdb_target_obs="riscv-linux-tdep.o riscv-tdep.o glibc-tdep.o \ + gdb_target_obs="riscv-linux-tdep.o glibc-tdep.o \ linux-tdep.o solib-svr4.o symfile-mem.o linux-record.o" ;; riscv*-*-*) # Target: RISC-V architecture - gdb_target_obs="riscv-tdep.o" + gdb_target_obs="" ;; rl78-*-elf) diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 28e12523765..59e7330a4dc 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2018-11-21 Andrew Burgess + + * gdb.texinfo (Standard Target Features): Add RISC-V Features + sub-section. + 2018-11-20 Philippe Waroquiers * gdb.texinfo (Examining the Symbol Table): Document language choice diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 3c3915b332c..7350d945738 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -42944,6 +42944,7 @@ registers using the capitalization used in the description. * Nios II Features:: * OpenRISC 1000 Features:: * PowerPC Features:: +* RISC-V Features:: * S/390 and System z Features:: * Sparc Features:: * TIC6x Features:: @@ -43334,6 +43335,41 @@ contain the 64-bit checkpointed register @samp{cdscr}. The @samp{org.gnu.gdb.power.htm.tar} feature is optional. It should contain the 64-bit checkpointed register @samp{ctar}. + +@node RISC-V Features +@subsection RISC-V Features +@cindex target descriptions, RISC-V Features + +The @samp{org.gnu.gdb.riscv.cpu} feature is required for RISC-V +targets. It should contain the registers @samp{x0} through +@samp{x31}, and @samp{pc}. Either the architectural names (@samp{x0}, +@samp{x1}, etc) can be used, or the ABI names (@samp{zero}, @samp{ra}, +etc). + +The @samp{org.gnu.gdb.riscv.fpu} feature is optional. If present, it +should contain registers @samp{f0} through @samp{f31}, @samp{fflags}, +@samp{frm}, and @samp{fcsr}. As with the cpu feature, either the +architectural register names, or the ABI names can be used. + +The @samp{org.gnu.gdb.riscv.virtual} feature is optional. If present, +it should contain registers that are not backed by real registers on +the target, but are instead virtual, where the register value is +derived from other target state. In many ways these are like +@value{GDBN}s pseudo-registers, except implemented by the target. +Currently the only register expected in this set is the one byte +@samp{priv} register that contains the target's privilege level in the +least significant two bits. + +The @samp{org.gnu.gdb.riscv.csr} feature is optional. If present, it +should contain all of the target's standard CSRs. Standard CSRs are +those defined in the RISC-V specification documents. There is some +overlap between this feature and the fpu feature; the @samp{fflags}, +@samp{frm}, and @samp{fcsr} registers could be in either feature. The +expectation is that these registers will be in the fpu feature if the +target has floating point hardware, but can be moved into the csr +feature if the target has the floating point control registers, but no +other floating point hardware. + @node S/390 and System z Features @subsection S/390 and System z Features @cindex target descriptions, S/390 features diff --git a/gdb/features/Makefile b/gdb/features/Makefile index 150fef23f0b..ff2e57c65fd 100644 --- a/gdb/features/Makefile +++ b/gdb/features/Makefile @@ -207,6 +207,7 @@ GDB = false #Targets which use feature based target descriptions. aarch64-feature = 1 i386-feature = 1 +riscv-feature = 1 tic6x-feature = 1 all: $(OUTPUTS) @@ -242,6 +243,12 @@ FEATURE_XMLFILES = aarch64-core.xml \ i386/64bit-pkeys.xml \ i386/64bit-sse.xml \ i386/x32-core.xml \ + riscv/32bit-cpu.xml \ + riscv/32bit-csr.xml \ + riscv/32bit-fpu.xml \ + riscv/64bit-cpu.xml \ + riscv/64bit-csr.xml \ + riscv/64bit-fpu.xml \ tic6x-c6xp.xml \ tic6x-core.xml \ tic6x-gp.xml @@ -339,6 +346,10 @@ $(outdir)/i386/x32-avx-avx512-linux.dat: i386/x32-core.xml i386/64bit-avx.xml \ i386/64bit-avx512.xml i386/64bit-linux.xml \ i386/64bit-segments.xml +# Regenerate RISC-V CSR feature lists. +riscv/32bit-csr.xml riscv/64bit-csr.xml: ../../include/opcode/riscv-opc.h + ./riscv/rebuild-csr-xml.sh ../../include/opcode/riscv-opc.h ./riscv + # 'all' doesn't build the C files, so don't delete them in 'clean' # either. clean-cfiles: diff --git a/gdb/features/riscv/32bit-cpu.c b/gdb/features/riscv/32bit-cpu.c new file mode 100644 index 00000000000..64686db5cdd --- /dev/null +++ b/gdb/features/riscv/32bit-cpu.c @@ -0,0 +1,46 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: 32bit-cpu.xml */ + +#include "common/tdesc.h" + +static int +create_feature_riscv_32bit_cpu (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.riscv.cpu"); + tdesc_create_reg (feature, "zero", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "ra", regnum++, 1, NULL, 32, "code_ptr"); + tdesc_create_reg (feature, "sp", regnum++, 1, NULL, 32, "data_ptr"); + tdesc_create_reg (feature, "gp", regnum++, 1, NULL, 32, "data_ptr"); + tdesc_create_reg (feature, "tp", regnum++, 1, NULL, 32, "data_ptr"); + tdesc_create_reg (feature, "t0", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "t1", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "t2", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "fp", regnum++, 1, NULL, 32, "data_ptr"); + tdesc_create_reg (feature, "s1", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "a0", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "a1", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "a2", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "a3", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "a4", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "a5", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "a6", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "a7", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "s2", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "s3", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "s4", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "s5", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "s6", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "s7", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "s8", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "s9", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "s10", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "s11", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "t3", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "t4", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "t5", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "t6", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pc", regnum++, 1, NULL, 32, "code_ptr"); + return regnum; +} diff --git a/gdb/features/riscv/32bit-cpu.xml b/gdb/features/riscv/32bit-cpu.xml new file mode 100644 index 00000000000..c02f86c0b03 --- /dev/null +++ b/gdb/features/riscv/32bit-cpu.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/features/riscv/32bit-csr.c b/gdb/features/riscv/32bit-csr.c new file mode 100644 index 00000000000..711e958ddae --- /dev/null +++ b/gdb/features/riscv/32bit-csr.c @@ -0,0 +1,253 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: 32bit-csr.xml */ + +#include "common/tdesc.h" + +static int +create_feature_riscv_32bit_csr (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.riscv.csr"); + tdesc_create_reg (feature, "ustatus", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "uie", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "utvec", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "uscratch", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "uepc", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "ucause", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "utval", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "uip", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "fflags", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "frm", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "fcsr", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "cycle", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "time", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "instret", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter3", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter4", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter5", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter6", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter7", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter8", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter9", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter10", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter11", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter12", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter13", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter14", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter15", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter16", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter17", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter18", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter19", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter20", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter21", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter22", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter23", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter24", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter25", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter26", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter27", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter28", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter29", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter30", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter31", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "cycleh", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "timeh", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "instreth", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter3h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter4h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter5h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter6h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter7h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter8h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter9h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter10h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter11h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter12h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter13h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter14h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter15h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter16h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter17h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter18h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter19h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter20h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter21h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter22h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter23h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter24h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter25h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter26h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter27h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter28h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter29h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter30h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hpmcounter31h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "sstatus", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "sedeleg", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "sideleg", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "sie", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "stvec", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "scounteren", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "sscratch", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "sepc", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "scause", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "stval", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "sip", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "satp", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mvendorid", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "marchid", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mimpid", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhartid", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mstatus", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "misa", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "medeleg", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mideleg", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mie", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mtvec", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mcounteren", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mscratch", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mepc", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mcause", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mtval", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mip", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpcfg0", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpcfg1", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpcfg2", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpcfg3", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr0", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr1", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr2", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr3", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr4", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr5", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr6", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr7", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr8", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr9", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr10", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr11", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr12", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr13", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr14", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "pmpaddr15", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mcycle", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "minstret", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter3", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter4", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter5", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter6", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter7", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter8", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter9", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter10", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter11", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter12", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter13", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter14", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter15", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter16", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter17", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter18", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter19", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter20", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter21", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter22", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter23", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter24", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter25", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter26", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter27", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter28", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter29", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter30", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter31", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mcycleh", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "minstreth", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter3h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter4h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter5h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter6h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter7h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter8h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter9h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter10h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter11h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter12h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter13h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter14h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter15h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter16h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter17h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter18h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter19h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter20h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter21h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter22h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter23h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter24h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter25h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter26h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter27h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter28h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter29h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter30h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmcounter31h", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent3", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent4", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent5", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent6", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent7", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent8", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent9", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent10", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent11", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent12", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent13", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent14", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent15", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent16", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent17", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent18", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent19", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent20", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent21", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent22", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent23", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent24", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent25", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent26", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent27", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent28", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent29", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent30", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhpmevent31", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "tselect", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "tdata1", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "tdata2", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "tdata3", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "dcsr", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "dpc", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "dscratch", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hstatus", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hedeleg", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hideleg", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hie", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "htvec", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hscratch", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hepc", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hcause", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hbadaddr", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hip", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mbase", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mbound", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mibase", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mibound", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mdbase", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mdbound", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mucounteren", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mscounteren", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "mhcounteren", regnum++, 1, NULL, 32, "int"); + return regnum; +} diff --git a/gdb/features/riscv/32bit-csr.xml b/gdb/features/riscv/32bit-csr.xml new file mode 100644 index 00000000000..4aea9e657b9 --- /dev/null +++ b/gdb/features/riscv/32bit-csr.xml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/features/riscv/32bit-fpu.c b/gdb/features/riscv/32bit-fpu.c new file mode 100644 index 00000000000..22e80d640e5 --- /dev/null +++ b/gdb/features/riscv/32bit-fpu.c @@ -0,0 +1,48 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: 32bit-fpu.xml */ + +#include "common/tdesc.h" + +static int +create_feature_riscv_32bit_fpu (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.riscv.fpu"); + tdesc_create_reg (feature, "ft0", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "ft1", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "ft2", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "ft3", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "ft4", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "ft5", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "ft6", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "ft7", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fs0", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fs1", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fa0", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fa1", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fa2", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fa3", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fa4", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fa5", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fa6", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fa7", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fs2", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fs3", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fs4", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fs5", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fs6", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fs7", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fs8", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fs9", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fs10", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fs11", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "ft8", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "ft9", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "ft10", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "ft11", regnum++, 1, NULL, 32, "ieee_single"); + tdesc_create_reg (feature, "fflags", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "frm", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "fcsr", regnum++, 1, NULL, 32, "int"); + return regnum; +} diff --git a/gdb/features/riscv/32bit-fpu.xml b/gdb/features/riscv/32bit-fpu.xml new file mode 100644 index 00000000000..783287d9362 --- /dev/null +++ b/gdb/features/riscv/32bit-fpu.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/features/riscv/64bit-cpu.c b/gdb/features/riscv/64bit-cpu.c new file mode 100644 index 00000000000..910089805ee --- /dev/null +++ b/gdb/features/riscv/64bit-cpu.c @@ -0,0 +1,46 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: 64bit-cpu.xml */ + +#include "common/tdesc.h" + +static int +create_feature_riscv_64bit_cpu (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.riscv.cpu"); + tdesc_create_reg (feature, "zero", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "ra", regnum++, 1, NULL, 64, "code_ptr"); + tdesc_create_reg (feature, "sp", regnum++, 1, NULL, 64, "data_ptr"); + tdesc_create_reg (feature, "gp", regnum++, 1, NULL, 64, "data_ptr"); + tdesc_create_reg (feature, "tp", regnum++, 1, NULL, 64, "data_ptr"); + tdesc_create_reg (feature, "t0", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "t1", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "t2", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "fp", regnum++, 1, NULL, 64, "data_ptr"); + tdesc_create_reg (feature, "s1", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "a0", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "a1", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "a2", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "a3", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "a4", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "a5", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "a6", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "a7", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "s2", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "s3", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "s4", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "s5", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "s6", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "s7", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "s8", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "s9", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "s10", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "s11", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "t3", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "t4", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "t5", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "t6", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pc", regnum++, 1, NULL, 64, "code_ptr"); + return regnum; +} diff --git a/gdb/features/riscv/64bit-cpu.xml b/gdb/features/riscv/64bit-cpu.xml new file mode 100644 index 00000000000..f37d7f3ce36 --- /dev/null +++ b/gdb/features/riscv/64bit-cpu.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/features/riscv/64bit-csr.c b/gdb/features/riscv/64bit-csr.c new file mode 100644 index 00000000000..7c777406254 --- /dev/null +++ b/gdb/features/riscv/64bit-csr.c @@ -0,0 +1,253 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: 64bit-csr.xml */ + +#include "common/tdesc.h" + +static int +create_feature_riscv_64bit_csr (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.riscv.csr"); + tdesc_create_reg (feature, "ustatus", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "uie", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "utvec", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "uscratch", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "uepc", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "ucause", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "utval", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "uip", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "fflags", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "frm", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "fcsr", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "cycle", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "time", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "instret", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter3", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter4", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter5", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter6", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter7", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter8", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter9", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter10", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter11", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter12", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter13", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter14", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter15", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter16", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter17", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter18", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter19", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter20", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter21", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter22", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter23", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter24", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter25", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter26", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter27", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter28", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter29", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter30", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter31", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "cycleh", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "timeh", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "instreth", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter3h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter4h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter5h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter6h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter7h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter8h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter9h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter10h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter11h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter12h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter13h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter14h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter15h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter16h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter17h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter18h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter19h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter20h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter21h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter22h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter23h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter24h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter25h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter26h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter27h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter28h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter29h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter30h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hpmcounter31h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "sstatus", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "sedeleg", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "sideleg", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "sie", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "stvec", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "scounteren", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "sscratch", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "sepc", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "scause", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "stval", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "sip", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "satp", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mvendorid", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "marchid", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mimpid", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhartid", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mstatus", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "misa", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "medeleg", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mideleg", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mie", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mtvec", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mcounteren", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mscratch", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mepc", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mcause", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mtval", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mip", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpcfg0", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpcfg1", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpcfg2", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpcfg3", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr0", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr1", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr2", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr3", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr4", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr5", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr6", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr7", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr8", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr9", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr10", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr11", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr12", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr13", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr14", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "pmpaddr15", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mcycle", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "minstret", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter3", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter4", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter5", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter6", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter7", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter8", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter9", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter10", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter11", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter12", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter13", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter14", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter15", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter16", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter17", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter18", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter19", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter20", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter21", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter22", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter23", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter24", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter25", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter26", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter27", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter28", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter29", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter30", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter31", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mcycleh", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "minstreth", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter3h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter4h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter5h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter6h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter7h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter8h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter9h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter10h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter11h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter12h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter13h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter14h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter15h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter16h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter17h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter18h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter19h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter20h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter21h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter22h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter23h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter24h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter25h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter26h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter27h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter28h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter29h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter30h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmcounter31h", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent3", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent4", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent5", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent6", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent7", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent8", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent9", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent10", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent11", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent12", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent13", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent14", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent15", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent16", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent17", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent18", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent19", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent20", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent21", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent22", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent23", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent24", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent25", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent26", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent27", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent28", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent29", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent30", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhpmevent31", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "tselect", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "tdata1", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "tdata2", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "tdata3", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "dcsr", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "dpc", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "dscratch", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hstatus", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hedeleg", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hideleg", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hie", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "htvec", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hscratch", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hepc", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hcause", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hbadaddr", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hip", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mbase", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mbound", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mibase", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mibound", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mdbase", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mdbound", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mucounteren", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mscounteren", regnum++, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "mhcounteren", regnum++, 1, NULL, 64, "int"); + return regnum; +} diff --git a/gdb/features/riscv/64bit-csr.xml b/gdb/features/riscv/64bit-csr.xml new file mode 100644 index 00000000000..a3de83443a5 --- /dev/null +++ b/gdb/features/riscv/64bit-csr.xml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/features/riscv/64bit-fpu.c b/gdb/features/riscv/64bit-fpu.c new file mode 100644 index 00000000000..8cbd7484ab3 --- /dev/null +++ b/gdb/features/riscv/64bit-fpu.c @@ -0,0 +1,56 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: 64bit-fpu.xml */ + +#include "common/tdesc.h" + +static int +create_feature_riscv_64bit_fpu (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.riscv.fpu"); + tdesc_type_with_fields *type_with_fields; + type_with_fields = tdesc_create_union (feature, "riscv_double"); + tdesc_type *field_type; + field_type = tdesc_named_type (feature, "ieee_single"); + tdesc_add_field (type_with_fields, "float", field_type); + field_type = tdesc_named_type (feature, "ieee_double"); + tdesc_add_field (type_with_fields, "double", field_type); + + tdesc_create_reg (feature, "ft0", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "ft1", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "ft2", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "ft3", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "ft4", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "ft5", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "ft6", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "ft7", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fs0", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fs1", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fa0", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fa1", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fa2", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fa3", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fa4", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fa5", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fa6", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fa7", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fs2", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fs3", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fs4", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fs5", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fs6", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fs7", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fs8", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fs9", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fs10", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fs11", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "ft8", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "ft9", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "ft10", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "ft11", regnum++, 1, NULL, 64, "riscv_double"); + tdesc_create_reg (feature, "fflags", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "frm", regnum++, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "fcsr", regnum++, 1, NULL, 32, "int"); + return regnum; +} diff --git a/gdb/features/riscv/64bit-fpu.xml b/gdb/features/riscv/64bit-fpu.xml new file mode 100644 index 00000000000..fb24b72bcaf --- /dev/null +++ b/gdb/features/riscv/64bit-fpu.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/features/riscv/rebuild-csr-xml.sh b/gdb/features/riscv/rebuild-csr-xml.sh new file mode 100755 index 00000000000..6971b8dbb2a --- /dev/null +++ b/gdb/features/riscv/rebuild-csr-xml.sh @@ -0,0 +1,29 @@ +#! /bin/bash + +RISCV_OPC_FILE=$1 +RISCV_FEATURE_DIR=$2 + +function gen_csr_xml () +{ + bitsize=$1 + + cat < + + + + +EOF + + grep "^DECLARE_CSR(" ${RISCV_OPC_FILE} \ + | sed -e "s!DECLARE_CSR(\(.*\), .*! !" + + echo "" +} + +gen_csr_xml 32 > ${RISCV_FEATURE_DIR}/32bit-csr.xml +gen_csr_xml 64 > ${RISCV_FEATURE_DIR}/64bit-csr.xml diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index 408ab0af24b..5965a594440 100644 --- a/gdb/riscv-tdep.c +++ b/gdb/riscv-tdep.c @@ -55,6 +55,7 @@ #include "cli/cli-decode.h" #include "observable.h" #include "prologue-value.h" +#include "arch/riscv.h" /* The stack must be 16-byte aligned. */ #define SP_ALIGNMENT 16 @@ -62,9 +63,6 @@ /* The biggest alignment that the target supports. */ #define BIGGEST_ALIGNMENT 16 -/* Forward declarations. */ -static bool riscv_has_feature (struct gdbarch *gdbarch, char feature); - /* Define a series of is_XXX_insn functions to check if the value INSN is an instance of instruction XXX. */ #define DECLARE_INSN(INSN_NAME, INSN_MATCH, INSN_MASK) \ @@ -98,110 +96,170 @@ struct riscv_unwind_cache CORE_ADDR frame_base; }; -/* The preferred register names for all the general purpose and floating - point registers. These are what GDB will use when referencing a - register. */ +/* RISC-V specific register group for CSRs. */ -static const char * const riscv_gdb_reg_names[RISCV_LAST_FP_REGNUM + 1] = -{ - "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "fp", "s1", - "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", - "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", - "pc", - "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", "fs0", "fs1", - "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", "fa6", "fa7", "fs2", "fs3", - "fs4", "fs5", "fs6", "fs7", "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", - "ft10", "ft11", -}; +static reggroup *csr_reggroup = NULL; -/* Map alternative register names onto their GDB register number. */ +/* A set of registers that we expect to find in a tdesc_feature. These + are use in RISCV_GDBARCH_INIT when processing the target description. */ -struct riscv_register_alias +struct riscv_register_feature { - /* The register alias. Usually more descriptive than the - architectural name of the register. */ + /* Information for a single register. */ + struct register_info + { + /* The GDB register number for this register. */ + int regnum; + + /* List of names for this register. The first name in this list is the + preferred name, the name GDB should use when describing this + register. */ + std::vector names; + + /* When true this register is required in this feature set. */ + bool required_p; + }; + + /* The name for this feature. This is the name used to find this feature + within the target description. */ const char *name; - /* The GDB register number. */ - int regnum; + /* List of all the registers that we expect that we might find in this + register set. */ + std::vector registers; +}; + +/* The general x-registers feature set. */ + +static const struct riscv_register_feature riscv_xreg_feature = +{ + "org.gnu.gdb.riscv.cpu", + { + { RISCV_ZERO_REGNUM + 0, { "zero", "x0" }, true }, + { RISCV_ZERO_REGNUM + 1, { "ra", "x1" }, true }, + { RISCV_ZERO_REGNUM + 2, { "sp", "x2" }, true }, + { RISCV_ZERO_REGNUM + 3, { "gp", "x3" }, true }, + { RISCV_ZERO_REGNUM + 4, { "tp", "x4" }, true }, + { RISCV_ZERO_REGNUM + 5, { "t0", "x5" }, true }, + { RISCV_ZERO_REGNUM + 6, { "t1", "x6" }, true }, + { RISCV_ZERO_REGNUM + 7, { "t2", "x7" }, true }, + { RISCV_ZERO_REGNUM + 8, { "fp", "x8", "s0" }, true }, + { RISCV_ZERO_REGNUM + 9, { "s1", "x9" }, true }, + { RISCV_ZERO_REGNUM + 10, { "a0", "x10" }, true }, + { RISCV_ZERO_REGNUM + 11, { "a1", "x11" }, true }, + { RISCV_ZERO_REGNUM + 12, { "a2", "x12" }, true }, + { RISCV_ZERO_REGNUM + 13, { "a3", "x13" }, true }, + { RISCV_ZERO_REGNUM + 14, { "a4", "x14" }, true }, + { RISCV_ZERO_REGNUM + 15, { "a5", "x15" }, true }, + { RISCV_ZERO_REGNUM + 16, { "a6", "x16" }, true }, + { RISCV_ZERO_REGNUM + 17, { "a7", "x17" }, true }, + { RISCV_ZERO_REGNUM + 18, { "s2", "x18" }, true }, + { RISCV_ZERO_REGNUM + 19, { "s3", "x19" }, true }, + { RISCV_ZERO_REGNUM + 20, { "s4", "x20" }, true }, + { RISCV_ZERO_REGNUM + 21, { "s5", "x21" }, true }, + { RISCV_ZERO_REGNUM + 22, { "s6", "x22" }, true }, + { RISCV_ZERO_REGNUM + 23, { "s7", "x23" }, true }, + { RISCV_ZERO_REGNUM + 24, { "s8", "x24" }, true }, + { RISCV_ZERO_REGNUM + 25, { "s9", "x25" }, true }, + { RISCV_ZERO_REGNUM + 26, { "s10", "x26" }, true }, + { RISCV_ZERO_REGNUM + 27, { "s11", "x27" }, true }, + { RISCV_ZERO_REGNUM + 28, { "t3", "x28" }, true }, + { RISCV_ZERO_REGNUM + 29, { "t4", "x29" }, true }, + { RISCV_ZERO_REGNUM + 30, { "t5", "x30" }, true }, + { RISCV_ZERO_REGNUM + 31, { "t6", "x31" }, true }, + { RISCV_ZERO_REGNUM + 32, { "pc" }, true } + } +}; + +/* The f-registers feature set. */ + +static const struct riscv_register_feature riscv_freg_feature = +{ + "org.gnu.gdb.riscv.fpu", + { + { RISCV_FIRST_FP_REGNUM + 0, { "ft0", "f0" }, true }, + { RISCV_FIRST_FP_REGNUM + 1, { "ft1", "f1" }, true }, + { RISCV_FIRST_FP_REGNUM + 2, { "ft2", "f2" }, true }, + { RISCV_FIRST_FP_REGNUM + 3, { "ft3", "f3" }, true }, + { RISCV_FIRST_FP_REGNUM + 4, { "ft4", "f4" }, true }, + { RISCV_FIRST_FP_REGNUM + 5, { "ft5", "f5" }, true }, + { RISCV_FIRST_FP_REGNUM + 6, { "ft6", "f6" }, true }, + { RISCV_FIRST_FP_REGNUM + 7, { "ft7", "f7" }, true }, + { RISCV_FIRST_FP_REGNUM + 8, { "fs0", "f8", "s0" }, true }, + { RISCV_FIRST_FP_REGNUM + 9, { "fs1", "f9" }, true }, + { RISCV_FIRST_FP_REGNUM + 10, { "fa0", "f10" }, true }, + { RISCV_FIRST_FP_REGNUM + 11, { "fa1", "f11" }, true }, + { RISCV_FIRST_FP_REGNUM + 12, { "fa2", "f12" }, true }, + { RISCV_FIRST_FP_REGNUM + 13, { "fa3", "f13" }, true }, + { RISCV_FIRST_FP_REGNUM + 14, { "fa4", "f14" }, true }, + { RISCV_FIRST_FP_REGNUM + 15, { "fa5", "f15" }, true }, + { RISCV_FIRST_FP_REGNUM + 16, { "fa6", "f16" }, true }, + { RISCV_FIRST_FP_REGNUM + 17, { "fa7", "f17" }, true }, + { RISCV_FIRST_FP_REGNUM + 18, { "fs2", "f18" }, true }, + { RISCV_FIRST_FP_REGNUM + 19, { "fs3", "f19" }, true }, + { RISCV_FIRST_FP_REGNUM + 20, { "fs4", "f20" }, true }, + { RISCV_FIRST_FP_REGNUM + 21, { "fs5", "f21" }, true }, + { RISCV_FIRST_FP_REGNUM + 22, { "fs6", "f22" }, true }, + { RISCV_FIRST_FP_REGNUM + 23, { "fs7", "f23" }, true }, + { RISCV_FIRST_FP_REGNUM + 24, { "fs8", "f24" }, true }, + { RISCV_FIRST_FP_REGNUM + 25, { "fs9", "f25" }, true }, + { RISCV_FIRST_FP_REGNUM + 26, { "fs10", "f26" }, true }, + { RISCV_FIRST_FP_REGNUM + 27, { "fs11", "f27" }, true }, + { RISCV_FIRST_FP_REGNUM + 28, { "ft8", "f28" }, true }, + { RISCV_FIRST_FP_REGNUM + 29, { "ft9", "f29" }, true }, + { RISCV_FIRST_FP_REGNUM + 30, { "ft10", "f30" }, true }, + { RISCV_FIRST_FP_REGNUM + 31, { "ft11", "f31" }, true }, + + { RISCV_CSR_FFLAGS_REGNUM, { "fflags" }, true }, + { RISCV_CSR_FRM_REGNUM, { "frm" }, true }, + { RISCV_CSR_FCSR_REGNUM, { "fcsr" }, true }, + + } +}; + +/* Set of virtual registers. These are not physical registers on the + hardware, but might be available from the target. These are not pseudo + registers, reading these really does result in a register read from the + target, it is just that there might not be a physical register backing + the result. */ + +static const struct riscv_register_feature riscv_virtual_feature = +{ + "org.gnu.gdb.riscv.virtual", + { + { RISCV_PRIV_REGNUM, { "priv" }, false } + } }; -/* Table of register aliases. */ - -static const struct riscv_register_alias riscv_register_aliases[] = -{ - /* Aliases for general purpose registers. These are the architectural - names, as GDB uses the more user friendly names by default. */ - { "x0", (RISCV_ZERO_REGNUM + 0) }, - { "x1", (RISCV_ZERO_REGNUM + 1) }, - { "x2", (RISCV_ZERO_REGNUM + 2) }, - { "x3", (RISCV_ZERO_REGNUM + 3) }, - { "x4", (RISCV_ZERO_REGNUM + 4) }, - { "x5", (RISCV_ZERO_REGNUM + 5) }, - { "x6", (RISCV_ZERO_REGNUM + 6) }, - { "x7", (RISCV_ZERO_REGNUM + 7) }, - { "x8", (RISCV_ZERO_REGNUM + 8) }, - { "s0", (RISCV_ZERO_REGNUM + 8) }, /* fp, s0, and x8 are all aliases. */ - { "x9", (RISCV_ZERO_REGNUM + 9) }, - { "x10", (RISCV_ZERO_REGNUM + 10) }, - { "x11", (RISCV_ZERO_REGNUM + 11) }, - { "x12", (RISCV_ZERO_REGNUM + 12) }, - { "x13", (RISCV_ZERO_REGNUM + 13) }, - { "x14", (RISCV_ZERO_REGNUM + 14) }, - { "x15", (RISCV_ZERO_REGNUM + 15) }, - { "x16", (RISCV_ZERO_REGNUM + 16) }, - { "x17", (RISCV_ZERO_REGNUM + 17) }, - { "x18", (RISCV_ZERO_REGNUM + 18) }, - { "x19", (RISCV_ZERO_REGNUM + 19) }, - { "x20", (RISCV_ZERO_REGNUM + 20) }, - { "x21", (RISCV_ZERO_REGNUM + 21) }, - { "x22", (RISCV_ZERO_REGNUM + 22) }, - { "x23", (RISCV_ZERO_REGNUM + 23) }, - { "x24", (RISCV_ZERO_REGNUM + 24) }, - { "x25", (RISCV_ZERO_REGNUM + 25) }, - { "x26", (RISCV_ZERO_REGNUM + 26) }, - { "x27", (RISCV_ZERO_REGNUM + 27) }, - { "x28", (RISCV_ZERO_REGNUM + 28) }, - { "x29", (RISCV_ZERO_REGNUM + 29) }, - { "x30", (RISCV_ZERO_REGNUM + 30) }, - { "x31", (RISCV_ZERO_REGNUM + 31) }, - - /* Aliases for the floating-point registers. These are the architectural - names as GDB uses the more user friendly names by default. */ - { "f0", (RISCV_FIRST_FP_REGNUM + 0) }, - { "f1", (RISCV_FIRST_FP_REGNUM + 1) }, - { "f2", (RISCV_FIRST_FP_REGNUM + 2) }, - { "f3", (RISCV_FIRST_FP_REGNUM + 3) }, - { "f4", (RISCV_FIRST_FP_REGNUM + 4) }, - { "f5", (RISCV_FIRST_FP_REGNUM + 5) }, - { "f6", (RISCV_FIRST_FP_REGNUM + 6) }, - { "f7", (RISCV_FIRST_FP_REGNUM + 7) }, - { "f8", (RISCV_FIRST_FP_REGNUM + 8) }, - { "f9", (RISCV_FIRST_FP_REGNUM + 9) }, - { "f10", (RISCV_FIRST_FP_REGNUM + 10) }, - { "f11", (RISCV_FIRST_FP_REGNUM + 11) }, - { "f12", (RISCV_FIRST_FP_REGNUM + 12) }, - { "f13", (RISCV_FIRST_FP_REGNUM + 13) }, - { "f14", (RISCV_FIRST_FP_REGNUM + 14) }, - { "f15", (RISCV_FIRST_FP_REGNUM + 15) }, - { "f16", (RISCV_FIRST_FP_REGNUM + 16) }, - { "f17", (RISCV_FIRST_FP_REGNUM + 17) }, - { "f18", (RISCV_FIRST_FP_REGNUM + 18) }, - { "f19", (RISCV_FIRST_FP_REGNUM + 19) }, - { "f20", (RISCV_FIRST_FP_REGNUM + 20) }, - { "f21", (RISCV_FIRST_FP_REGNUM + 21) }, - { "f22", (RISCV_FIRST_FP_REGNUM + 22) }, - { "f23", (RISCV_FIRST_FP_REGNUM + 23) }, - { "f24", (RISCV_FIRST_FP_REGNUM + 24) }, - { "f25", (RISCV_FIRST_FP_REGNUM + 25) }, - { "f26", (RISCV_FIRST_FP_REGNUM + 26) }, - { "f27", (RISCV_FIRST_FP_REGNUM + 27) }, - { "f28", (RISCV_FIRST_FP_REGNUM + 28) }, - { "f29", (RISCV_FIRST_FP_REGNUM + 29) }, - { "f30", (RISCV_FIRST_FP_REGNUM + 30) }, - { "f31", (RISCV_FIRST_FP_REGNUM + 31) }, +/* Feature set for CSRs. This set is NOT constant as the register names + list for each register is not complete. The aliases are computed + during RISCV_CREATE_CSR_ALIASES. */ + +static struct riscv_register_feature riscv_csr_feature = +{ + "org.gnu.gdb.riscv.csr", + { +#define DECLARE_CSR(NAME,VALUE) \ + { RISCV_ ## VALUE ## _REGNUM, { # NAME }, false }, +#include "opcode/riscv-opc.h" +#undef DECLARE_CSR + } }; +/* Complete RISCV_CSR_FEATURE, building the CSR alias names and adding them + to the name list for each register. */ + +static void +riscv_create_csr_aliases () +{ + for (auto ® : riscv_csr_feature.registers) + { + int csr_num = reg.regnum - RISCV_FIRST_CSR_REGNUM; + const char *alias = xstrprintf ("csr%d", csr_num); + reg.names.push_back (alias); + } +} + /* Controls whether we place compressed breakpoints or not. When in auto mode GDB tries to determine if the target supports compressed breakpoints, and uses them if it does. */ @@ -293,82 +351,17 @@ static unsigned int riscv_debug_infcall = 0; static unsigned int riscv_debug_unwinder = 0; -/* Read the MISA register from the target. There are a couple of locations - that the register might be found, these are all tried. If the MISA - register can't be found at all then the default value of 0 is returned, - this is inline with the RISC-V specification. */ - -static uint32_t -riscv_read_misa_reg () -{ - uint32_t value = 0; - - if (target_has_registers) - { - /* Old cores might have MISA located at a different offset. */ - static int misa_regs[] = - { RISCV_CSR_MISA_REGNUM, RISCV_CSR_LEGACY_MISA_REGNUM }; - - struct frame_info *frame = get_current_frame (); - - for (int i = 0; i < ARRAY_SIZE (misa_regs); ++i) - { - bool success = false; - - TRY - { - value = get_frame_register_unsigned (frame, misa_regs[i]); - success = true; - } - CATCH (ex, RETURN_MASK_ERROR) - { - /* Ignore errors, it is acceptable for a target to not - provide a MISA register, in which case the default value - of 0 should be used. */ - } - END_CATCH - - if (success) - break; - } - } - - return value; -} +/* When this is set to non-zero debugging information about gdbarch + initialisation will be printed. */ -/* Return true if FEATURE is available for the architecture GDBARCH. The - FEATURE should be one of the single character feature codes described in - the RiscV ISA manual, these are between 'A' and 'Z'. */ - -static bool -riscv_has_feature (struct gdbarch *gdbarch, char feature) -{ - gdb_assert (feature >= 'A' && feature <= 'Z'); - - uint32_t misa = riscv_read_misa_reg (); - if (misa == 0) - misa = gdbarch_tdep (gdbarch)->core_features; - - return (misa & (1 << (feature - 'A'))) != 0; -} +static unsigned int riscv_debug_gdbarch = 0; /* See riscv-tdep.h. */ int riscv_isa_xlen (struct gdbarch *gdbarch) { - switch (gdbarch_tdep (gdbarch)->abi.fields.base_len) - { - default: - warning (_("unknown xlen size, assuming 4 bytes")); - /* Fall through. */ - case 1: - return 4; - case 2: - return 8; - case 3: - return 16; - } + return gdbarch_tdep (gdbarch)->features.xlen; } /* See riscv-tdep.h. */ @@ -376,14 +369,7 @@ riscv_isa_xlen (struct gdbarch *gdbarch) int riscv_isa_flen (struct gdbarch *gdbarch) { - if (riscv_has_feature (gdbarch, 'Q')) - return 16; - else if (riscv_has_feature (gdbarch, 'D')) - return 8; - else if (riscv_has_feature (gdbarch, 'F')) - return 4; - - return 0; + return gdbarch_tdep (gdbarch)->features.flen; } /* Return true if the target for GDBARCH has floating point hardware. */ @@ -399,7 +385,7 @@ riscv_has_fp_regs (struct gdbarch *gdbarch) static bool riscv_has_fp_abi (struct gdbarch *gdbarch) { - return (gdbarch_tdep (gdbarch)->abi.fields.float_abi != 0); + return gdbarch_tdep (gdbarch)->features.hw_float_abi; } /* Return true if REGNO is a floating pointer register. */ @@ -485,16 +471,36 @@ value_of_riscv_user_reg (struct frame_info *frame, const void *baton) return value_of_register (*reg_p, frame); } -/* Implement the register_name gdbarch method. */ +/* Implement the register_name gdbarch method. This is used instead of + the function supplied by calling TDESC_USE_REGISTERS so that we can + ensure the preferred names are offered. */ static const char * riscv_register_name (struct gdbarch *gdbarch, int regnum) { - /* Prefer to use the alias. */ - if (regnum >= RISCV_ZERO_REGNUM && regnum <= RISCV_LAST_FP_REGNUM) + /* Lookup the name through the target description. If we get back NULL + then this is an unknown register. If we do get a name back then we + look up the registers preferred name below. */ + const char *name = tdesc_register_name (gdbarch, regnum); + if (name == NULL || name[0] == '\0') + return NULL; + + if (regnum >= RISCV_ZERO_REGNUM && regnum < RISCV_FIRST_FP_REGNUM) + { + gdb_assert (regnum < riscv_xreg_feature.registers.size ()); + return riscv_xreg_feature.registers[regnum].names[0]; + } + + if (regnum >= RISCV_FIRST_FP_REGNUM && regnum <= RISCV_LAST_FP_REGNUM) { - gdb_assert (regnum < ARRAY_SIZE (riscv_gdb_reg_names)); - return riscv_gdb_reg_names[regnum]; + if (riscv_has_fp_regs (gdbarch)) + { + regnum -= RISCV_FIRST_FP_REGNUM; + gdb_assert (regnum < riscv_freg_feature.registers.size ()); + return riscv_freg_feature.registers[regnum].names[0]; + } + else + return NULL; } /* Check that there's no gap between the set of registers handled above, @@ -509,14 +515,6 @@ riscv_register_name (struct gdbarch *gdbarch, int regnum) switch (regnum) { #include "opcode/riscv-opc.h" - default: - { - static char buf[20]; - - xsnprintf (buf, sizeof (buf), "csr%d", - regnum - RISCV_FIRST_CSR_REGNUM); - return buf; - } } #undef DECLARE_CSR } @@ -524,7 +522,10 @@ riscv_register_name (struct gdbarch *gdbarch, int regnum) if (regnum == RISCV_PRIV_REGNUM) return "priv"; - return NULL; + /* It is possible that that the target provides some registers that GDB + is unaware of, in that case just return the NAME from the target + description. */ + return name; } /* Construct a type for 64-bit FP registers. */ @@ -561,115 +562,59 @@ riscv_fpreg_d_type (struct gdbarch *gdbarch) return tdep->riscv_fpreg_d_type; } -/* Construct a type for 128-bit FP registers. */ +/* Implement the register_type gdbarch method. This is installed as an + for the override setup by TDESC_USE_REGISTERS, for most registers we + delegate the type choice to the target description, but for a few + registers we try to improve the types if the target description has + taken a simplistic approach. */ static struct type * -riscv_fpreg_q_type (struct gdbarch *gdbarch) +riscv_register_type (struct gdbarch *gdbarch, int regnum) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + struct type *type = tdesc_register_type (gdbarch, regnum); + int xlen = riscv_isa_xlen (gdbarch); - if (tdep->riscv_fpreg_q_type == nullptr) + /* We want to perform some specific type "fixes" in cases where we feel + that we really can do better than the target description. For all + other cases we just return what the target description says. */ + if (riscv_is_fp_regno_p (regnum)) { - const struct builtin_type *bt = builtin_type (gdbarch); - - /* The type we're building is this: */ -#if 0 - union __gdb_builtin_type_fpreg_d - { - float f; - double d; - long double ld; - }; -#endif - - struct type *t; - - t = arch_composite_type (gdbarch, - "__gdb_builtin_type_fpreg_q", TYPE_CODE_UNION); - append_composite_type_field (t, "float", bt->builtin_float); - append_composite_type_field (t, "double", bt->builtin_double); - append_composite_type_field (t, "long double", bt->builtin_long_double); - TYPE_VECTOR (t) = 1; - TYPE_NAME (t) = "builtin_type_fpreg_q"; - tdep->riscv_fpreg_q_type = t; + /* This spots the case for RV64 where the double is defined as + either 'ieee_double' or 'float' (which is the generic name that + converts to 'double' on 64-bit). In these cases its better to + present the registers using a union type. */ + int flen = riscv_isa_flen (gdbarch); + if (flen == 8 + && TYPE_CODE (type) == TYPE_CODE_FLT + && TYPE_LENGTH (type) == flen + && (strcmp (TYPE_NAME (type), "builtin_type_ieee_double") == 0 + || strcmp (TYPE_NAME (type), "double") == 0)) + type = riscv_fpreg_d_type (gdbarch); } - return tdep->riscv_fpreg_q_type; -} - -/* Implement the register_type gdbarch method. */ - -static struct type * -riscv_register_type (struct gdbarch *gdbarch, int regnum) -{ - int regsize; - - if (regnum < RISCV_FIRST_FP_REGNUM) + if ((regnum == gdbarch_pc_regnum (gdbarch) + || regnum == RISCV_RA_REGNUM + || regnum == RISCV_FP_REGNUM + || regnum == RISCV_SP_REGNUM + || regnum == RISCV_GP_REGNUM + || regnum == RISCV_TP_REGNUM) + && TYPE_CODE (type) == TYPE_CODE_INT + && TYPE_LENGTH (type) == xlen) { + /* This spots the case where some interesting registers are defined + as simple integers of the expected size, we force these registers + to be pointers as we believe that is more useful. */ if (regnum == gdbarch_pc_regnum (gdbarch) - || regnum == RISCV_RA_REGNUM) - return builtin_type (gdbarch)->builtin_func_ptr; - - if (regnum == RISCV_FP_REGNUM - || regnum == RISCV_SP_REGNUM - || regnum == RISCV_GP_REGNUM - || regnum == RISCV_TP_REGNUM) - return builtin_type (gdbarch)->builtin_data_ptr; - - /* Remaining GPRs vary in size based on the current ISA. */ - regsize = riscv_isa_xlen (gdbarch); - switch (regsize) - { - case 4: - return builtin_type (gdbarch)->builtin_uint32; - case 8: - return builtin_type (gdbarch)->builtin_uint64; - case 16: - return builtin_type (gdbarch)->builtin_uint128; - default: - internal_error (__FILE__, __LINE__, - _("unknown isa regsize %i"), regsize); - } + || regnum == RISCV_RA_REGNUM) + type = builtin_type (gdbarch)->builtin_func_ptr; + else if (regnum == RISCV_FP_REGNUM + || regnum == RISCV_SP_REGNUM + || regnum == RISCV_GP_REGNUM + || regnum == RISCV_TP_REGNUM) + type = builtin_type (gdbarch)->builtin_data_ptr; } - else if (regnum <= RISCV_LAST_FP_REGNUM) - { - regsize = riscv_isa_xlen (gdbarch); - switch (regsize) - { - case 4: - return builtin_type (gdbarch)->builtin_float; - case 8: - return riscv_fpreg_d_type (gdbarch); - case 16: - return riscv_fpreg_q_type (gdbarch); - default: - internal_error (__FILE__, __LINE__, - _("unknown isa regsize %i"), regsize); - } - } - else if (regnum == RISCV_PRIV_REGNUM) - return builtin_type (gdbarch)->builtin_int8; - else - { - if (regnum == RISCV_CSR_FFLAGS_REGNUM - || regnum == RISCV_CSR_FRM_REGNUM - || regnum == RISCV_CSR_FCSR_REGNUM) - return builtin_type (gdbarch)->builtin_int32; - regsize = riscv_isa_xlen (gdbarch); - switch (regsize) - { - case 4: - return builtin_type (gdbarch)->builtin_int32; - case 8: - return builtin_type (gdbarch)->builtin_int64; - case 16: - return builtin_type (gdbarch)->builtin_int128; - default: - internal_error (__FILE__, __LINE__, - _("unknown isa regsize %i"), regsize); - } - } + return type; } /* Helper for riscv_print_registers_info, prints info for a single register @@ -682,14 +627,28 @@ riscv_print_one_register_info (struct gdbarch *gdbarch, int regnum) { const char *name = gdbarch_register_name (gdbarch, regnum); - struct value *val = value_of_register (regnum, frame); - struct type *regtype = value_type (val); + struct value *val; + struct type *regtype; int print_raw_format; enum tab_stops { value_column_1 = 15 }; fputs_filtered (name, file); print_spaces_filtered (value_column_1 - strlen (name), file); + TRY + { + val = value_of_register (regnum, frame); + regtype = value_type (val); + } + CATCH (ex, RETURN_MASK_ERROR) + { + /* Handle failure to read a register without interrupting the entire + 'info registers' flow. */ + fprintf_filtered (file, "%s\n", ex.message); + return; + } + END_CATCH + print_raw_format = (value_entirely_available (val) && !value_optimized_out (val)); @@ -904,6 +863,15 @@ riscv_register_reggroup_p (struct gdbarch *gdbarch, int regnum, || gdbarch_register_name (gdbarch, regnum)[0] == '\0') return 0; + if (regnum > RISCV_LAST_REGNUM) + { + int ret = tdesc_register_in_reggroup_p (gdbarch, regnum, reggroup); + if (ret != -1) + return ret; + + return default_register_reggroup_p (gdbarch, regnum, reggroup); + } + if (reggroup == all_reggroup) { if (regnum < RISCV_FIRST_CSR_REGNUM || regnum == RISCV_PRIV_REGNUM) @@ -926,7 +894,7 @@ riscv_register_reggroup_p (struct gdbarch *gdbarch, int regnum, else return regnum < RISCV_FIRST_FP_REGNUM; } - else if (reggroup == system_reggroup) + else if (reggroup == system_reggroup || reggroup == csr_reggroup) { if (regnum == RISCV_PRIV_REGNUM) return 1; @@ -954,7 +922,6 @@ riscv_print_registers_info (struct gdbarch *gdbarch, if (regnum != -1) { /* Print one specified register. */ - gdb_assert (regnum <= RISCV_LAST_REGNUM); if (gdbarch_register_name (gdbarch, regnum) == NULL || *(gdbarch_register_name (gdbarch, regnum)) == '\0') error (_("Not a valid register for the current processor type")); @@ -981,7 +948,7 @@ riscv_print_registers_info (struct gdbarch *gdbarch, continue; /* Is the register in the group we're interested in? */ - if (!riscv_register_reggroup_p (gdbarch, regnum, reggroup)) + if (!gdbarch_register_reggroup_p (gdbarch, regnum, reggroup)) continue; riscv_print_one_register_info (gdbarch, file, frame, regnum); @@ -2822,36 +2789,26 @@ static const struct frame_unwind riscv_frame_unwind = /*.prev_arch =*/ NULL, }; -/* Initialize the current architecture based on INFO. If possible, - re-use an architecture from ARCHES, which is a list of - architectures already created during this debugging session. - - Called e.g. at program startup, when reading a core file, and when - reading a binary file. */ +/* Find a suitable default target description. Use the contents of INFO, + specifically the bfd object being executed, to guide the selection of a + suitable default target description. */ -static struct gdbarch * -riscv_gdbarch_init (struct gdbarch_info info, - struct gdbarch_list *arches) +static struct target_desc * +riscv_find_default_target_description (const struct gdbarch_info info) { - struct gdbarch *gdbarch; - struct gdbarch_tdep *tdep; - struct gdbarch_tdep tmp_tdep; - int i; - - /* Ideally, we'd like to get as much information from the target for - things like register size, and whether the target has floating point - hardware. However, there are some things that the target can't tell - us, like, what ABI is being used. + struct riscv_gdbarch_features features; - So, for now, we take as much information as possible from the ELF, - including things like register size, and FP hardware support, along - with information about the ABI. - - Information about this target is built up in TMP_TDEP, and then we - look for an existing gdbarch in ARCHES that matches TMP_TDEP. If no - match is found we'll create a new gdbarch and copy TMP_TDEP over. */ - memset (&tmp_tdep, 0, sizeof (tmp_tdep)); + /* Setup some arbitrary defaults. */ + features.xlen = 8; + features.flen = 0; + features.hw_float_abi = false; + /* Now try to improve on the defaults by looking at the binary we are + going to execute. We assume the user knows what they are doing and + that the target will match the binary. Remember, this code path is + only used at all if the target hasn't given us a description, so this + is really a last ditched effort to do something sane before giving + up. */ if (info.abfd != NULL && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour) { @@ -2859,26 +2816,22 @@ riscv_gdbarch_init (struct gdbarch_info info, int e_flags = elf_elfheader (info.abfd)->e_flags; if (eclass == ELFCLASS32) - tmp_tdep.abi.fields.base_len = 1; + features.xlen = 4; else if (eclass == ELFCLASS64) - tmp_tdep.abi.fields.base_len = 2; + features.xlen = 8; else - internal_error (__FILE__, __LINE__, + internal_error (__FILE__, __LINE__, _("unknown ELF header class %d"), eclass); - if (e_flags & EF_RISCV_RVC) - tmp_tdep.core_features |= (1 << ('C' - 'A')); - if (e_flags & EF_RISCV_FLOAT_ABI_DOUBLE) { - tmp_tdep.abi.fields.float_abi = 2; - tmp_tdep.core_features |= (1 << ('D' - 'A')); - tmp_tdep.core_features |= (1 << ('F' - 'A')); + features.flen = 8; + features.hw_float_abi = true; } else if (e_flags & EF_RISCV_FLOAT_ABI_SINGLE) { - tmp_tdep.abi.fields.float_abi = 1; - tmp_tdep.core_features |= (1 << ('F' - 'A')); + features.flen = 4; + features.hw_float_abi = true; } } else @@ -2886,25 +2839,210 @@ riscv_gdbarch_init (struct gdbarch_info info, const struct bfd_arch_info *binfo = info.bfd_arch_info; if (binfo->bits_per_word == 32) - tmp_tdep.abi.fields.base_len = 1; + features.xlen = 4; else if (binfo->bits_per_word == 64) - tmp_tdep.abi.fields.base_len = 2; + features.xlen = 8; else - internal_error (__FILE__, __LINE__, _("unknown bits_per_word %d"), + internal_error (__FILE__, __LINE__, _("unknown bits_per_word %d"), binfo->bits_per_word); } + /* Now build a target description based on the feature set. */ + return riscv_create_target_description (features); +} + +/* All of the registers in REG_SET are checked for in FEATURE, TDESC_DATA + is updated with the register numbers for each register as listed in + REG_SET. If any register marked as required in REG_SET is not found in + FEATURE then this function returns false, otherwise, it returns true. */ + +static bool +riscv_check_tdesc_feature (struct tdesc_arch_data *tdesc_data, + const struct tdesc_feature *feature, + const struct riscv_register_feature *reg_set) +{ + for (const auto ® : reg_set->registers) + { + bool found = false; + + for (const char *name : reg.names) + { + found = + tdesc_numbered_register (feature, tdesc_data, reg.regnum, name); + + if (found) + break; + } + + if (!found && reg.required_p) + return false; + } + + return true; +} + +/* Add all the expected register sets into GDBARCH. */ + +static void +riscv_add_reggroups (struct gdbarch *gdbarch) +{ + /* Add predefined register groups. */ + reggroup_add (gdbarch, all_reggroup); + reggroup_add (gdbarch, save_reggroup); + reggroup_add (gdbarch, restore_reggroup); + reggroup_add (gdbarch, system_reggroup); + reggroup_add (gdbarch, vector_reggroup); + reggroup_add (gdbarch, general_reggroup); + reggroup_add (gdbarch, float_reggroup); + + /* Add RISC-V specific register groups. */ + reggroup_add (gdbarch, csr_reggroup); +} + +/* Create register aliases for all the alternative names that exist for + registers in REG_SET. */ + +static void +riscv_setup_register_aliases (struct gdbarch *gdbarch, + const struct riscv_register_feature *reg_set) +{ + for (auto ® : reg_set->registers) + { + /* The first item in the names list is the preferred name for the + register, this is what RISCV_REGISTER_NAME returns, and so we + don't need to create an alias with that name here. */ + for (int i = 1; i < reg.names.size (); ++i) + user_reg_add (gdbarch, reg.names[i], value_of_riscv_user_reg, + ®.regnum); + } +} + +/* Initialize the current architecture based on INFO. If possible, + re-use an architecture from ARCHES, which is a list of + architectures already created during this debugging session. + + Called e.g. at program startup, when reading a core file, and when + reading a binary file. */ + +static struct gdbarch * +riscv_gdbarch_init (struct gdbarch_info info, + struct gdbarch_list *arches) +{ + struct gdbarch *gdbarch; + struct gdbarch_tdep *tdep; + struct riscv_gdbarch_features features; + const struct target_desc *tdesc = info.target_desc; + + /* Ensure we always have a target description. */ + if (!tdesc_has_registers (tdesc)) + tdesc = riscv_find_default_target_description (info); + gdb_assert (tdesc); + + if (riscv_debug_gdbarch) + fprintf_unfiltered (gdb_stdlog, "Have got a target description\n"); + + const struct tdesc_feature *feature_cpu + = tdesc_find_feature (tdesc, riscv_xreg_feature.name); + const struct tdesc_feature *feature_fpu + = tdesc_find_feature (tdesc, riscv_freg_feature.name); + const struct tdesc_feature *feature_virtual + = tdesc_find_feature (tdesc, riscv_virtual_feature.name); + const struct tdesc_feature *feature_csr + = tdesc_find_feature (tdesc, riscv_csr_feature.name); + + if (feature_cpu == NULL) + return NULL; + + struct tdesc_arch_data *tdesc_data = tdesc_data_alloc (); + + bool valid_p = riscv_check_tdesc_feature (tdesc_data, + feature_cpu, + &riscv_xreg_feature); + if (valid_p) + { + /* Check that all of the core cpu registers have the same bitsize. */ + int xlen_bitsize = tdesc_register_bitsize (feature_cpu, "pc"); + + for (auto &tdesc_reg : feature_cpu->registers) + valid_p &= (tdesc_reg->bitsize == xlen_bitsize); + + if (riscv_debug_gdbarch) + fprintf_filtered + (gdb_stdlog, + "From target-description, xlen = %d\n", xlen_bitsize); + + features.xlen = (xlen_bitsize / 8); + } + + if (feature_fpu != NULL) + { + valid_p &= riscv_check_tdesc_feature (tdesc_data, feature_fpu, + &riscv_freg_feature); + + int bitsize = tdesc_register_bitsize (feature_fpu, "ft0"); + features.flen = (bitsize / 8); + features.hw_float_abi = true; + + if (riscv_debug_gdbarch) + fprintf_filtered + (gdb_stdlog, + "From target-description, flen = %d\n", bitsize); + } + else + { + features.flen = 0; + features.hw_float_abi = false; + + if (riscv_debug_gdbarch) + fprintf_filtered + (gdb_stdlog, + "No FPU in target-description, assume soft-float ABI\n"); + } + + if (feature_virtual) + riscv_check_tdesc_feature (tdesc_data, feature_virtual, + &riscv_virtual_feature); + + if (feature_csr) + riscv_check_tdesc_feature (tdesc_data, feature_csr, + &riscv_csr_feature); + + if (!valid_p) + { + if (riscv_debug_gdbarch) + fprintf_unfiltered (gdb_stdlog, "Target description is not valid\n"); + tdesc_data_cleanup (tdesc_data); + return NULL; + } + /* Find a candidate among the list of pre-declared architectures. */ for (arches = gdbarch_list_lookup_by_info (arches, &info); arches != NULL; arches = gdbarch_list_lookup_by_info (arches->next, &info)) - if (gdbarch_tdep (arches->gdbarch)->abi.value == tmp_tdep.abi.value) + { + /* Check that the feature set of the ARCHES matches the feature set + we are looking for. If it doesn't then we can't reuse this + gdbarch. */ + struct gdbarch_tdep *other_tdep = gdbarch_tdep (arches->gdbarch); + + if (other_tdep->features.hw_float_abi != features.hw_float_abi + || other_tdep->features.xlen != features.xlen + || other_tdep->features.flen != features.flen) + continue; + + break; + } + + if (arches != NULL) + { + tdesc_data_cleanup (tdesc_data); return arches->gdbarch; + } /* None found, so create a new architecture from the information provided. */ - tdep = (struct gdbarch_tdep *) xmalloc (sizeof *tdep); + tdep = new (struct gdbarch_tdep); gdbarch = gdbarch_alloc (&info, tdep); - memcpy (tdep, &tmp_tdep, sizeof (tmp_tdep)); + tdep->features = features; /* Target data types. */ set_gdbarch_short_bit (gdbarch, 16); @@ -2924,19 +3062,6 @@ riscv_gdbarch_init (struct gdbarch_info info, set_gdbarch_sw_breakpoint_from_kind (gdbarch, riscv_sw_breakpoint_from_kind); set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); - /* Register architecture. */ - set_gdbarch_num_regs (gdbarch, RISCV_LAST_REGNUM + 1); - set_gdbarch_sp_regnum (gdbarch, RISCV_SP_REGNUM); - set_gdbarch_pc_regnum (gdbarch, RISCV_PC_REGNUM); - set_gdbarch_ps_regnum (gdbarch, RISCV_FP_REGNUM); - set_gdbarch_deprecated_fp_regnum (gdbarch, RISCV_FP_REGNUM); - - /* Functions to supply register information. */ - set_gdbarch_register_name (gdbarch, riscv_register_name); - set_gdbarch_register_type (gdbarch, riscv_register_type); - set_gdbarch_print_registers_info (gdbarch, riscv_print_registers_info); - set_gdbarch_register_reggroup_p (gdbarch, riscv_register_reggroup_p); - /* Functions to analyze frames. */ set_gdbarch_skip_prologue (gdbarch, riscv_skip_prologue); set_gdbarch_inner_than (gdbarch, core_addr_lessthan); @@ -2957,9 +3082,49 @@ riscv_gdbarch_init (struct gdbarch_info info, dwarf2_append_unwinders (gdbarch); frame_unwind_append_unwinder (gdbarch, &riscv_frame_unwind); - for (i = 0; i < ARRAY_SIZE (riscv_register_aliases); ++i) - user_reg_add (gdbarch, riscv_register_aliases[i].name, - value_of_riscv_user_reg, &riscv_register_aliases[i].regnum); + /* Register architecture. */ + riscv_add_reggroups (gdbarch); + + /* We reserve all possible register numbers for the known registers. + This means the target description mechanism will add any target + specific registers after this number. This helps make debugging GDB + just a little easier. */ + set_gdbarch_num_regs (gdbarch, RISCV_LAST_REGNUM + 1); + + /* We don't have to provide the count of 0 here (its the default) but + include this line to make it explicit that, right now, we don't have + any pseudo registers on RISC-V. */ + set_gdbarch_num_pseudo_regs (gdbarch, 0); + + /* Some specific register numbers GDB likes to know about. */ + set_gdbarch_sp_regnum (gdbarch, RISCV_SP_REGNUM); + set_gdbarch_pc_regnum (gdbarch, RISCV_PC_REGNUM); + + set_gdbarch_print_registers_info (gdbarch, riscv_print_registers_info); + + /* Finalise the target description registers. */ + tdesc_use_registers (gdbarch, tdesc, tdesc_data); + + /* Override the register type callback setup by the target description + mechanism. This allows us to provide special type for floating point + registers. */ + set_gdbarch_register_type (gdbarch, riscv_register_type); + + /* Override the register name callback setup by the target description + mechanism. This allows us to force our preferred names for the + registers, no matter what the target description called them. */ + set_gdbarch_register_name (gdbarch, riscv_register_name); + + /* Override the register group callback setup by the target description + mechanism. This allows us to force registers into the groups we + want, ignoring what the target tells us. */ + set_gdbarch_register_reggroup_p (gdbarch, riscv_register_reggroup_p); + + /* Create register aliases for alternative register names. */ + riscv_setup_register_aliases (gdbarch, &riscv_xreg_feature); + if (riscv_has_fp_regs (gdbarch)) + riscv_setup_register_aliases (gdbarch, &riscv_freg_feature); + riscv_setup_register_aliases (gdbarch, &riscv_csr_feature); /* Hook in OS ABI-specific overrides, if they have been registered. */ gdbarch_init_osabi (info, gdbarch); @@ -3106,9 +3271,20 @@ riscv_software_single_step (struct regcache *regcache) return {next_pc}; } +/* Create RISC-V specific reggroups. */ + +static void +riscv_init_reggroups () +{ + csr_reggroup = reggroup_new ("csr", USER_REGGROUP); +} + void _initialize_riscv_tdep (void) { + riscv_create_csr_aliases (); + riscv_init_reggroups (); + gdbarch_register (bfd_arch_riscv, riscv_gdbarch_init, NULL); /* Add root prefix command for all "set debug riscv" and "show debug @@ -3153,6 +3329,16 @@ of the stack unwinding mechanism."), show_riscv_debug_variable, &setdebugriscvcmdlist, &showdebugriscvcmdlist); + add_setshow_zuinteger_cmd ("gdbarch", class_maintenance, + &riscv_debug_gdbarch, _("\ +Set riscv gdbarch initialisation debugging."), _("\ +Show riscv gdbarch initialisation debugging."), _("\ +When non-zero, print debugging information for the riscv gdbarch\n\ +initialisation process."), + NULL, + show_riscv_debug_variable, + &setdebugriscvcmdlist, &showdebugriscvcmdlist); + /* Add root prefix command for all "set riscv" and "show riscv" commands. */ add_prefix_cmd ("riscv", no_class, set_riscv_command, _("RISC-V specific commands."), diff --git a/gdb/riscv-tdep.h b/gdb/riscv-tdep.h index 2cb51b16c53..59ad37df6ce 100644 --- a/gdb/riscv-tdep.h +++ b/gdb/riscv-tdep.h @@ -21,6 +21,8 @@ #ifndef RISCV_TDEP_H #define RISCV_TDEP_H +#include "arch/riscv.h" + /* RiscV register numbers. */ enum { @@ -57,31 +59,12 @@ enum /* RISC-V specific per-architecture information. */ struct gdbarch_tdep { - union - { - /* Provide access to the whole ABI in one value. */ - unsigned value; - - struct - { - /* Encode the base machine length following the same rules as in the - MISA register. */ - unsigned base_len : 2; - - /* Encode which floating point ABI is in use following the same rules - as the ELF e_flags field. */ - unsigned float_abi : 2; - } fields; - } abi; - - /* Only the least significant 26 bits are (possibly) valid, and indicate - features that are supported on the target. These could be cached from - the target, or read from the executable when available. */ - unsigned core_features; + /* Features about the target that impact how the gdbarch is configured. + Two gdbarch instances are compatible only if this field matches. */ + struct riscv_gdbarch_features features; /* ISA-specific data types. */ - struct type *riscv_fpreg_d_type; - struct type *riscv_fpreg_q_type; + struct type *riscv_fpreg_d_type = nullptr; }; diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c index bdd29c0f2b5..20604bb4b96 100644 --- a/gdb/target-descriptions.c +++ b/gdb/target-descriptions.c @@ -1716,6 +1716,7 @@ maint_print_c_tdesc_cmd (const char *args, int from_tty) if (startswith (filename_after_features.c_str (), "i386/32bit-") || startswith (filename_after_features.c_str (), "i386/64bit-") || startswith (filename_after_features.c_str (), "i386/x32-core.xml") + || startswith (filename_after_features.c_str (), "riscv/") || startswith (filename_after_features.c_str (), "tic6x-") || startswith (filename_after_features.c_str (), "aarch64")) {