This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] gdb/riscv: Add target description support


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b5ffee3181d157a4d964f62344ac827142e37bde

commit b5ffee3181d157a4d964f62344ac827142e37bde
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date:   Mon Oct 29 15:10:52 2018 +0000

    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:
---
 gdb/ChangeLog                         |  66 +++
 gdb/Makefile.in                       |   2 +
 gdb/NEWS                              |   2 +
 gdb/arch/riscv.c                      |  69 +++
 gdb/arch/riscv.h                      |  64 +++
 gdb/configure.tgt                     |   9 +-
 gdb/doc/ChangeLog                     |   5 +
 gdb/doc/gdb.texinfo                   |  36 ++
 gdb/features/Makefile                 |  11 +
 gdb/features/riscv/32bit-cpu.c        |  46 ++
 gdb/features/riscv/32bit-cpu.xml      |  43 ++
 gdb/features/riscv/32bit-csr.c        | 253 ++++++++++
 gdb/features/riscv/32bit-csr.xml      | 250 ++++++++++
 gdb/features/riscv/32bit-fpu.c        |  48 ++
 gdb/features/riscv/32bit-fpu.xml      |  46 ++
 gdb/features/riscv/64bit-cpu.c        |  46 ++
 gdb/features/riscv/64bit-cpu.xml      |  43 ++
 gdb/features/riscv/64bit-csr.c        | 253 ++++++++++
 gdb/features/riscv/64bit-csr.xml      | 250 ++++++++++
 gdb/features/riscv/64bit-fpu.c        |  56 +++
 gdb/features/riscv/64bit-fpu.xml      |  52 ++
 gdb/features/riscv/rebuild-csr-xml.sh |  29 ++
 gdb/riscv-tdep.c                      | 888 ++++++++++++++++++++--------------
 gdb/riscv-tdep.h                      |  29 +-
 gdb/target-descriptions.c             |   1 +
 25 files changed, 2220 insertions(+), 377 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d81d500..1630bd8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,69 @@
