xref: /openbsd/gnu/usr.bin/binutils/gdb/reggroups.c (revision 11efff7f)
1b725ae77Skettenis /* Register groupings for GDB, the GNU debugger.
2b725ae77Skettenis 
3b725ae77Skettenis    Copyright 2002, 2003 Free Software Foundation, Inc.
4b725ae77Skettenis 
5b725ae77Skettenis    Contributed by Red Hat.
6b725ae77Skettenis 
7b725ae77Skettenis    This file is part of GDB.
8b725ae77Skettenis 
9b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
10b725ae77Skettenis    it under the terms of the GNU General Public License as published by
11b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
12b725ae77Skettenis    (at your option) any later version.
13b725ae77Skettenis 
14b725ae77Skettenis    This program is distributed in the hope that it will be useful,
15b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
16b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17b725ae77Skettenis    GNU General Public License for more details.
18b725ae77Skettenis 
19b725ae77Skettenis    You should have received a copy of the GNU General Public License
20b725ae77Skettenis    along with this program; if not, write to the Free Software
21b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
22b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
23b725ae77Skettenis 
24b725ae77Skettenis #include "defs.h"
25b725ae77Skettenis #include "reggroups.h"
26b725ae77Skettenis #include "gdbtypes.h"
27b725ae77Skettenis #include "gdb_assert.h"
28b725ae77Skettenis #include "regcache.h"
29b725ae77Skettenis #include "command.h"
30b725ae77Skettenis #include "gdbcmd.h"		/* For maintenanceprintlist.  */
31b725ae77Skettenis 
32b725ae77Skettenis /* Individual register groups.  */
33b725ae77Skettenis 
34b725ae77Skettenis struct reggroup
35b725ae77Skettenis {
36b725ae77Skettenis   const char *name;
37b725ae77Skettenis   enum reggroup_type type;
38b725ae77Skettenis };
39b725ae77Skettenis 
40b725ae77Skettenis struct reggroup *
reggroup_new(const char * name,enum reggroup_type type)41b725ae77Skettenis reggroup_new (const char *name, enum reggroup_type type)
42b725ae77Skettenis {
43b725ae77Skettenis   struct reggroup *group = XMALLOC (struct reggroup);
44b725ae77Skettenis   group->name = name;
45b725ae77Skettenis   group->type = type;
46b725ae77Skettenis   return group;
47b725ae77Skettenis }
48b725ae77Skettenis 
49b725ae77Skettenis /* Register group attributes.  */
50b725ae77Skettenis 
51b725ae77Skettenis const char *
reggroup_name(struct reggroup * group)52b725ae77Skettenis reggroup_name (struct reggroup *group)
53b725ae77Skettenis {
54b725ae77Skettenis   return group->name;
55b725ae77Skettenis }
56b725ae77Skettenis 
57b725ae77Skettenis enum reggroup_type
reggroup_type(struct reggroup * group)58b725ae77Skettenis reggroup_type (struct reggroup *group)
59b725ae77Skettenis {
60b725ae77Skettenis   return group->type;
61b725ae77Skettenis }
62b725ae77Skettenis 
63b725ae77Skettenis /* A linked list of groups for the given architecture.  */
64b725ae77Skettenis 
65b725ae77Skettenis struct reggroup_el
66b725ae77Skettenis {
67b725ae77Skettenis   struct reggroup *group;
68b725ae77Skettenis   struct reggroup_el *next;
69b725ae77Skettenis };
70b725ae77Skettenis 
71b725ae77Skettenis struct reggroups
72b725ae77Skettenis {
73b725ae77Skettenis   struct reggroup_el *first;
74b725ae77Skettenis   struct reggroup_el **last;
75b725ae77Skettenis };
76b725ae77Skettenis 
77b725ae77Skettenis static struct gdbarch_data *reggroups_data;
78b725ae77Skettenis 
79b725ae77Skettenis static void *
reggroups_init(struct gdbarch * gdbarch)80b725ae77Skettenis reggroups_init (struct gdbarch *gdbarch)
81b725ae77Skettenis {
82b725ae77Skettenis   struct reggroups *groups = GDBARCH_OBSTACK_ZALLOC (gdbarch,
83b725ae77Skettenis 						     struct reggroups);
84b725ae77Skettenis   groups->last = &groups->first;
85b725ae77Skettenis   return groups;
86b725ae77Skettenis }
87b725ae77Skettenis 
88b725ae77Skettenis /* Add a register group (with attribute values) to the pre-defined
89b725ae77Skettenis    list.  */
90b725ae77Skettenis 
91b725ae77Skettenis static void
add_group(struct reggroups * groups,struct reggroup * group,struct reggroup_el * el)92b725ae77Skettenis add_group (struct reggroups *groups, struct reggroup *group,
93b725ae77Skettenis 	   struct reggroup_el *el)
94b725ae77Skettenis {
95b725ae77Skettenis   gdb_assert (group != NULL);
96b725ae77Skettenis   el->group = group;
97b725ae77Skettenis   el->next = NULL;
98b725ae77Skettenis   (*groups->last) = el;
99b725ae77Skettenis   groups->last = &el->next;
100b725ae77Skettenis }
101b725ae77Skettenis 
102b725ae77Skettenis void
reggroup_add(struct gdbarch * gdbarch,struct reggroup * group)103b725ae77Skettenis reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
104b725ae77Skettenis {
105b725ae77Skettenis   struct reggroups *groups = gdbarch_data (gdbarch, reggroups_data);
106b725ae77Skettenis 
107b725ae77Skettenis   if (groups == NULL)
108b725ae77Skettenis     {
109b725ae77Skettenis       /* ULGH, called during architecture initialization.  Patch
110b725ae77Skettenis          things up.  */
111b725ae77Skettenis       groups = reggroups_init (gdbarch);
112*11efff7fSkettenis       deprecated_set_gdbarch_data (gdbarch, reggroups_data, groups);
113b725ae77Skettenis     }
114b725ae77Skettenis   add_group (groups, group,
115b725ae77Skettenis 	     GDBARCH_OBSTACK_ZALLOC (gdbarch, struct reggroup_el));
116b725ae77Skettenis }
117b725ae77Skettenis 
118b725ae77Skettenis /* The default register groups for an architecture.  */
119b725ae77Skettenis 
120b725ae77Skettenis static struct reggroups default_groups = { NULL, &default_groups.first };
121b725ae77Skettenis 
122b725ae77Skettenis /* A register group iterator.  */
123b725ae77Skettenis 
124b725ae77Skettenis struct reggroup *
reggroup_next(struct gdbarch * gdbarch,struct reggroup * last)125b725ae77Skettenis reggroup_next (struct gdbarch *gdbarch, struct reggroup *last)
126b725ae77Skettenis {
127b725ae77Skettenis   struct reggroups *groups;
128b725ae77Skettenis   struct reggroup_el *el;
129b725ae77Skettenis 
130b725ae77Skettenis   /* Don't allow this function to be called during architecture
131b725ae77Skettenis      creation.  If there are no groups, use the default groups list.  */
132b725ae77Skettenis   groups = gdbarch_data (gdbarch, reggroups_data);
133b725ae77Skettenis   gdb_assert (groups != NULL);
134b725ae77Skettenis   if (groups->first == NULL)
135b725ae77Skettenis     groups = &default_groups;
136b725ae77Skettenis 
137b725ae77Skettenis   /* Return the first/next reggroup.  */
138b725ae77Skettenis   if (last == NULL)
139b725ae77Skettenis     return groups->first->group;
140b725ae77Skettenis   for (el = groups->first; el != NULL; el = el->next)
141b725ae77Skettenis     {
142b725ae77Skettenis       if (el->group == last)
143b725ae77Skettenis 	{
144b725ae77Skettenis 	  if (el->next != NULL)
145b725ae77Skettenis 	    return el->next->group;
146b725ae77Skettenis 	  else
147b725ae77Skettenis 	    return NULL;
148b725ae77Skettenis 	}
149b725ae77Skettenis     }
150b725ae77Skettenis   return NULL;
151b725ae77Skettenis }
152b725ae77Skettenis 
153b725ae77Skettenis /* Is REGNUM a member of REGGROUP?  */
154b725ae77Skettenis int
default_register_reggroup_p(struct gdbarch * gdbarch,int regnum,struct reggroup * group)155b725ae77Skettenis default_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
156b725ae77Skettenis 			     struct reggroup *group)
157b725ae77Skettenis {
158b725ae77Skettenis   int vector_p;
159b725ae77Skettenis   int float_p;
160b725ae77Skettenis   int raw_p;
161b725ae77Skettenis 
162b725ae77Skettenis   if (REGISTER_NAME (regnum) == NULL
163b725ae77Skettenis       || *REGISTER_NAME (regnum) == '\0')
164b725ae77Skettenis     return 0;
165b725ae77Skettenis   if (group == all_reggroup)
166b725ae77Skettenis     return 1;
167b725ae77Skettenis   vector_p = TYPE_VECTOR (register_type (gdbarch, regnum));
168b725ae77Skettenis   float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT;
169b725ae77Skettenis   /* FIXME: cagney/2003-04-13: Can't yet use gdbarch_num_regs
170b725ae77Skettenis      (gdbarch), as not all architectures are multi-arch.  */
171b725ae77Skettenis   raw_p = regnum < NUM_REGS;
172b725ae77Skettenis   if (group == float_reggroup)
173b725ae77Skettenis     return float_p;
174b725ae77Skettenis   if (group == vector_reggroup)
175b725ae77Skettenis     return vector_p;
176b725ae77Skettenis   if (group == general_reggroup)
177b725ae77Skettenis     return (!vector_p && !float_p);
178b725ae77Skettenis   if (group == save_reggroup || group == restore_reggroup)
179b725ae77Skettenis     return raw_p;
180b725ae77Skettenis   return 0;
181b725ae77Skettenis }
182b725ae77Skettenis 
183b725ae77Skettenis /* Dump out a table of register groups for the current architecture.  */
184b725ae77Skettenis 
185b725ae77Skettenis static void
reggroups_dump(struct gdbarch * gdbarch,struct ui_file * file)186b725ae77Skettenis reggroups_dump (struct gdbarch *gdbarch, struct ui_file *file)
187b725ae77Skettenis {
188b725ae77Skettenis   struct reggroup *group = NULL;
189b725ae77Skettenis 
190b725ae77Skettenis   do
191b725ae77Skettenis     {
192b725ae77Skettenis       /* Group name.  */
193b725ae77Skettenis       {
194b725ae77Skettenis 	const char *name;
195b725ae77Skettenis 	if (group == NULL)
196b725ae77Skettenis 	  name = "Group";
197b725ae77Skettenis 	else
198b725ae77Skettenis 	  name = reggroup_name (group);
199b725ae77Skettenis 	fprintf_unfiltered (file, " %-10s", name);
200b725ae77Skettenis       }
201b725ae77Skettenis 
202b725ae77Skettenis       /* Group type.  */
203b725ae77Skettenis       {
204b725ae77Skettenis 	const char *type;
205b725ae77Skettenis 	if (group == NULL)
206b725ae77Skettenis 	  type = "Type";
207b725ae77Skettenis 	else
208b725ae77Skettenis 	  {
209b725ae77Skettenis 	    switch (reggroup_type (group))
210b725ae77Skettenis 	      {
211b725ae77Skettenis 	      case USER_REGGROUP:
212b725ae77Skettenis 		type = "user";
213b725ae77Skettenis 		break;
214b725ae77Skettenis 	      case INTERNAL_REGGROUP:
215b725ae77Skettenis 		type = "internal";
216b725ae77Skettenis 		break;
217b725ae77Skettenis 	      default:
218b725ae77Skettenis 		internal_error (__FILE__, __LINE__, "bad switch");
219b725ae77Skettenis 	      }
220b725ae77Skettenis 	  }
221b725ae77Skettenis 	fprintf_unfiltered (file, " %-10s", type);
222b725ae77Skettenis       }
223b725ae77Skettenis 
224b725ae77Skettenis       /* Note: If you change this, be sure to also update the
225b725ae77Skettenis          documentation.  */
226b725ae77Skettenis 
227b725ae77Skettenis       fprintf_unfiltered (file, "\n");
228b725ae77Skettenis 
229b725ae77Skettenis       group = reggroup_next (gdbarch, group);
230b725ae77Skettenis     }
231b725ae77Skettenis   while (group != NULL);
232b725ae77Skettenis }
233b725ae77Skettenis 
234b725ae77Skettenis static void
maintenance_print_reggroups(char * args,int from_tty)235b725ae77Skettenis maintenance_print_reggroups (char *args, int from_tty)
236b725ae77Skettenis {
237b725ae77Skettenis   if (args == NULL)
238b725ae77Skettenis     reggroups_dump (current_gdbarch, gdb_stdout);
239b725ae77Skettenis   else
240b725ae77Skettenis     {
241b725ae77Skettenis       struct ui_file *file = gdb_fopen (args, "w");
242b725ae77Skettenis       if (file == NULL)
243b725ae77Skettenis 	perror_with_name ("maintenance print reggroups");
244b725ae77Skettenis       reggroups_dump (current_gdbarch, file);
245b725ae77Skettenis       ui_file_delete (file);
246b725ae77Skettenis     }
247b725ae77Skettenis }
248b725ae77Skettenis 
249b725ae77Skettenis /* Pre-defined register groups.  */
250b725ae77Skettenis static struct reggroup general_group = { "general", USER_REGGROUP };
251b725ae77Skettenis static struct reggroup float_group = { "float", USER_REGGROUP };
252b725ae77Skettenis static struct reggroup system_group = { "system", USER_REGGROUP };
253b725ae77Skettenis static struct reggroup vector_group = { "vector", USER_REGGROUP };
254b725ae77Skettenis static struct reggroup all_group = { "all", USER_REGGROUP };
255b725ae77Skettenis static struct reggroup save_group = { "save", INTERNAL_REGGROUP };
256b725ae77Skettenis static struct reggroup restore_group = { "restore", INTERNAL_REGGROUP };
257b725ae77Skettenis 
258b725ae77Skettenis struct reggroup *const general_reggroup = &general_group;
259b725ae77Skettenis struct reggroup *const float_reggroup = &float_group;
260b725ae77Skettenis struct reggroup *const system_reggroup = &system_group;
261b725ae77Skettenis struct reggroup *const vector_reggroup = &vector_group;
262b725ae77Skettenis struct reggroup *const all_reggroup = &all_group;
263b725ae77Skettenis struct reggroup *const save_reggroup = &save_group;
264b725ae77Skettenis struct reggroup *const restore_reggroup = &restore_group;
265b725ae77Skettenis 
266b725ae77Skettenis extern initialize_file_ftype _initialize_reggroup; /* -Wmissing-prototypes */
267b725ae77Skettenis 
268b725ae77Skettenis void
_initialize_reggroup(void)269b725ae77Skettenis _initialize_reggroup (void)
270b725ae77Skettenis {
271*11efff7fSkettenis   reggroups_data = gdbarch_data_register_post_init (reggroups_init);
272b725ae77Skettenis 
273b725ae77Skettenis   /* The pre-defined list of groups.  */
274b725ae77Skettenis   add_group (&default_groups, general_reggroup, XMALLOC (struct reggroup_el));
275b725ae77Skettenis   add_group (&default_groups, float_reggroup, XMALLOC (struct reggroup_el));
276b725ae77Skettenis   add_group (&default_groups, system_reggroup, XMALLOC (struct reggroup_el));
277b725ae77Skettenis   add_group (&default_groups, vector_reggroup, XMALLOC (struct reggroup_el));
278b725ae77Skettenis   add_group (&default_groups, all_reggroup, XMALLOC (struct reggroup_el));
279b725ae77Skettenis   add_group (&default_groups, save_reggroup, XMALLOC (struct reggroup_el));
280b725ae77Skettenis   add_group (&default_groups, restore_reggroup, XMALLOC (struct reggroup_el));
281b725ae77Skettenis 
282b725ae77Skettenis   add_cmd ("reggroups", class_maintenance,
283b725ae77Skettenis 	   maintenance_print_reggroups, "\
284b725ae77Skettenis Print the internal register group names.\n\
285b725ae77Skettenis Takes an optional file parameter.",
286b725ae77Skettenis 	   &maintenanceprintlist);
287b725ae77Skettenis 
288b725ae77Skettenis }
289