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