@@ -3,6 +3,10 @@
*** Changes since GDB 8.0
+* GDB now supports dynamically creating arbitrary register groups specified
+ in xml target descriptors. This allows for finer grain grouping of
+ registers on systems with a large amount of registers.
+
* On Unix systems, GDBserver now does globbing expansion and variable
substitution in inferior command line arguments.
@@ -41000,10 +41000,11 @@ architecture's normal floating point format) of the correct size for
@var{bitsize}. The default is @code{int}.
@item group
-The register group to which this register belongs. It must
-be either @code{general}, @code{float}, or @code{vector}. If no
-@var{group} is specified, @value{GDBN} will not display the register
-in @code{info registers}.
+The register group to which this register belongs. It can be one of the
+standard register groups @code{general}, @code{float}, @code{vector} or an
+arbitrary string. The string should be limited to alphanumeric characters
+and internal hyphens. If no @var{group} is specified, @value{GDBN} will
+not display the register in @code{info registers}.
@end table
@@ -63,12 +63,11 @@ typedef struct tdesc_reg
int save_restore;
/* The name of the register group containing this register, or NULL
- if the group should be automatically determined from the
- register's type. If this is "general", "float", or "vector", the
- corresponding "info" command should display this register's
- value. It can be an arbitrary string, but should be limited to
- alphanumeric characters and internal hyphens. Currently other
- strings are ignored (treated as NULL). */
+ if the group should be automatically determined from the register's
+ type. This is traditionally "general", "float", "vector" but can
+ also be an arbitrary string. If defined the corresponding "info"
+ command should display this register's value. The string should be
+ limited to alphanumeric characters and internal hyphens. */
char *group;
/* The size of the register, in bits. */
@@ -1081,17 +1080,13 @@ tdesc_remote_register_number (struct gdbarch *gdbarch, int regno)
}
/* Check whether REGNUM is a member of REGGROUP. Registers from the
- target description may be classified as general, float, or vector.
- Unlike a gdbarch register_reggroup_p method, this function will
- return -1 if it does not know; the caller should handle registers
- with no specified group.
-
- Arbitrary strings (other than "general", "float", and "vector")
- from the description are not used; they cause the register to be
- displayed in "info all-registers" but excluded from "info
- registers" et al. The names of containing features are also not
- used. This might be extended to display registers in some more
- useful groupings.
+ target description may be classified as general, float, vector or other
+ register groups registered with reggroup_add(). Unlike a gdbarch
+ register_reggroup_p method, this function will return -1 if it does not
+ know; the caller should handle registers with no specified group.
+
+ The names of containing features are not used. This might be extended
+ to display registers in some more useful groupings.
The save-restore flag is also implemented here. */
@@ -1101,26 +1096,9 @@ tdesc_register_in_reggroup_p (struct gdbarch *gdbarch, int regno,
{
struct tdesc_reg *reg = tdesc_find_register (gdbarch, regno);
- if (reg != NULL && reg->group != NULL)
- {
- int general_p = 0, float_p = 0, vector_p = 0;
-
- if (strcmp (reg->group, "general") == 0)
- general_p = 1;
- else if (strcmp (reg->group, "float") == 0)
- float_p = 1;
- else if (strcmp (reg->group, "vector") == 0)
- vector_p = 1;
-
- if (reggroup == float_reggroup)
- return float_p;
-
- if (reggroup == vector_reggroup)
- return vector_p;
-
- if (reggroup == general_reggroup)
- return general_p;
- }
+ if (reg != NULL && reg->group != NULL
+ && (strcmp (reg->group, reggroup_name (reggroup)) == 0))
+ return 1;
if (reg != NULL
&& (reggroup == save_reggroup || reggroup == restore_reggroup))
@@ -1231,6 +1209,28 @@ tdesc_use_registers (struct gdbarch *gdbarch,
void **slot = htab_find_slot (reg_hash, reg, INSERT);
*slot = reg;
+ /* Add reggroup if its new. */
+ if (reg->group != NULL)
+ {
+ struct reggroup *group;
+ bool group_exists = false;
+
+ for (group = reggroup_next (gdbarch, NULL);
+ group != NULL;
+ group = reggroup_next (gdbarch, group))
+ {
+ if (strcmp (reg->group, reggroup_name (group)) == 0)
+ {
+ group_exists = true;
+ break;
+ }
+ }
+
+ if (!group_exists)
+ reggroup_add (gdbarch, reggroup_gdbarch_new (gdbarch,
+ reg->group,
+ USER_REGGROUP));
+ }
}
/* Remove any registers which were assigned numbers by the
@@ -53,5 +53,6 @@
<reg name="bitfields" bitsize="64" type="struct2"/>
<reg name="flags" bitsize="32" type="flags"/>
<reg name="mixed_flags" bitsize="32" type="mixed_flags"/>
+ <reg name="groupreg" bitsize="32" type="uint32" group="foo"/>
</feature>
</target>
@@ -187,6 +187,9 @@ gdb_test "ptype \$flags" \
"type = flag flags {\r\n *bool X @0;\r\n *uint32_t Y @2;\r\n}"
gdb_test "ptype \$mixed_flags" \
"type = flag mixed_flags {\r\n *bool A @0;\r\n *uint32_t B @1-3;\r\n *bool C @4;\r\n *uint32_t D @5;\r\n *uint32_t @6-7;\r\n *enum {yes = 1, no = 0, maybe = 2, so} Z @8-9;\r\n}"
+# Reggroups should have at least general and the extra foo group
+gdb_test "maintenance print reggroups" \
+ " Group\[ \t\]+Type\[ \t\]+\r\n.* general\[ \t\]+user\[ \t\]+\r\n.* foo\[ \t\]+user\[ \t\]+"
load_description "core-only.xml" "" "test-regs.xml"
# The extra register from the previous description should be gone.