+2020-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * riscv-tdep.c (riscv_create_csr_aliases): Handle csr aliases from
+ riscv-opc.h.
+ (class riscv_pending_register_alias): New class.
+ (riscv_check_tdesc_feature): Take vector of pending aliases and
+ populate it as appropriate.
+ (riscv_setup_register_aliases): Delete.
+ (riscv_gdbarch_init): Create vector of pending aliases and pass it
+ to riscv_check_tdesc_feature in all cases. Use the vector to
+ create the register aliases.
+
2020-06-25 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* sol2-tdep.c (sol2_static_transform_name): Remove.
int csr_num = reg.regnum - RISCV_FIRST_CSR_REGNUM;
const char *alias = xstrprintf ("csr%d", csr_num);
reg.names.push_back (alias);
+
+ /* Setup the other csr aliases. We don't use a switch table here in
+ case there are multiple aliases with the same value. Also filter
+ based on ABRT_VER in order to avoid a very old alias for misa that
+ duplicates the name "misa" but at a different CSR address. */
+#define DECLARE_CSR_ALIAS(NAME,VALUE,CLASS,DEF_VER,ABRT_VER) \
+ if (csr_num == VALUE && ABRT_VER >= PRIV_SPEC_CLASS_1P11) \
+ reg.names.push_back ( # NAME );
+#include "opcode/riscv-opc.h"
+#undef DECLARE_CSR_ALIAS
}
}
return riscv_lookup_target_description (features);
}
+/* Information about a register alias that needs to be set up for this
+ target. These are collected when the target's XML description is
+ analysed, and then processed later, once the gdbarch has been created. */
+
+class riscv_pending_register_alias
+{
+public:
+ /* Constructor. */
+
+ riscv_pending_register_alias (const char *name, const void *baton)
+ : m_name (name),
+ m_baton (baton)
+ { /* Nothing. */ }
+
+ /* Convert this into a user register for GDBARCH. */
+
+ void create (struct gdbarch *gdbarch) const
+ {
+ user_reg_add (gdbarch, m_name, value_of_riscv_user_reg, m_baton);
+ }
+
+private:
+ /* The name for this alias. */
+ const char *m_name;
+
+ /* The baton value for passing to user_reg_add. This must point to some
+ data that will live for at least as long as the gdbarch object to
+ which the user register is attached. */
+ const void *m_baton;
+};
+
/* All of the registers in REG_SET are checked for in FEATURE, TDESC_DATA
is updated with the register numbers for each register as listed in
REG_SET. If any register marked as required in REG_SET is not found in
static bool
riscv_check_tdesc_feature (struct tdesc_arch_data *tdesc_data,
const struct tdesc_feature *feature,
- const struct riscv_register_feature *reg_set)
+ const struct riscv_register_feature *reg_set,
+ std::vector<riscv_pending_register_alias> *aliases)
{
for (const auto ® : reg_set->registers)
{
tdesc_numbered_register (feature, tdesc_data, reg.regnum, name);
if (found)
- break;
+ {
+ /* We know that the target description mentions this
+ register. In RISCV_REGISTER_NAME we ensure that GDB
+ always uses the first name for each register, so here we
+ add aliases for all of the remaining names. */
+ for (int i = 0; i < reg.names.size (); ++i)
+ aliases->emplace_back (reg.names[i], (void *) ®.regnum);
+ break;
+ }
}
if (!found && reg.required_p)
reggroup_add (gdbarch, csr_reggroup);
}
-/* Create register aliases for all the alternative names that exist for
- registers in REG_SET. */
-
-static void
-riscv_setup_register_aliases (struct gdbarch *gdbarch,
- const struct riscv_register_feature *reg_set)
-{
- for (auto ® : reg_set->registers)
- {
- /* The first item in the names list is the preferred name for the
- register, this is what RISCV_REGISTER_NAME returns, and so we
- don't need to create an alias with that name here. */
- for (int i = 1; i < reg.names.size (); ++i)
- user_reg_add (gdbarch, reg.names[i], value_of_riscv_user_reg,
- ®.regnum);
- }
-}
-
/* Implement the "dwarf2_reg_to_regnum" gdbarch method. */
static int
return NULL;
struct tdesc_arch_data *tdesc_data = tdesc_data_alloc ();
+ std::vector<riscv_pending_register_alias> pending_aliases;
bool valid_p = riscv_check_tdesc_feature (tdesc_data,
feature_cpu,
- &riscv_xreg_feature);
+ &riscv_xreg_feature,
+ &pending_aliases);
if (valid_p)
{
/* Check that all of the core cpu registers have the same bitsize. */
if (feature_fpu != NULL)
{
valid_p &= riscv_check_tdesc_feature (tdesc_data, feature_fpu,
- &riscv_freg_feature);
+ &riscv_freg_feature,
+ &pending_aliases);
/* Search for the first floating point register (by any alias), to
determine the bitsize. */
if (feature_virtual)
riscv_check_tdesc_feature (tdesc_data, feature_virtual,
- &riscv_virtual_feature);
+ &riscv_virtual_feature,
+ &pending_aliases);
if (feature_csr)
riscv_check_tdesc_feature (tdesc_data, feature_csr,
- &riscv_csr_feature);
+ &riscv_csr_feature,
+ &pending_aliases);
if (!valid_p)
{
want, ignoring what the target tells us. */
set_gdbarch_register_reggroup_p (gdbarch, riscv_register_reggroup_p);
- /* Create register aliases for alternative register names. */
- riscv_setup_register_aliases (gdbarch, &riscv_xreg_feature);
- if (riscv_has_fp_regs (gdbarch))
- riscv_setup_register_aliases (gdbarch, &riscv_freg_feature);
- riscv_setup_register_aliases (gdbarch, &riscv_csr_feature);
+ /* Create register aliases for alternative register names. We only
+ create aliases for registers which were mentioned in the target
+ description. */
+ for (const auto &alias : pending_aliases)
+ alias.create (gdbarch);
/* Compile command hooks. */
set_gdbarch_gcc_target_options (gdbarch, riscv_gcc_target_options);
+2020-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * gdb.arch/riscv-tdesc-regs-32.xml: New file.
+ * gdb.arch/riscv-tdesc-regs-64.xml: New file.
+ * gdb.arch/riscv-tdesc-regs.c: New file.
+ * gdb.arch/riscv-tdesc-regs.exp: New file.
+
2020-06-24 Pedro Alves <palves@redhat.com>
* gdb.arch/amd64-entry-value-paramref.exp: Use
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>riscv</architecture>
+ <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>
+ <feature name="org.gnu.gdb.riscv.fpu">
+ <reg name="ft0" bitsize="32" type="float"/>
+ <reg name="ft1" bitsize="32" type="float"/>
+ <reg name="ft2" bitsize="32" type="float"/>
+ <reg name="ft3" bitsize="32" type="float"/>
+ <reg name="ft4" bitsize="32" type="float"/>
+ <reg name="ft5" bitsize="32" type="float"/>
+ <reg name="ft6" bitsize="32" type="float"/>
+ <reg name="ft7" bitsize="32" type="float"/>
+ <reg name="fs0" bitsize="32" type="float"/>
+ <reg name="fs1" bitsize="32" type="float"/>
+ <reg name="fa0" bitsize="32" type="float"/>
+ <reg name="fa1" bitsize="32" type="float"/>
+ <reg name="fa2" bitsize="32" type="float"/>
+ <reg name="fa3" bitsize="32" type="float"/>
+ <reg name="fa4" bitsize="32" type="float"/>
+ <reg name="fa5" bitsize="32" type="float"/>
+ <reg name="fa6" bitsize="32" type="float"/>
+ <reg name="fa7" bitsize="32" type="float"/>
+ <reg name="fs2" bitsize="32" type="float"/>
+ <reg name="fs3" bitsize="32" type="float"/>
+ <reg name="fs4" bitsize="32" type="float"/>
+ <reg name="fs5" bitsize="32" type="float"/>
+ <reg name="fs6" bitsize="32" type="float"/>
+ <reg name="fs7" bitsize="32" type="float"/>
+ <reg name="fs8" bitsize="32" type="float"/>
+ <reg name="fs9" bitsize="32" type="float"/>
+ <reg name="fs10" bitsize="32" type="float"/>
+ <reg name="fs11" bitsize="32" type="float"/>
+ <reg name="ft8" bitsize="32" type="float"/>
+ <reg name="ft9" bitsize="32" type="float"/>
+ <reg name="ft10" bitsize="32" type="float"/>
+ <reg name="ft11" bitsize="32" type="float"/>
+ <!-- The following 3 registers are duplicated. -->
+ <reg name="fflags" bitsize="32" type="int"/>
+ <reg name="frm" bitsize="32" type="int"/>
+ <reg name="fcsr" bitsize="32" type="int"/>
+ </feature>
+ <feature name="org.gnu.gdb.riscv.csr">
+ <!-- The following 3 registers are duplicated. -->
+ <reg name="fflags" bitsize="32" type="int"/>
+ <reg name="frm" bitsize="32" type="int"/>
+ <reg name="fcsr" bitsize="32" type="int"/>
+ <!-- The following is a CSR unknown to GDB. -->
+ <reg name="unknown_csr" bitsize="32" type="int"/>
+ <!-- The following is now known as 'dscratch0' in the official
+ RISC-V spec, but GDB should NOT rename this register. -->
+ <reg name="dscratch" bitsize="32" type="int"/>
+ </feature>
+</target>
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>riscv</architecture>
+ <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>
+ <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"/>
+ <!-- The following 3 registers are duplicated. -->
+ <reg name="fflags" bitsize="32" type="int"/>
+ <reg name="frm" bitsize="32" type="int"/>
+ <reg name="fcsr" bitsize="32" type="int"/>
+ </feature>
+ <feature name="org.gnu.gdb.riscv.csr">
+ <!-- The following 3 registers are duplicated. -->
+ <reg name="fflags" bitsize="32" type="int"/>
+ <reg name="frm" bitsize="32" type="int"/>
+ <reg name="fcsr" bitsize="32" type="int"/>
+ <!-- The following is a CSR unknown to GDB. -->
+ <reg name="unknown_csr" bitsize="32" type="int"/>
+ <!-- The following is now known as 'dscratch0' in the official
+ RISC-V spec, but GDB should NOT rename this register. -->
+ <reg name="dscratch" bitsize="32" type="int"/>
+ </feature>
+</target>
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2020 Free Software Foundation, Inc.
+
+ 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/>. */
+
+int
+main ()
+{
+ return 0;
+}
--- /dev/null
+# Copyright 2020 Free Software Foundation, Inc.
+#
+# 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/>.
+
+# Various tests to check which register names are available after
+# loading a new target description file.
+
+if {![istarget "riscv*-*-*"]} {
+ verbose "Skipping ${gdb_test_file_name}."
+ return
+}
+
+standard_testfile
+
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
+ {debug quiet}] } {
+ unsupported "failed to compile"
+ return -1
+}
+
+if { ![runto_main] } {
+ untested "failed to runto main"
+ return -1
+}
+
+# First, figure out if we are 32-bit or 64-bit.
+set xlen [get_valueof "/d" "sizeof (\$a0)" 0]
+set flen [get_valueof "/d" "sizeof (\$fa0)" 0]
+
+gdb_assert { $xlen != 0 && $flen != 0 } "read xlen and flen"
+
+# We only handle 32-bit or 64-bit x-registers.
+if { $xlen != 4 && $xlen != 8 } {
+ unsupported "unknown x-register size"
+ return -1
+}
+
+# If FLEN is 1 then the target doesn't have floating point support
+# (the register $fa0 was not recognised). Otherwise, we can only
+# proceed if FLEN equals XLEN, otherwise we'd need more test XML
+# files.
+if { $flen != 1 && $flen != $xlen } {
+ unsupport "unknown xlen/flen combination"
+ return -1
+}
+
+if { $xlen == 4 } {
+ set xml_tdesc "riscv-tdesc-regs-32.xml"
+} else {
+ set xml_tdesc "riscv-tdesc-regs-64.xml"
+}
+set xml_tdesc "${srcdir}/${subdir}/${xml_tdesc}"
+
+# Maybe copy the target over if we're remote testing.
+if {[is_remote host]} {
+ set remote_file [remote_download host $xml_tdesc]
+} else {
+ set remote_file $xml_tdesc
+}
+
+gdb_test_no_output "set tdesc filename $remote_file" \
+ "load the new target description"
+
+# Check that an alias for an unknown CSR will give a suitable error.
+gdb_test "info registers \$csr0" "Invalid register `csr0'"
+
+# Check we can access the dscratch register using either of its names.
+gdb_test "info registers \$dscratch0" "dscratch0\[ \t\]+.*"
+gdb_test "info registers \$dscratch" "dscratch\[ \t\]+.*"
+