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