+2018-11-21  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* 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  <palves@redhat.com>
 
 	* valops.c (find_method_list, value_find_oload_method_list)
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 8bd78a6..4001bcb 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 ef037de..9ecbb83 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 0000000..ca2238d
--- /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 <http://www.gnu.org/licenses/>.  */
+
+#include "common-defs.h"
+#include "riscv.h"
+#include <stdlib.h>
+
+#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 0000000..0079440
--- /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 <http://www.gnu.org/licenses/>.  */
+
+#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 e1f5e31..9b646fa 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 28e1252..59e7330 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2018-11-21  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* gdb.texinfo (Standard Target Features): Add RISC-V Features
+	sub-section.
+
 2018-11-20  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
 
 	* gdb.texinfo (Examining the Symbol Table): Document language choice
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 3c3915b..7350d94 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 150fef2..ff2e57c 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 0000000..64686db
--- /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 0000000..c02f86c
--- /dev/null
+++ b/gdb/features/riscv/32bit-cpu.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.cpu">
+  <reg name="zero" bitsize="32" type="int"/>
+  <reg name="ra" bitsize="32" type="code_ptr"/>
+  <reg name="sp" bitsize="32" type="data_ptr"/>
+  <reg name="gp" bitsize="32" type="data_ptr"/>
+  <reg name="tp" bitsize="32" type="data_ptr"/>
+  <reg name="t0" bitsize="32" type="int"/>
+  <reg name="t1" bitsize="32" type="int"/>
+  <reg name="t2" bitsize="32" type="int"/>
+  <reg name="fp" bitsize="32" type="data_ptr"/>
+  <reg name="s1" bitsize="32" type="int"/>
+  <reg name="a0" bitsize="32" type="int"/>
+  <reg name="a1" bitsize="32" type="int"/>
+  <reg name="a2" bitsize="32" type="int"/>
+  <reg name="a3" bitsize="32" type="int"/>
+  <reg name="a4" bitsize="32" type="int"/>
+  <reg name="a5" bitsize="32" type="int"/>
+  <reg name="a6" bitsize="32" type="int"/>
+  <reg name="a7" bitsize="32" type="int"/>
+  <reg name="s2" bitsize="32" type="int"/>
+  <reg name="s3" bitsize="32" type="int"/>
+  <reg name="s4" bitsize="32" type="int"/>
+  <reg name="s5" bitsize="32" type="int"/>
+  <reg name="s6" bitsize="32" type="int"/>
+  <reg name="s7" bitsize="32" type="int"/>
+  <reg name="s8" bitsize="32" type="int"/>
+  <reg name="s9" bitsize="32" type="int"/>
+  <reg name="s10" bitsize="32" type="int"/>
+  <reg name="s11" bitsize="32" type="int"/>
+  <reg name="t3" bitsize="32" type="int"/>
+  <reg name="t4" bitsize="32" type="int"/>
+  <reg name="t5" bitsize="32" type="int"/>
+  <reg name="t6" bitsize="32" type="int"/>
+  <reg name="pc" bitsize="32" type="code_ptr"/>
+</feature>
diff --git a/gdb/features/riscv/32bit-csr.c b/gdb/features/riscv/32bit-csr.c
new file mode 100644
index 0000000..711e958
--- /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 0000000..4aea9e6
--- /dev/null
+++ b/gdb/features/riscv/32bit-csr.xml
@@ -0,0 +1,250 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.csr">
+  <reg name="ustatus" bitsize="32"/>
+  <reg name="uie" bitsize="32"/>
+  <reg name="utvec" bitsize="32"/>
+  <reg name="uscratch" bitsize="32"/>
+  <reg name="uepc" bitsize="32"/>
+  <reg name="ucause" bitsize="32"/>
+  <reg name="utval" bitsize="32"/>
+  <reg name="uip" bitsize="32"/>
+  <reg name="fflags" bitsize="32"/>
+  <reg name="frm" bitsize="32"/>
+  <reg name="fcsr" bitsize="32"/>
+  <reg name="cycle" bitsize="32"/>
+  <reg name="time" bitsize="32"/>
+  <reg name="instret" bitsize="32"/>
+  <reg name="hpmcounter3" bitsize="32"/>
+  <reg name="hpmcounter4" bitsize="32"/>
+  <reg name="hpmcounter5" bitsize="32"/>
+  <reg name="hpmcounter6" bitsize="32"/>
+  <reg name="hpmcounter7" bitsize="32"/>
+  <reg name="hpmcounter8" bitsize="32"/>
+  <reg name="hpmcounter9" bitsize="32"/>
+  <reg name="hpmcounter10" bitsize="32"/>
+  <reg name="hpmcounter11" bitsize="32"/>
+  <reg name="hpmcounter12" bitsize="32"/>
+  <reg name="hpmcounter13" bitsize="32"/>
+  <reg name="hpmcounter14" bitsize="32"/>
+  <reg name="hpmcounter15" bitsize="32"/>
+  <reg name="hpmcounter16" bitsize="32"/>
+  <reg name="hpmcounter17" bitsize="32"/>
+  <reg name="hpmcounter18" bitsize="32"/>
+  <reg name="hpmcounter19" bitsize="32"/>
+  <reg name="hpmcounter20" bitsize="32"/>
+  <reg name="hpmcounter21" bitsize="32"/>
+  <reg name="hpmcounter22" bitsize="32"/>
+  <reg name="hpmcounter23" bitsize="32"/>
+  <reg name="hpmcounter24" bitsize="32"/>
+  <reg name="hpmcounter25" bitsize="32"/>
+  <reg name="hpmcounter26" bitsize="32"/>
+  <reg name="hpmcounter27" bitsize="32"/>
+  <reg name="hpmcounter28" bitsize="32"/>
+  <reg name="hpmcounter29" bitsize="32"/>
+  <reg name="hpmcounter30" bitsize="32"/>
+  <reg name="hpmcounter31" bitsize="32"/>
+  <reg name="cycleh" bitsize="32"/>
+  <reg name="timeh" bitsize="32"/>
+  <reg name="instreth" bitsize="32"/>
+  <reg name="hpmcounter3h" bitsize="32"/>
+  <reg name="hpmcounter4h" bitsize="32"/>
+  <reg name="hpmcounter5h" bitsize="32"/>
+  <reg name="hpmcounter6h" bitsize="32"/>
+  <reg name="hpmcounter7h" bitsize="32"/>
+  <reg name="hpmcounter8h" bitsize="32"/>
+  <reg name="hpmcounter9h" bitsize="32"/>
+  <reg name="hpmcounter10h" bitsize="32"/>
+  <reg name="hpmcounter11h" bitsize="32"/>
+  <reg name="hpmcounter12h" bitsize="32"/>
+  <reg name="hpmcounter13h" bitsize="32"/>
+  <reg name="hpmcounter14h" bitsize="32"/>
+  <reg name="hpmcounter15h" bitsize="32"/>
+  <reg name="hpmcounter16h" bitsize="32"/>
+  <reg name="hpmcounter17h" bitsize="32"/>
+  <reg name="hpmcounter18h" bitsize="32"/>
+  <reg name="hpmcounter19h" bitsize="32"/>
+  <reg name="hpmcounter20h" bitsize="32"/>
+  <reg name="hpmcounter21h" bitsize="32"/>
+  <reg name="hpmcounter22h" bitsize="32"/>
+  <reg name="hpmcounter23h" bitsize="32"/>
+  <reg name="hpmcounter24h" bitsize="32"/>
+  <reg name="hpmcounter25h" bitsize="32"/>
+  <reg name="hpmcounter26h" bitsize="32"/>
+  <reg name="hpmcounter27h" bitsize="32"/>
+  <reg name="hpmcounter28h" bitsize="32"/>
+  <reg name="hpmcounter29h" bitsize="32"/>
+  <reg name="hpmcounter30h" bitsize="32"/>
+  <reg name="hpmcounter31h" bitsize="32"/>
+  <reg name="sstatus" bitsize="32"/>
+  <reg name="sedeleg" bitsize="32"/>
+  <reg name="sideleg" bitsize="32"/>
+  <reg name="sie" bitsize="32"/>
+  <reg name="stvec" bitsize="32"/>
+  <reg name="scounteren" bitsize="32"/>
+  <reg name="sscratch" bitsize="32"/>
+  <reg name="sepc" bitsize="32"/>
+  <reg name="scause" bitsize="32"/>
+  <reg name="stval" bitsize="32"/>
+  <reg name="sip" bitsize="32"/>
+  <reg name="satp" bitsize="32"/>
+  <reg name="mvendorid" bitsize="32"/>
+  <reg name="marchid" bitsize="32"/>
+  <reg name="mimpid" bitsize="32"/>
+  <reg name="mhartid" bitsize="32"/>
+  <reg name="mstatus" bitsize="32"/>
+  <reg name="misa" bitsize="32"/>
+  <reg name="medeleg" bitsize="32"/>
+  <reg name="mideleg" bitsize="32"/>
+  <reg name="mie" bitsize="32"/>
+  <reg name="mtvec" bitsize="32"/>
+  <reg name="mcounteren" bitsize="32"/>
+  <reg name="mscratch" bitsize="32"/>
+  <reg name="mepc" bitsize="32"/>
+  <reg name="mcause" bitsize="32"/>
+  <reg name="mtval" bitsize="32"/>
+  <reg name="mip" bitsize="32"/>
+  <reg name="pmpcfg0" bitsize="32"/>
+  <reg name="pmpcfg1" bitsize="32"/>
+  <reg name="pmpcfg2" bitsize="32"/>
+  <reg name="pmpcfg3" bitsize="32"/>
+  <reg name="pmpaddr0" bitsize="32"/>
+  <reg name="pmpaddr1" bitsize="32"/>
+  <reg name="pmpaddr2" bitsize="32"/>
+  <reg name="pmpaddr3" bitsize="32"/>
+  <reg name="pmpaddr4" bitsize="32"/>
+  <reg name="pmpaddr5" bitsize="32"/>
+  <reg name="pmpaddr6" bitsize="32"/>
+  <reg name="pmpaddr7" bitsize="32"/>
+  <reg name="pmpaddr8" bitsize="32"/>
+  <reg name="pmpaddr9" bitsize="32"/>
+  <reg name="pmpaddr10" bitsize="32"/>
+  <reg name="pmpaddr11" bitsize="32"/>
+  <reg name="pmpaddr12" bitsize="32"/>
+  <reg name="pmpaddr13" bitsize="32"/>
+  <reg name="pmpaddr14" bitsize="32"/>
+  <reg name="pmpaddr15" bitsize="32"/>
+  <reg name="mcycle" bitsize="32"/>
+  <reg name="minstret" bitsize="32"/>
+  <reg name="mhpmcounter3" bitsize="32"/>
+  <reg name="mhpmcounter4" bitsize="32"/>
+  <reg name="mhpmcounter5" bitsize="32"/>
+  <reg name="mhpmcounter6" bitsize="32"/>
+  <reg name="mhpmcounter7" bitsize="32"/>
+  <reg name="mhpmcounter8" bitsize="32"/>
+  <reg name="mhpmcounter9" bitsize="32"/>
+  <reg name="mhpmcounter10" bitsize="32"/>
+  <reg name="mhpmcounter11" bitsize="32"/>
+  <reg name="mhpmcounter12" bitsize="32"/>
+  <reg name="mhpmcounter13" bitsize="32"/>
+  <reg name="mhpmcounter14" bitsize="32"/>
+  <reg name="mhpmcounter15" bitsize="32"/>
+  <reg name="mhpmcounter16" bitsize="32"/>
+  <reg name="mhpmcounter17" bitsize="32"/>
+  <reg name="mhpmcounter18" bitsize="32"/>
+  <reg name="mhpmcounter19" bitsize="32"/>
+  <reg name="mhpmcounter20" bitsize="32"/>
+  <reg name="mhpmcounter21" bitsize="32"/>
+  <reg name="mhpmcounter22" bitsize="32"/>
+  <reg name="mhpmcounter23" bitsize="32"/>
+  <reg name="mhpmcounter24" bitsize="32"/>
+  <reg name="mhpmcounter25" bitsize="32"/>
+  <reg name="mhpmcounter26" bitsize="32"/>
+  <reg name="mhpmcounter27" bitsize="32"/>
+  <reg name="mhpmcounter28" bitsize="32"/>
+  <reg name="mhpmcounter29" bitsize="32"/>
+  <reg name="mhpmcounter30" bitsize="32"/>
+  <reg name="mhpmcounter31" bitsize="32"/>
+  <reg name="mcycleh" bitsize="32"/>
+  <reg name="minstreth" bitsize="32"/>
+  <reg name="mhpmcounter3h" bitsize="32"/>
+  <reg name="mhpmcounter4h" bitsize="32"/>
+  <reg name="mhpmcounter5h" bitsize="32"/>
+  <reg name="mhpmcounter6h" bitsize="32"/>
+  <reg name="mhpmcounter7h" bitsize="32"/>
+  <reg name="mhpmcounter8h" bitsize="32"/>
+  <reg name="mhpmcounter9h" bitsize="32"/>
+  <reg name="mhpmcounter10h" bitsize="32"/>
+  <reg name="mhpmcounter11h" bitsize="32"/>
+  <reg name="mhpmcounter12h" bitsize="32"/>
+  <reg name="mhpmcounter13h" bitsize="32"/>
+  <reg name="mhpmcounter14h" bitsize="32"/>
+  <reg name="mhpmcounter15h" bitsize="32"/>
+  <reg name="mhpmcounter16h" bitsize="32"/>
+  <reg name="mhpmcounter17h" bitsize="32"/>
+  <reg name="mhpmcounter18h" bitsize="32"/>
+  <reg name="mhpmcounter19h" bitsize="32"/>
+  <reg name="mhpmcounter20h" bitsize="32"/>
+  <reg name="mhpmcounter21h" bitsize="32"/>
+  <reg name="mhpmcounter22h" bitsize="32"/>
+  <reg name="mhpmcounter23h" bitsize="32"/>
+  <reg name="mhpmcounter24h" bitsize="32"/>
+  <reg name="mhpmcounter25h" bitsize="32"/>
+  <reg name="mhpmcounter26h" bitsize="32"/>
+  <reg name="mhpmcounter27h" bitsize="32"/>
+  <reg name="mhpmcounter28h" bitsize="32"/>
+  <reg name="mhpmcounter29h" bitsize="32"/>
+  <reg name="mhpmcounter30h" bitsize="32"/>
+  <reg name="mhpmcounter31h" bitsize="32"/>
+  <reg name="mhpmevent3" bitsize="32"/>
+  <reg name="mhpmevent4" bitsize="32"/>
+  <reg name="mhpmevent5" bitsize="32"/>
+  <reg name="mhpmevent6" bitsize="32"/>
+  <reg name="mhpmevent7" bitsize="32"/>
+  <reg name="mhpmevent8" bitsize="32"/>
+  <reg name="mhpmevent9" bitsize="32"/>
+  <reg name="mhpmevent10" bitsize="32"/>
+  <reg name="mhpmevent11" bitsize="32"/>
+  <reg name="mhpmevent12" bitsize="32"/>
+  <reg name="mhpmevent13" bitsize="32"/>
+  <reg name="mhpmevent14" bitsize="32"/>
+  <reg name="mhpmevent15" bitsize="32"/>
+  <reg name="mhpmevent16" bitsize="32"/>
+  <reg name="mhpmevent17" bitsize="32"/>
+  <reg name="mhpmevent18" bitsize="32"/>
+  <reg name="mhpmevent19" bitsize="32"/>
+  <reg name="mhpmevent20" bitsize="32"/>
+  <reg name="mhpmevent21" bitsize="32"/>
+  <reg name="mhpmevent22" bitsize="32"/>
+  <reg name="mhpmevent23" bitsize="32"/>
+  <reg name="mhpmevent24" bitsize="32"/>
+  <reg name="mhpmevent25" bitsize="32"/>
+  <reg name="mhpmevent26" bitsize="32"/>
+  <reg name="mhpmevent27" bitsize="32"/>
+  <reg name="mhpmevent28" bitsize="32"/>
+  <reg name="mhpmevent29" bitsize="32"/>
+  <reg name="mhpmevent30" bitsize="32"/>
+  <reg name="mhpmevent31" bitsize="32"/>
+  <reg name="tselect" bitsize="32"/>
+  <reg name="tdata1" bitsize="32"/>
+  <reg name="tdata2" bitsize="32"/>
+  <reg name="tdata3" bitsize="32"/>
+  <reg name="dcsr" bitsize="32"/>
+  <reg name="dpc" bitsize="32"/>
+  <reg name="dscratch" bitsize="32"/>
+  <reg name="hstatus" bitsize="32"/>
+  <reg name="hedeleg" bitsize="32"/>
+  <reg name="hideleg" bitsize="32"/>
+  <reg name="hie" bitsize="32"/>
+  <reg name="htvec" bitsize="32"/>
+  <reg name="hscratch" bitsize="32"/>
+  <reg name="hepc" bitsize="32"/>
+  <reg name="hcause" bitsize="32"/>
+  <reg name="hbadaddr" bitsize="32"/>
+  <reg name="hip" bitsize="32"/>
+  <reg name="mbase" bitsize="32"/>
+  <reg name="mbound" bitsize="32"/>
+  <reg name="mibase" bitsize="32"/>
+  <reg name="mibound" bitsize="32"/>
+  <reg name="mdbase" bitsize="32"/>
+  <reg name="mdbound" bitsize="32"/>
+  <reg name="mucounteren" bitsize="32"/>
+  <reg name="mscounteren" bitsize="32"/>
+  <reg name="mhcounteren" bitsize="32"/>
+</feature>
diff --git a/gdb/features/riscv/32bit-fpu.c b/gdb/features/riscv/32bit-fpu.c
new file mode 100644
index 0000000..22e80d6
--- /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 0000000..783287d
--- /dev/null
+++ b/gdb/features/riscv/32bit-fpu.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.fpu">
+  <reg name="ft0" bitsize="32" type="ieee_single"/>
+  <reg name="ft1" bitsize="32" type="ieee_single"/>
+  <reg name="ft2" bitsize="32" type="ieee_single"/>
+  <reg name="ft3" bitsize="32" type="ieee_single"/>
+  <reg name="ft4" bitsize="32" type="ieee_single"/>
+  <reg name="ft5" bitsize="32" type="ieee_single"/>
+  <reg name="ft6" bitsize="32" type="ieee_single"/>
+  <reg name="ft7" bitsize="32" type="ieee_single"/>
+  <reg name="fs0" bitsize="32" type="ieee_single"/>
+  <reg name="fs1" bitsize="32" type="ieee_single"/>
+  <reg name="fa0" bitsize="32" type="ieee_single"/>
+  <reg name="fa1" bitsize="32" type="ieee_single"/>
+  <reg name="fa2" bitsize="32" type="ieee_single"/>
+  <reg name="fa3" bitsize="32" type="ieee_single"/>
+  <reg name="fa4" bitsize="32" type="ieee_single"/>
+  <reg name="fa5" bitsize="32" type="ieee_single"/>
+  <reg name="fa6" bitsize="32" type="ieee_single"/>
+  <reg name="fa7" bitsize="32" type="ieee_single"/>
+  <reg name="fs2" bitsize="32" type="ieee_single"/>
+  <reg name="fs3" bitsize="32" type="ieee_single"/>
+  <reg name="fs4" bitsize="32" type="ieee_single"/>
+  <reg name="fs5" bitsize="32" type="ieee_single"/>
+  <reg name="fs6" bitsize="32" type="ieee_single"/>
+  <reg name="fs7" bitsize="32" type="ieee_single"/>
+  <reg name="fs8" bitsize="32" type="ieee_single"/>
+  <reg name="fs9" bitsize="32" type="ieee_single"/>
+  <reg name="fs10" bitsize="32" type="ieee_single"/>
+  <reg name="fs11" bitsize="32" type="ieee_single"/>
+  <reg name="ft8" bitsize="32" type="ieee_single"/>
+  <reg name="ft9" bitsize="32" type="ieee_single"/>
+  <reg name="ft10" bitsize="32" type="ieee_single"/>
+  <reg name="ft11" bitsize="32" type="ieee_single"/>
+
+  <reg name="fflags" bitsize="32" type="int"/>
+  <reg name="frm" bitsize="32" type="int"/>
+  <reg name="fcsr" bitsize="32" type="int"/>
+</feature>
diff --git a/gdb/features/riscv/64bit-cpu.c b/gdb/features/riscv/64bit-cpu.c
new file mode 100644
index 0000000..9100898
--- /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 0000000..f37d7f3
--- /dev/null
+++ b/gdb/features/riscv/64bit-cpu.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.cpu">
+  <reg name="zero" bitsize="64" type="int"/>
+  <reg name="ra" bitsize="64" type="code_ptr"/>
+  <reg name="sp" bitsize="64" type="data_ptr"/>
+  <reg name="gp" bitsize="64" type="data_ptr"/>
+  <reg name="tp" bitsize="64" type="data_ptr"/>
+  <reg name="t0" bitsize="64" type="int"/>
+  <reg name="t1" bitsize="64" type="int"/>
+  <reg name="t2" bitsize="64" type="int"/>
+  <reg name="fp" bitsize="64" type="data_ptr"/>
+  <reg name="s1" bitsize="64" type="int"/>
+  <reg name="a0" bitsize="64" type="int"/>
+  <reg name="a1" bitsize="64" type="int"/>
+  <reg name="a2" bitsize="64" type="int"/>
+  <reg name="a3" bitsize="64" type="int"/>
+  <reg name="a4" bitsize="64" type="int"/>
+  <reg name="a5" bitsize="64" type="int"/>
+  <reg name="a6" bitsize="64" type="int"/>
+  <reg name="a7" bitsize="64" type="int"/>
+  <reg name="s2" bitsize="64" type="int"/>
+  <reg name="s3" bitsize="64" type="int"/>
+  <reg name="s4" bitsize="64" type="int"/>
+  <reg name="s5" bitsize="64" type="int"/>
+  <reg name="s6" bitsize="64" type="int"/>
+  <reg name="s7" bitsize="64" type="int"/>
+  <reg name="s8" bitsize="64" type="int"/>
+  <reg name="s9" bitsize="64" type="int"/>
+  <reg name="s10" bitsize="64" type="int"/>
+  <reg name="s11" bitsize="64" type="int"/>
+  <reg name="t3" bitsize="64" type="int"/>
+  <reg name="t4" bitsize="64" type="int"/>
+  <reg name="t5" bitsize="64" type="int"/>
+  <reg name="t6" bitsize="64" type="int"/>
+  <reg name="pc" bitsize="64" type="code_ptr"/>
+</feature>
diff --git a/gdb/features/riscv/64bit-csr.c b/gdb/features/riscv/64bit-csr.c
new file mode 100644
index 0000000..7c77740
--- /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 0000000..a3de834
--- /dev/null
+++ b/gdb/features/riscv/64bit-csr.xml
@@ -0,0 +1,250 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.csr">
+  <reg name="ustatus" bitsize="64"/>
+  <reg name="uie" bitsize="64"/>
+  <reg name="utvec" bitsize="64"/>
+  <reg name="uscratch" bitsize="64"/>
+  <reg name="uepc" bitsize="64"/>
+  <reg name="ucause" bitsize="64"/>
+  <reg name="utval" bitsize="64"/>
+  <reg name="uip" bitsize="64"/>
+  <reg name="fflags" bitsize="64"/>
+  <reg name="frm" bitsize="64"/>
+  <reg name="fcsr" bitsize="64"/>
+  <reg name="cycle" bitsize="64"/>
+  <reg name="time" bitsize="64"/>
+  <reg name="instret" bitsize="64"/>
+  <reg name="hpmcounter3" bitsize="64"/>
+  <reg name="hpmcounter4" bitsize="64"/>
+  <reg name="hpmcounter5" bitsize="64"/>
+  <reg name="hpmcounter6" bitsize="64"/>
+  <reg name="hpmcounter7" bitsize="64"/>
+  <reg name="hpmcounter8" bitsize="64"/>
+  <reg name="hpmcounter9" bitsize="64"/>
+  <reg name="hpmcounter10" bitsize="64"/>
+  <reg name="hpmcounter11" bitsize="64"/>
+  <reg name="hpmcounter12" bitsize="64"/>
+  <reg name="hpmcounter13" bitsize="64"/>
+  <reg name="hpmcounter14" bitsize="64"/>
+  <reg name="hpmcounter15" bitsize="64"/>
+  <reg name="hpmcounter16" bitsize="64"/>
+  <reg name="hpmcounter17" bitsize="64"/>
+  <reg name="hpmcounter18" bitsize="64"/>
+  <reg name="hpmcounter19" bitsize="64"/>
+  <reg name="hpmcounter20" bitsize="64"/>
+  <reg name="hpmcounter21" bitsize="64"/>
+  <reg name="hpmcounter22" bitsize="64"/>
+  <reg name="hpmcounter23" bitsize="64"/>
+  <reg name="hpmcounter24" bitsize="64"/>
+  <reg name="hpmcounter25" bitsize="64"/>
+  <reg name="hpmcounter26" bitsize="64"/>
+  <reg name="hpmcounter27" bitsize="64"/>
+  <reg name="hpmcounter28" bitsize="64"/>
+  <reg name="hpmcounter29" bitsize="64"/>
+  <reg name="hpmcounter30" bitsize="64"/>
+  <reg name="hpmcounter31" bitsize="64"/>
+  <reg name="cycleh" bitsize="64"/>
+  <reg name="timeh" bitsize="64"/>
+  <reg name="instreth" bitsize="64"/>
+  <reg name="hpmcounter3h" bitsize="64"/>
+  <reg name="hpmcounter4h" bitsize="64"/>
+  <reg name="hpmcounter5h" bitsize="64"/>
+  <reg name="hpmcounter6h" bitsize="64"/>
+  <reg name="hpmcounter7h" bitsize="64"/>
+  <reg name="hpmcounter8h" bitsize="64"/>
+  <reg name="hpmcounter9h" bitsize="64"/>
+  <reg name="hpmcounter10h" bitsize="64"/>
+  <reg name="hpmcounter11h" bitsize="64"/>
+  <reg name="hpmcounter12h" bitsize="64"/>
+  <reg name="hpmcounter13h" bitsize="64"/>
+  <reg name="hpmcounter14h" bitsize="64"/>
+  <reg name="hpmcounter15h" bitsize="64"/>
+  <reg name="hpmcounter16h" bitsize="64"/>
+  <reg name="hpmcounter17h" bitsize="64"/>
+  <reg name="hpmcounter18h" bitsize="64"/>
+  <reg name="hpmcounter19h" bitsize="64"/>
+  <reg name="hpmcounter20h" bitsize="64"/>
+  <reg name="hpmcounter21h" bitsize="64"/>
+  <reg name="hpmcounter22h" bitsize="64"/>
+  <reg name="hpmcounter23h" bitsize="64"/>
+  <reg name="hpmcounter24h" bitsize="64"/>
+  <reg name="hpmcounter25h" bitsize="64"/>
+  <reg name="hpmcounter26h" bitsize="64"/>
+  <reg name="hpmcounter27h" bitsize="64"/>
+  <reg name="hpmcounter28h" bitsize="64"/>
+  <reg name="hpmcounter29h" bitsize="64"/>
+  <reg name="hpmcounter30h" bitsize="64"/>
+  <reg name="hpmcounter31h" bitsize="64"/>
+  <reg name="sstatus" bitsize="64"/>
+  <reg name="sedeleg" bitsize="64"/>
+  <reg name="sideleg" bitsize="64"/>
+  <reg name="sie" bitsize="64"/>
+  <reg name="stvec" bitsize="64"/>
+  <reg name="scounteren" bitsize="64"/>
+  <reg name="sscratch" bitsize="64"/>
+  <reg name="sepc" bitsize="64"/>
+  <reg name="scause" bitsize="64"/>
+  <reg name="stval" bitsize="64"/>
+  <reg name="sip" bitsize="64"/>
+  <reg name="satp" bitsize="64"/>
+  <reg name="mvendorid" bitsize="64"/>
+  <reg name="marchid" bitsize="64"/>
+  <reg name="mimpid" bitsize="64"/>
+  <reg name="mhartid" bitsize="64"/>
+  <reg name="mstatus" bitsize="64"/>
+  <reg name="misa" bitsize="64"/>
+  <reg name="medeleg" bitsize="64"/>
+  <reg name="mideleg" bitsize="64"/>
+  <reg name="mie" bitsize="64"/>
+  <reg name="mtvec" bitsize="64"/>
+  <reg name="mcounteren" bitsize="64"/>
+  <reg name="mscratch" bitsize="64"/>
+  <reg name="mepc" bitsize="64"/>
+  <reg name="mcause" bitsize="64"/>
+  <reg name="mtval" bitsize="64"/>
+  <reg name="mip" bitsize="64"/>
+  <reg name="pmpcfg0" bitsize="64"/>
+  <reg name="pmpcfg1" bitsize="64"/>
+  <reg name="pmpcfg2" bitsize="64"/>
+  <reg name="pmpcfg3" bitsize="64"/>
+  <reg name="pmpaddr0" bitsize="64"/>
+  <reg name="pmpaddr1" bitsize="64"/>
+  <reg name="pmpaddr2" bitsize="64"/>
+  <reg name="pmpaddr3" bitsize="64"/>
+  <reg name="pmpaddr4" bitsize="64"/>
+  <reg name="pmpaddr5" bitsize="64"/>
+  <reg name="pmpaddr6" bitsize="64"/>
+  <reg name="pmpaddr7" bitsize="64"/>
+  <reg name="pmpaddr8" bitsize="64"/>
+  <reg name="pmpaddr9" bitsize="64"/>
+  <reg name="pmpaddr10" bitsize="64"/>
+  <reg name="pmpaddr11" bitsize="64"/>
+  <reg name="pmpaddr12" bitsize="64"/>
+  <reg name="pmpaddr13" bitsize="64"/>
+  <reg name="pmpaddr14" bitsize="64"/>
+  <reg name="pmpaddr15" bitsize="64"/>
+  <reg name="mcycle" bitsize="64"/>
+  <reg name="minstret" bitsize="64"/>
+  <reg name="mhpmcounter3" bitsize="64"/>
+  <reg name="mhpmcounter4" bitsize="64"/>
+  <reg name="mhpmcounter5" bitsize="64"/>
+  <reg name="mhpmcounter6" bitsize="64"/>
+  <reg name="mhpmcounter7" bitsize="64"/>
+  <reg name="mhpmcounter8" bitsize="64"/>
+  <reg name="mhpmcounter9" bitsize="64"/>
+  <reg name="mhpmcounter10" bitsize="64"/>
+  <reg name="mhpmcounter11" bitsize="64"/>
+  <reg name="mhpmcounter12" bitsize="64"/>
+  <reg name="mhpmcounter13" bitsize="64"/>
+  <reg name="mhpmcounter14" bitsize="64"/>
+  <reg name="mhpmcounter15" bitsize="64"/>
+  <reg name="mhpmcounter16" bitsize="64"/>
+  <reg name="mhpmcounter17" bitsize="64"/>
+  <reg name="mhpmcounter18" bitsize="64"/>
+  <reg name="mhpmcounter19" bitsize="64"/>
+  <reg name="mhpmcounter20" bitsize="64"/>
+  <reg name="mhpmcounter21" bitsize="64"/>
+  <reg name="mhpmcounter22" bitsize="64"/>
+  <reg name="mhpmcounter23" bitsize="64"/>
+  <reg name="mhpmcounter24" bitsize="64"/>
+  <reg name="mhpmcounter25" bitsize="64"/>
+  <reg name="mhpmcounter26" bitsize="64"/>
+  <reg name="mhpmcounter27" bitsize="64"/>
+  <reg name="mhpmcounter28" bitsize="64"/>
+  <reg name="mhpmcounter29" bitsize="64"/>
+  <reg name="mhpmcounter30" bitsize="64"/>
+  <reg name="mhpmcounter31" bitsize="64"/>
+  <reg name="mcycleh" bitsize="64"/>
+  <reg name="minstreth" bitsize="64"/>
+  <reg name="mhpmcounter3h" bitsize="64"/>
+  <reg name="mhpmcounter4h" bitsize="64"/>
+  <reg name="mhpmcounter5h" bitsize="64"/>
+  <reg name="mhpmcounter6h" bitsize="64"/>
+  <reg name="mhpmcounter7h" bitsize="64"/>
+  <reg name="mhpmcounter8h" bitsize="64"/>
+  <reg name="mhpmcounter9h" bitsize="64"/>
+  <reg name="mhpmcounter10h" bitsize="64"/>
+  <reg name="mhpmcounter11h" bitsize="64"/>
+  <reg name="mhpmcounter12h" bitsize="64"/>
+  <reg name="mhpmcounter13h" bitsize="64"/>
+  <reg name="mhpmcounter14h" bitsize="64"/>
+  <reg name="mhpmcounter15h" bitsize="64"/>
+  <reg name="mhpmcounter16h" bitsize="64"/>
+  <reg name="mhpmcounter17h" bitsize="64"/>
+  <reg name="mhpmcounter18h" bitsize="64"/>
+  <reg name="mhpmcounter19h" bitsize="64"/>
+  <reg name="mhpmcounter20h" bitsize="64"/>
+  <reg name="mhpmcounter21h" bitsize="64"/>
+  <reg name="mhpmcounter22h" bitsize="64"/>
+  <reg name="mhpmcounter23h" bitsize="64"/>
+  <reg name="mhpmcounter24h" bitsize="64"/>
+  <reg name="mhpmcounter25h" bitsize="64"/>
+  <reg name="mhpmcounter26h" bitsize="64"/>
+  <reg name="mhpmcounter27h" bitsize="64"/>
+  <reg name="mhpmcounter28h" bitsize="64"/>
+  <reg name="mhpmcounter29h" bitsize="64"/>
+  <reg name="mhpmcounter30h" bitsize="64"/>
+  <reg name="mhpmcounter31h" bitsize="64"/>
+  <reg name="mhpmevent3" bitsize="64"/>
+  <reg name="mhpmevent4" bitsize="64"/>
+  <reg name="mhpmevent5" bitsize="64"/>
+  <reg name="mhpmevent6" bitsize="64"/>
+  <reg name="mhpmevent7" bitsize="64"/>
+  <reg name="mhpmevent8" bitsize="64"/>
+  <reg name="mhpmevent9" bitsize="64"/>
+  <reg name="mhpmevent10" bitsize="64"/>
+  <reg name="mhpmevent11" bitsize="64"/>
+  <reg name="mhpmevent12" bitsize="64"/>
+  <reg name="mhpmevent13" bitsize="64"/>
+  <reg name="mhpmevent14" bitsize="64"/>
+  <reg name="mhpmevent15" bitsize="64"/>
+  <reg name="mhpmevent16" bitsize="64"/>
+  <reg name="mhpmevent17" bitsize="64"/>
+  <reg name="mhpmevent18" bitsize="64"/>
+  <reg name="mhpmevent19" bitsize="64"/>
+  <reg name="mhpmevent20" bitsize="64"/>
+  <reg name="mhpmevent21" bitsize="64"/>
+  <reg name="mhpmevent22" bitsize="64"/>
+  <reg name="mhpmevent23" bitsize="64"/>
+  <reg name="mhpmevent24" bitsize="64"/>
+  <reg name="mhpmevent25" bitsize="64"/>
+  <reg name="mhpmevent26" bitsize="64"/>
+  <reg name="mhpmevent27" bitsize="64"/>
+  <reg name="mhpmevent28" bitsize="64"/>
+  <reg name="mhpmevent29" bitsize="64"/>
+  <reg name="mhpmevent30" bitsize="64"/>
+  <reg name="mhpmevent31" bitsize="64"/>
+  <reg name="tselect" bitsize="64"/>
+  <reg name="tdata1" bitsize="64"/>
+  <reg name="tdata2" bitsize="64"/>
+  <reg name="tdata3" bitsize="64"/>
+  <reg name="dcsr" bitsize="64"/>
+  <reg name="dpc" bitsize="64"/>
+  <reg name="dscratch" bitsize="64"/>
+  <reg name="hstatus" bitsize="64"/>
+  <reg name="hedeleg" bitsize="64"/>
+  <reg name="hideleg" bitsize="64"/>
+  <reg name="hie" bitsize="64"/>
+  <reg name="htvec" bitsize="64"/>
+  <reg name="hscratch" bitsize="64"/>
+  <reg name="hepc" bitsize="64"/>
+  <reg name="hcause" bitsize="64"/>
+  <reg name="hbadaddr" bitsize="64"/>
+  <reg name="hip" bitsize="64"/>
+  <reg name="mbase" bitsize="64"/>
+  <reg name="mbound" bitsize="64"/>
+  <reg name="mibase" bitsize="64"/>
+  <reg name="mibound" bitsize="64"/>
+  <reg name="mdbase" bitsize="64"/>
+  <reg name="mdbound" bitsize="64"/>
+  <reg name="mucounteren" bitsize="64"/>
+  <reg name="mscounteren" bitsize="64"/>
+  <reg name="mhcounteren" bitsize="64"/>
+</feature>
diff --git a/gdb/features/riscv/64bit-fpu.c b/gdb/features/riscv/64bit-fpu.c
new file mode 100644
index 0000000..8cbd748
--- /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 0000000..fb24b72
--- /dev/null
+++ b/gdb/features/riscv/64bit-fpu.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.fpu">
+
+  <union id="riscv_double">
+    <field name="float" type="ieee_single"/>
+    <field name="double" type="ieee_double"/>
+  </union>
+
+  <reg name="ft0" bitsize="64" type="riscv_double"/>
+  <reg name="ft1" bitsize="64" type="riscv_double"/>
+  <reg name="ft2" bitsize="64" type="riscv_double"/>
+  <reg name="ft3" bitsize="64" type="riscv_double"/>
+  <reg name="ft4" bitsize="64" type="riscv_double"/>
+  <reg name="ft5" bitsize="64" type="riscv_double"/>
+  <reg name="ft6" bitsize="64" type="riscv_double"/>
+  <reg name="ft7" bitsize="64" type="riscv_double"/>
+  <reg name="fs0" bitsize="64" type="riscv_double"/>
+  <reg name="fs1" bitsize="64" type="riscv_double"/>
+  <reg name="fa0" bitsize="64" type="riscv_double"/>
+  <reg name="fa1" bitsize="64" type="riscv_double"/>
+  <reg name="fa2" bitsize="64" type="riscv_double"/>
+  <reg name="fa3" bitsize="64" type="riscv_double"/>
+  <reg name="fa4" bitsize="64" type="riscv_double"/>
+  <reg name="fa5" bitsize="64" type="riscv_double"/>
+  <reg name="fa6" bitsize="64" type="riscv_double"/>
+  <reg name="fa7" bitsize="64" type="riscv_double"/>
+  <reg name="fs2" bitsize="64" type="riscv_double"/>
+  <reg name="fs3" bitsize="64" type="riscv_double"/>
+  <reg name="fs4" bitsize="64" type="riscv_double"/>
+  <reg name="fs5" bitsize="64" type="riscv_double"/>
+  <reg name="fs6" bitsize="64" type="riscv_double"/>
+  <reg name="fs7" bitsize="64" type="riscv_double"/>
+  <reg name="fs8" bitsize="64" type="riscv_double"/>
+  <reg name="fs9" bitsize="64" type="riscv_double"/>
+  <reg name="fs10" bitsize="64" type="riscv_double"/>
+  <reg name="fs11" bitsize="64" type="riscv_double"/>
+  <reg name="ft8" bitsize="64" type="riscv_double"/>
+  <reg name="ft9" bitsize="64" type="riscv_double"/>
+  <reg name="ft10" bitsize="64" type="riscv_double"/>
+  <reg name="ft11" bitsize="64" type="riscv_double"/>
+
+  <reg name="fflags" bitsize="32" type="int"/>
+  <reg name="frm" bitsize="32" type="int"/>
+  <reg name="fcsr" bitsize="32" type="int"/>
+</feature>
diff --git a/gdb/features/riscv/rebuild-csr-xml.sh b/gdb/features/riscv/rebuild-csr-xml.sh
new file mode 100755
index 0000000..6971b8d
--- /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
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.riscv.csr">
+EOF
+
+    grep "^DECLARE_CSR(" ${RISCV_OPC_FILE} \
+        | sed -e "s!DECLARE_CSR(\(.*\), .*!  <reg name=\"\1\" bitsize=\"$bitsize\"/>!"
+
+    echo "</feature>"
+}
+
+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 408ab0a..5965a59 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 <const char *> 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 <struct register_info> 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 },
+[...]

[diff truncated at 100000 bytes]


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]