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