1130803Smarcel/* Register groupings for GDB, the GNU debugger.
2130803Smarcel
3130803Smarcel   Copyright 2002, 2003 Free Software Foundation, Inc.
4130803Smarcel
5130803Smarcel   Contributed by Red Hat.
6130803Smarcel
7130803Smarcel   This file is part of GDB.
8130803Smarcel
9130803Smarcel   This program is free software; you can redistribute it and/or modify
10130803Smarcel   it under the terms of the GNU General Public License as published by
11130803Smarcel   the Free Software Foundation; either version 2 of the License, or
12130803Smarcel   (at your option) any later version.
13130803Smarcel
14130803Smarcel   This program is distributed in the hope that it will be useful,
15130803Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
16130803Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17130803Smarcel   GNU General Public License for more details.
18130803Smarcel
19130803Smarcel   You should have received a copy of the GNU General Public License
20130803Smarcel   along with this program; if not, write to the Free Software
21130803Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
22130803Smarcel   Boston, MA 02111-1307, USA.  */
23130803Smarcel
24130803Smarcel#include "defs.h"
25130803Smarcel#include "reggroups.h"
26130803Smarcel#include "gdbtypes.h"
27130803Smarcel#include "gdb_assert.h"
28130803Smarcel#include "regcache.h"
29130803Smarcel#include "command.h"
30130803Smarcel#include "gdbcmd.h"		/* For maintenanceprintlist.  */
31130803Smarcel
32130803Smarcel/* Individual register groups.  */
33130803Smarcel
34130803Smarcelstruct reggroup
35130803Smarcel{
36130803Smarcel  const char *name;
37130803Smarcel  enum reggroup_type type;
38130803Smarcel};
39130803Smarcel
40130803Smarcelstruct reggroup *
41130803Smarcelreggroup_new (const char *name, enum reggroup_type type)
42130803Smarcel{
43130803Smarcel  struct reggroup *group = XMALLOC (struct reggroup);
44130803Smarcel  group->name = name;
45130803Smarcel  group->type = type;
46130803Smarcel  return group;
47130803Smarcel}
48130803Smarcel
49130803Smarcel/* Register group attributes.  */
50130803Smarcel
51130803Smarcelconst char *
52130803Smarcelreggroup_name (struct reggroup *group)
53130803Smarcel{
54130803Smarcel  return group->name;
55130803Smarcel}
56130803Smarcel
57130803Smarcelenum reggroup_type
58130803Smarcelreggroup_type (struct reggroup *group)
59130803Smarcel{
60130803Smarcel  return group->type;
61130803Smarcel}
62130803Smarcel
63130803Smarcel/* A linked list of groups for the given architecture.  */
64130803Smarcel
65130803Smarcelstruct reggroup_el
66130803Smarcel{
67130803Smarcel  struct reggroup *group;
68130803Smarcel  struct reggroup_el *next;
69130803Smarcel};
70130803Smarcel
71130803Smarcelstruct reggroups
72130803Smarcel{
73130803Smarcel  struct reggroup_el *first;
74130803Smarcel  struct reggroup_el **last;
75130803Smarcel};
76130803Smarcel
77130803Smarcelstatic struct gdbarch_data *reggroups_data;
78130803Smarcel
79130803Smarcelstatic void *
80130803Smarcelreggroups_init (struct gdbarch *gdbarch)
81130803Smarcel{
82130803Smarcel  struct reggroups *groups = GDBARCH_OBSTACK_ZALLOC (gdbarch,
83130803Smarcel						     struct reggroups);
84130803Smarcel  groups->last = &groups->first;
85130803Smarcel  return groups;
86130803Smarcel}
87130803Smarcel
88130803Smarcel/* Add a register group (with attribute values) to the pre-defined
89130803Smarcel   list.  */
90130803Smarcel
91130803Smarcelstatic void
92130803Smarceladd_group (struct reggroups *groups, struct reggroup *group,
93130803Smarcel	   struct reggroup_el *el)
94130803Smarcel{
95130803Smarcel  gdb_assert (group != NULL);
96130803Smarcel  el->group = group;
97130803Smarcel  el->next = NULL;
98130803Smarcel  (*groups->last) = el;
99130803Smarcel  groups->last = &el->next;
100130803Smarcel}
101130803Smarcel
102130803Smarcelvoid
103130803Smarcelreggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
104130803Smarcel{
105130803Smarcel  struct reggroups *groups = gdbarch_data (gdbarch, reggroups_data);
106130803Smarcel
107130803Smarcel  if (groups == NULL)
108130803Smarcel    {
109130803Smarcel      /* ULGH, called during architecture initialization.  Patch
110130803Smarcel         things up.  */
111130803Smarcel      groups = reggroups_init (gdbarch);
112130803Smarcel      set_gdbarch_data (gdbarch, reggroups_data, groups);
113130803Smarcel    }
114130803Smarcel  add_group (groups, group,
115130803Smarcel	     GDBARCH_OBSTACK_ZALLOC (gdbarch, struct reggroup_el));
116130803Smarcel}
117130803Smarcel
118130803Smarcel/* The default register groups for an architecture.  */
119130803Smarcel
120130803Smarcelstatic struct reggroups default_groups = { NULL, &default_groups.first };
121130803Smarcel
122130803Smarcel/* A register group iterator.  */
123130803Smarcel
124130803Smarcelstruct reggroup *
125130803Smarcelreggroup_next (struct gdbarch *gdbarch, struct reggroup *last)
126130803Smarcel{
127130803Smarcel  struct reggroups *groups;
128130803Smarcel  struct reggroup_el *el;
129130803Smarcel
130130803Smarcel  /* Don't allow this function to be called during architecture
131130803Smarcel     creation.  If there are no groups, use the default groups list.  */
132130803Smarcel  groups = gdbarch_data (gdbarch, reggroups_data);
133130803Smarcel  gdb_assert (groups != NULL);
134130803Smarcel  if (groups->first == NULL)
135130803Smarcel    groups = &default_groups;
136130803Smarcel
137130803Smarcel  /* Return the first/next reggroup.  */
138130803Smarcel  if (last == NULL)
139130803Smarcel    return groups->first->group;
140130803Smarcel  for (el = groups->first; el != NULL; el = el->next)
141130803Smarcel    {
142130803Smarcel      if (el->group == last)
143130803Smarcel	{
144130803Smarcel	  if (el->next != NULL)
145130803Smarcel	    return el->next->group;
146130803Smarcel	  else
147130803Smarcel	    return NULL;
148130803Smarcel	}
149130803Smarcel    }
150130803Smarcel  return NULL;
151130803Smarcel}
152130803Smarcel
153130803Smarcel/* Is REGNUM a member of REGGROUP?  */
154130803Smarcelint
155130803Smarceldefault_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
156130803Smarcel			     struct reggroup *group)
157130803Smarcel{
158130803Smarcel  int vector_p;
159130803Smarcel  int float_p;
160130803Smarcel  int raw_p;
161130803Smarcel
162130803Smarcel  if (REGISTER_NAME (regnum) == NULL
163130803Smarcel      || *REGISTER_NAME (regnum) == '\0')
164130803Smarcel    return 0;
165130803Smarcel  if (group == all_reggroup)
166130803Smarcel    return 1;
167130803Smarcel  vector_p = TYPE_VECTOR (register_type (gdbarch, regnum));
168130803Smarcel  float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT;
169130803Smarcel  /* FIXME: cagney/2003-04-13: Can't yet use gdbarch_num_regs
170130803Smarcel     (gdbarch), as not all architectures are multi-arch.  */
171130803Smarcel  raw_p = regnum < NUM_REGS;
172130803Smarcel  if (group == float_reggroup)
173130803Smarcel    return float_p;
174130803Smarcel  if (group == vector_reggroup)
175130803Smarcel    return vector_p;
176130803Smarcel  if (group == general_reggroup)
177130803Smarcel    return (!vector_p && !float_p);
178130803Smarcel  if (group == save_reggroup || group == restore_reggroup)
179130803Smarcel    return raw_p;
180130803Smarcel  return 0;
181130803Smarcel}
182130803Smarcel
183130803Smarcel/* Dump out a table of register groups for the current architecture.  */
184130803Smarcel
185130803Smarcelstatic void
186130803Smarcelreggroups_dump (struct gdbarch *gdbarch, struct ui_file *file)
187130803Smarcel{
188130803Smarcel  struct reggroup *group = NULL;
189130803Smarcel
190130803Smarcel  do
191130803Smarcel    {
192130803Smarcel      /* Group name.  */
193130803Smarcel      {
194130803Smarcel	const char *name;
195130803Smarcel	if (group == NULL)
196130803Smarcel	  name = "Group";
197130803Smarcel	else
198130803Smarcel	  name = reggroup_name (group);
199130803Smarcel	fprintf_unfiltered (file, " %-10s", name);
200130803Smarcel      }
201130803Smarcel
202130803Smarcel      /* Group type.  */
203130803Smarcel      {
204130803Smarcel	const char *type;
205130803Smarcel	if (group == NULL)
206130803Smarcel	  type = "Type";
207130803Smarcel	else
208130803Smarcel	  {
209130803Smarcel	    switch (reggroup_type (group))
210130803Smarcel	      {
211130803Smarcel	      case USER_REGGROUP:
212130803Smarcel		type = "user";
213130803Smarcel		break;
214130803Smarcel	      case INTERNAL_REGGROUP:
215130803Smarcel		type = "internal";
216130803Smarcel		break;
217130803Smarcel	      default:
218130803Smarcel		internal_error (__FILE__, __LINE__, "bad switch");
219130803Smarcel	      }
220130803Smarcel	  }
221130803Smarcel	fprintf_unfiltered (file, " %-10s", type);
222130803Smarcel      }
223130803Smarcel
224130803Smarcel      /* Note: If you change this, be sure to also update the
225130803Smarcel         documentation.  */
226130803Smarcel
227130803Smarcel      fprintf_unfiltered (file, "\n");
228130803Smarcel
229130803Smarcel      group = reggroup_next (gdbarch, group);
230130803Smarcel    }
231130803Smarcel  while (group != NULL);
232130803Smarcel}
233130803Smarcel
234130803Smarcelstatic void
235130803Smarcelmaintenance_print_reggroups (char *args, int from_tty)
236130803Smarcel{
237130803Smarcel  if (args == NULL)
238130803Smarcel    reggroups_dump (current_gdbarch, gdb_stdout);
239130803Smarcel  else
240130803Smarcel    {
241130803Smarcel      struct ui_file *file = gdb_fopen (args, "w");
242130803Smarcel      if (file == NULL)
243130803Smarcel	perror_with_name ("maintenance print reggroups");
244130803Smarcel      reggroups_dump (current_gdbarch, file);
245130803Smarcel      ui_file_delete (file);
246130803Smarcel    }
247130803Smarcel}
248130803Smarcel
249130803Smarcel/* Pre-defined register groups.  */
250130803Smarcelstatic struct reggroup general_group = { "general", USER_REGGROUP };
251130803Smarcelstatic struct reggroup float_group = { "float", USER_REGGROUP };
252130803Smarcelstatic struct reggroup system_group = { "system", USER_REGGROUP };
253130803Smarcelstatic struct reggroup vector_group = { "vector", USER_REGGROUP };
254130803Smarcelstatic struct reggroup all_group = { "all", USER_REGGROUP };
255130803Smarcelstatic struct reggroup save_group = { "save", INTERNAL_REGGROUP };
256130803Smarcelstatic struct reggroup restore_group = { "restore", INTERNAL_REGGROUP };
257130803Smarcel
258130803Smarcelstruct reggroup *const general_reggroup = &general_group;
259130803Smarcelstruct reggroup *const float_reggroup = &float_group;
260130803Smarcelstruct reggroup *const system_reggroup = &system_group;
261130803Smarcelstruct reggroup *const vector_reggroup = &vector_group;
262130803Smarcelstruct reggroup *const all_reggroup = &all_group;
263130803Smarcelstruct reggroup *const save_reggroup = &save_group;
264130803Smarcelstruct reggroup *const restore_reggroup = &restore_group;
265130803Smarcel
266130803Smarcelextern initialize_file_ftype _initialize_reggroup; /* -Wmissing-prototypes */
267130803Smarcel
268130803Smarcelvoid
269130803Smarcel_initialize_reggroup (void)
270130803Smarcel{
271130803Smarcel  reggroups_data = register_gdbarch_data (reggroups_init);
272130803Smarcel
273130803Smarcel  /* The pre-defined list of groups.  */
274130803Smarcel  add_group (&default_groups, general_reggroup, XMALLOC (struct reggroup_el));
275130803Smarcel  add_group (&default_groups, float_reggroup, XMALLOC (struct reggroup_el));
276130803Smarcel  add_group (&default_groups, system_reggroup, XMALLOC (struct reggroup_el));
277130803Smarcel  add_group (&default_groups, vector_reggroup, XMALLOC (struct reggroup_el));
278130803Smarcel  add_group (&default_groups, all_reggroup, XMALLOC (struct reggroup_el));
279130803Smarcel  add_group (&default_groups, save_reggroup, XMALLOC (struct reggroup_el));
280130803Smarcel  add_group (&default_groups, restore_reggroup, XMALLOC (struct reggroup_el));
281130803Smarcel
282130803Smarcel  add_cmd ("reggroups", class_maintenance,
283130803Smarcel	   maintenance_print_reggroups, "\
284130803SmarcelPrint the internal register group names.\n\
285130803SmarcelTakes an optional file parameter.",
286130803Smarcel	   &maintenanceprintlist);
287130803Smarcel
288130803Smarcel}
289