diff options
-rw-r--r-- | gdb/ChangeLog | 19 | ||||
-rw-r--r-- | gdb/NEWS | 5 | ||||
-rw-r--r-- | gdb/arch/riscv.c | 6 | ||||
-rw-r--r-- | gdb/arch/riscv.h | 12 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 8 | ||||
-rw-r--r-- | gdb/riscv-tdep.c | 121 | ||||
-rw-r--r-- | gdb/riscv-tdep.h | 8 |
8 files changed, 177 insertions, 6 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0501a56..11f2154 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,24 @@ 2021-06-21 Andrew Burgess <andrew.burgess@embecosm.com> + * NEWS: Mention new target feature name. + * arch/riscv.c (riscv_create_target_description): GDB doesn't + currently create target descriptions containing vector registers. + * arch/riscv.h (struct riscv_gdbarch_features) <vlen>: New member + variable. + <operator==>: Also compare vlen. + <hash>: Also include vlen. + * riscv-tdep.c (riscv_feature_name_vector): New static global. + (struct riscv_vector_feature): New struct. + (riscv_vector_feature): New static global. + (riscv_register_reggroup_p): Ensure vector registers are part of + the 'all' group, and part of the 'vector' group. + (riscv_dwarf_reg_to_regnum): Handle vector registers. + (riscv_gdbarch_init): Check vector register feature. + * riscv-tdep.h: Add vector registers to GDB's internal register + numbers, and to the DWARF register numbers. + +2021-06-21 Andrew Burgess <andrew.burgess@embecosm.com> + * NEWS: Mention the two new methods. * python/py-frame.c (frapy_level): New function. (frame_object_methods): Register 'level' method. @@ -78,6 +78,11 @@ and "-eiex" that allow options (that would normally appear in a gdbearlyinit file) to be passed on the command line. +* For RISC-V targets, the target feature "org.gnu.gdb.riscv.vector" is + now understood by GDB, and can be used to describe the vector + registers of a target. The precise requirements of this register + feature are documented in the GDB manual. + * New commands set debug event-loop diff --git a/gdb/arch/riscv.c b/gdb/arch/riscv.c index 8fbcad1..85d60a3 100644 --- a/gdb/arch/riscv.c +++ b/gdb/arch/riscv.c @@ -84,6 +84,12 @@ riscv_create_target_description (const struct riscv_gdbarch_features features) else if (features.flen == 8) regnum = create_feature_riscv_64bit_fpu (tdesc.get (), regnum); + /* Currently GDB only supports vector features coming from remote + targets. We don't support creating vector features on native targets + (yet). */ + if (features.vlen != 0) + error (_("unable to create vector feature")); + return tdesc; } diff --git a/gdb/arch/riscv.h b/gdb/arch/riscv.h index faa038a..65a998b 100644 --- a/gdb/arch/riscv.h +++ b/gdb/arch/riscv.h @@ -46,13 +46,20 @@ struct riscv_gdbarch_features that there are no f-registers. No other value is valid. */ int flen = 0; + /* The size of the v-registers in bytes. The value 0 indicates a target + with no vector registers. The minimum value for a standard compliant + target should be 16, but GDB doesn't currently mind, and will accept + any vector size. */ + int vlen = 0; + /* When true this target is RV32E. */ bool embedded = false; /* Equality operator. */ bool operator== (const struct riscv_gdbarch_features &rhs) const { - return (xlen == rhs.xlen && flen == rhs.flen && embedded == rhs.embedded); + return (xlen == rhs.xlen && flen == rhs.flen + && embedded == rhs.embedded && vlen == rhs.vlen); } /* Inequality operator. */ @@ -66,7 +73,8 @@ struct riscv_gdbarch_features { std::size_t val = ((embedded ? 1 : 0) << 10 | (xlen & 0x1f) << 5 - | (flen & 0x1f) << 0); + | (flen & 0x1f) << 0 + | (vlen & 0xfff) << 11); return val; } }; diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 9595c21..ad0b2e7 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,5 +1,9 @@ 2021-06-21 Andrew Burgess <andrew.burgess@embecosm.com> + * gdb.texinfo (RISC-V Features): Mention vector register feature. + +2021-06-21 Andrew Burgess <andrew.burgess@embecosm.com> + * python.texi (Unwinding Frames in Python): Mention PendingFrame.level. (Frames In Python): Mention Frame.level. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 7cdc83b..dfc00b1 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -46349,6 +46349,14 @@ 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. +The @samp{org.gnu.gdb.riscv.vector} feature is optional. If present, +it should contain registers @samp{v0} through @samp{v31}, all of which +must be the same size. These requirements are based on the v0.10 +draft vector extension, as the vector extension is not yet final. In +the event that the register set of the vector extension changes for +the final specification, the requirements given here could change for +future releases of @value{GDBN}. + @node RX Features @subsection RX Features @cindex target descriptions, RX Features diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index 7fae914..d942b05 100644 --- a/gdb/riscv-tdep.c +++ b/gdb/riscv-tdep.c @@ -99,6 +99,7 @@ const char *riscv_feature_name_csr = "org.gnu.gdb.riscv.csr"; static const char *riscv_feature_name_cpu = "org.gnu.gdb.riscv.cpu"; static const char *riscv_feature_name_fpu = "org.gnu.gdb.riscv.fpu"; static const char *riscv_feature_name_virtual = "org.gnu.gdb.riscv.virtual"; +static const char *riscv_feature_name_vector = "org.gnu.gdb.riscv.vector"; /* Cached information about a frame. */ @@ -575,6 +576,115 @@ private: static const struct riscv_csr_feature riscv_csr_feature; +/* Class representing the v-registers feature set. */ + +struct riscv_vector_feature : public riscv_register_feature +{ + riscv_vector_feature () + : riscv_register_feature (riscv_feature_name_vector) + { + m_registers = { + { RISCV_V0_REGNUM + 0, { "v0" } }, + { RISCV_V0_REGNUM + 1, { "v1" } }, + { RISCV_V0_REGNUM + 2, { "v2" } }, + { RISCV_V0_REGNUM + 3, { "v3" } }, + { RISCV_V0_REGNUM + 4, { "v4" } }, + { RISCV_V0_REGNUM + 5, { "v5" } }, + { RISCV_V0_REGNUM + 6, { "v6" } }, + { RISCV_V0_REGNUM + 7, { "v7" } }, + { RISCV_V0_REGNUM + 8, { "v8" } }, + { RISCV_V0_REGNUM + 9, { "v9" } }, + { RISCV_V0_REGNUM + 10, { "v10" } }, + { RISCV_V0_REGNUM + 11, { "v11" } }, + { RISCV_V0_REGNUM + 12, { "v12" } }, + { RISCV_V0_REGNUM + 13, { "v13" } }, + { RISCV_V0_REGNUM + 14, { "v14" } }, + { RISCV_V0_REGNUM + 15, { "v15" } }, + { RISCV_V0_REGNUM + 16, { "v16" } }, + { RISCV_V0_REGNUM + 17, { "v17" } }, + { RISCV_V0_REGNUM + 18, { "v18" } }, + { RISCV_V0_REGNUM + 19, { "v19" } }, + { RISCV_V0_REGNUM + 20, { "v20" } }, + { RISCV_V0_REGNUM + 21, { "v21" } }, + { RISCV_V0_REGNUM + 22, { "v22" } }, + { RISCV_V0_REGNUM + 23, { "v23" } }, + { RISCV_V0_REGNUM + 24, { "v24" } }, + { RISCV_V0_REGNUM + 25, { "v25" } }, + { RISCV_V0_REGNUM + 26, { "v26" } }, + { RISCV_V0_REGNUM + 27, { "v27" } }, + { RISCV_V0_REGNUM + 28, { "v28" } }, + { RISCV_V0_REGNUM + 29, { "v29" } }, + { RISCV_V0_REGNUM + 30, { "v30" } }, + { RISCV_V0_REGNUM + 31, { "v31" } }, + }; + } + + /* Return the preferred name for the register with gdb register number + REGNUM, which must be in the inclusive range RISCV_V0_REGNUM to + RISCV_V0_REGNUM + 31. */ + const char *register_name (int regnum) const + { + gdb_assert (regnum >= RISCV_V0_REGNUM + && regnum <= RISCV_V0_REGNUM + 31); + regnum -= RISCV_V0_REGNUM; + return m_registers[regnum].names[0]; + } + + /* Check this feature within TDESC, record the registers from this + feature into TDESC_DATA and update ALIASES and FEATURES. */ + bool check (const struct target_desc *tdesc, + struct tdesc_arch_data *tdesc_data, + std::vector<riscv_pending_register_alias> *aliases, + struct riscv_gdbarch_features *features) const + { + const struct tdesc_feature *feature_vector = tdesc_feature (tdesc); + + /* It's fine if this feature is missing. Update the architecture + feature set and return. */ + if (feature_vector == nullptr) + { + features->vlen = 0; + return true; + } + + /* Check all of the vector registers are present. */ + for (const auto ® : m_registers) + { + if (!reg.check (tdesc_data, feature_vector, true, aliases)) + return false; + } + + /* Look through all of the vector registers and check they all have the + same bitsize. Use this bitsize to update the feature set for this + gdbarch. */ + int vector_bitsize = -1; + for (const auto ® : m_registers) + { + int reg_bitsize = -1; + for (const char *name : reg.names) + { + if (tdesc_unnumbered_register (feature_vector, name)) + { + reg_bitsize = tdesc_register_bitsize (feature_vector, name); + break; + } + } + gdb_assert (reg_bitsize != -1); + if (vector_bitsize == -1) + vector_bitsize = reg_bitsize; + else if (vector_bitsize != reg_bitsize) + return false; + } + + features->vlen = (vector_bitsize / 8); + return true; + } +}; + +/* An instance of the v-register feature set. */ + +static const struct riscv_vector_feature riscv_vector_feature; + /* Controls whether we place compressed breakpoints or not. When in auto mode GDB tries to determine if the target supports compressed breakpoints, and uses them if it does. */ @@ -1192,7 +1302,7 @@ riscv_register_reggroup_p (struct gdbarch *gdbarch, int regnum, if (reggroup == all_reggroup) { - if (regnum < RISCV_FIRST_CSR_REGNUM || regnum == RISCV_PRIV_REGNUM) + if (regnum < RISCV_FIRST_CSR_REGNUM || regnum >= RISCV_PRIV_REGNUM) return 1; if (riscv_is_regnum_a_named_csr (regnum)) return 1; @@ -1226,7 +1336,7 @@ riscv_register_reggroup_p (struct gdbarch *gdbarch, int regnum, return 0; } else if (reggroup == vector_reggroup) - return 0; + return (regnum >= RISCV_V0_REGNUM && regnum <= RISCV_V31_REGNUM); else return 0; } @@ -3320,6 +3430,9 @@ riscv_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) else if (reg >= RISCV_DWARF_FIRST_CSR && reg <= RISCV_DWARF_LAST_CSR) return RISCV_FIRST_CSR_REGNUM + (reg - RISCV_DWARF_FIRST_CSR); + else if (reg >= RISCV_DWARF_REGNUM_V0 && reg <= RISCV_DWARF_REGNUM_V31) + return RISCV_V0_REGNUM + (reg - RISCV_DWARF_REGNUM_V0); + return -1; } @@ -3488,7 +3601,9 @@ riscv_gdbarch_init (struct gdbarch_info info, && riscv_virtual_feature.check (tdesc, tdesc_data.get (), &pending_aliases, &features) && riscv_csr_feature.check (tdesc, tdesc_data.get (), - &pending_aliases, &features)); + &pending_aliases, &features) + && riscv_vector_feature.check (tdesc, tdesc_data.get (), + &pending_aliases, &features)); if (!valid_p) { if (riscv_debug_gdbarch) diff --git a/gdb/riscv-tdep.h b/gdb/riscv-tdep.h index 154097d..62bf479 100644 --- a/gdb/riscv-tdep.h +++ b/gdb/riscv-tdep.h @@ -53,7 +53,11 @@ enum RISCV_PRIV_REGNUM = 4161, - RISCV_LAST_REGNUM = RISCV_PRIV_REGNUM + RISCV_V0_REGNUM, + + RISCV_V31_REGNUM = RISCV_V0_REGNUM + 31, + + RISCV_LAST_REGNUM = RISCV_V31_REGNUM }; /* RiscV DWARF register numbers. */ @@ -63,6 +67,8 @@ enum RISCV_DWARF_REGNUM_X31 = 31, RISCV_DWARF_REGNUM_F0 = 32, RISCV_DWARF_REGNUM_F31 = 63, + RISCV_DWARF_REGNUM_V0 = 96, + RISCV_DWARF_REGNUM_V31 = 127, RISCV_DWARF_FIRST_CSR = 4096, RISCV_DWARF_LAST_CSR = 8191, }; |