xref: /dflybsd-src/contrib/gdb-7/gdb/regcache.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Cache and manage the values of registers for GDB, the GNU debugger.
25796c8dcSSimon Schubert 
3*ef5ccd6cSJohn Marino    Copyright (C) 1986-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    This file is part of GDB.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert    (at your option) any later version.
115796c8dcSSimon Schubert 
125796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155796c8dcSSimon Schubert    GNU General Public License for more details.
165796c8dcSSimon Schubert 
175796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
195796c8dcSSimon Schubert 
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert #include "inferior.h"
225796c8dcSSimon Schubert #include "target.h"
235796c8dcSSimon Schubert #include "gdbarch.h"
245796c8dcSSimon Schubert #include "gdbcmd.h"
255796c8dcSSimon Schubert #include "regcache.h"
265796c8dcSSimon Schubert #include "reggroups.h"
275796c8dcSSimon Schubert #include "gdb_assert.h"
285796c8dcSSimon Schubert #include "gdb_string.h"
295796c8dcSSimon Schubert #include "gdbcmd.h"		/* For maintenanceprintlist.  */
305796c8dcSSimon Schubert #include "observer.h"
31c50c785cSJohn Marino #include "exceptions.h"
32a45ae5f8SJohn Marino #include "remote.h"
335796c8dcSSimon Schubert 
345796c8dcSSimon Schubert /*
355796c8dcSSimon Schubert  * DATA STRUCTURE
365796c8dcSSimon Schubert  *
375796c8dcSSimon Schubert  * Here is the actual register cache.
385796c8dcSSimon Schubert  */
395796c8dcSSimon Schubert 
405796c8dcSSimon Schubert /* Per-architecture object describing the layout of a register cache.
41c50c785cSJohn Marino    Computed once when the architecture is created.  */
425796c8dcSSimon Schubert 
435796c8dcSSimon Schubert struct gdbarch_data *regcache_descr_handle;
445796c8dcSSimon Schubert 
455796c8dcSSimon Schubert struct regcache_descr
465796c8dcSSimon Schubert {
475796c8dcSSimon Schubert   /* The architecture this descriptor belongs to.  */
485796c8dcSSimon Schubert   struct gdbarch *gdbarch;
495796c8dcSSimon Schubert 
505796c8dcSSimon Schubert   /* The raw register cache.  Each raw (or hard) register is supplied
515796c8dcSSimon Schubert      by the target interface.  The raw cache should not contain
525796c8dcSSimon Schubert      redundant information - if the PC is constructed from two
535796c8dcSSimon Schubert      registers then those registers and not the PC lives in the raw
545796c8dcSSimon Schubert      cache.  */
555796c8dcSSimon Schubert   int nr_raw_registers;
565796c8dcSSimon Schubert   long sizeof_raw_registers;
57c50c785cSJohn Marino   long sizeof_raw_register_status;
585796c8dcSSimon Schubert 
595796c8dcSSimon Schubert   /* The cooked register space.  Each cooked register in the range
605796c8dcSSimon Schubert      [0..NR_RAW_REGISTERS) is direct-mapped onto the corresponding raw
615796c8dcSSimon Schubert      register.  The remaining [NR_RAW_REGISTERS
625796c8dcSSimon Schubert      .. NR_COOKED_REGISTERS) (a.k.a. pseudo registers) are mapped onto
635796c8dcSSimon Schubert      both raw registers and memory by the architecture methods
645796c8dcSSimon Schubert      gdbarch_pseudo_register_read and gdbarch_pseudo_register_write.  */
655796c8dcSSimon Schubert   int nr_cooked_registers;
665796c8dcSSimon Schubert   long sizeof_cooked_registers;
67c50c785cSJohn Marino   long sizeof_cooked_register_status;
685796c8dcSSimon Schubert 
69a45ae5f8SJohn Marino   /* Offset and size (in 8 bit bytes), of each register in the
705796c8dcSSimon Schubert      register cache.  All registers (including those in the range
71c50c785cSJohn Marino      [NR_RAW_REGISTERS .. NR_COOKED_REGISTERS) are given an
72c50c785cSJohn Marino      offset.  */
735796c8dcSSimon Schubert   long *register_offset;
745796c8dcSSimon Schubert   long *sizeof_register;
755796c8dcSSimon Schubert 
765796c8dcSSimon Schubert   /* Cached table containing the type of each register.  */
775796c8dcSSimon Schubert   struct type **register_type;
785796c8dcSSimon Schubert };
795796c8dcSSimon Schubert 
805796c8dcSSimon Schubert static void *
init_regcache_descr(struct gdbarch * gdbarch)815796c8dcSSimon Schubert init_regcache_descr (struct gdbarch *gdbarch)
825796c8dcSSimon Schubert {
835796c8dcSSimon Schubert   int i;
845796c8dcSSimon Schubert   struct regcache_descr *descr;
855796c8dcSSimon Schubert   gdb_assert (gdbarch != NULL);
865796c8dcSSimon Schubert 
875796c8dcSSimon Schubert   /* Create an initial, zero filled, table.  */
885796c8dcSSimon Schubert   descr = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct regcache_descr);
895796c8dcSSimon Schubert   descr->gdbarch = gdbarch;
905796c8dcSSimon Schubert 
915796c8dcSSimon Schubert   /* Total size of the register space.  The raw registers are mapped
925796c8dcSSimon Schubert      directly onto the raw register cache while the pseudo's are
935796c8dcSSimon Schubert      either mapped onto raw-registers or memory.  */
945796c8dcSSimon Schubert   descr->nr_cooked_registers = gdbarch_num_regs (gdbarch)
955796c8dcSSimon Schubert 			       + gdbarch_num_pseudo_regs (gdbarch);
96c50c785cSJohn Marino   descr->sizeof_cooked_register_status
97c50c785cSJohn Marino     = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
985796c8dcSSimon Schubert 
995796c8dcSSimon Schubert   /* Fill in a table of register types.  */
1005796c8dcSSimon Schubert   descr->register_type
101c50c785cSJohn Marino     = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers,
102c50c785cSJohn Marino 			      struct type *);
1035796c8dcSSimon Schubert   for (i = 0; i < descr->nr_cooked_registers; i++)
1045796c8dcSSimon Schubert     descr->register_type[i] = gdbarch_register_type (gdbarch, i);
1055796c8dcSSimon Schubert 
1065796c8dcSSimon Schubert   /* Construct a strictly RAW register cache.  Don't allow pseudo's
1075796c8dcSSimon Schubert      into the register cache.  */
1085796c8dcSSimon Schubert   descr->nr_raw_registers = gdbarch_num_regs (gdbarch);
109c50c785cSJohn Marino   descr->sizeof_raw_register_status = gdbarch_num_regs (gdbarch);
1105796c8dcSSimon Schubert 
1115796c8dcSSimon Schubert   /* Lay out the register cache.
1125796c8dcSSimon Schubert 
1135796c8dcSSimon Schubert      NOTE: cagney/2002-05-22: Only register_type() is used when
1145796c8dcSSimon Schubert      constructing the register cache.  It is assumed that the
1155796c8dcSSimon Schubert      register's raw size, virtual size and type length are all the
1165796c8dcSSimon Schubert      same.  */
1175796c8dcSSimon Schubert 
1185796c8dcSSimon Schubert   {
1195796c8dcSSimon Schubert     long offset = 0;
120cf7f2e2dSJohn Marino 
1215796c8dcSSimon Schubert     descr->sizeof_register
1225796c8dcSSimon Schubert       = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long);
1235796c8dcSSimon Schubert     descr->register_offset
1245796c8dcSSimon Schubert       = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long);
125c50c785cSJohn Marino     for (i = 0; i < descr->nr_raw_registers; i++)
1265796c8dcSSimon Schubert       {
1275796c8dcSSimon Schubert 	descr->sizeof_register[i] = TYPE_LENGTH (descr->register_type[i]);
1285796c8dcSSimon Schubert 	descr->register_offset[i] = offset;
1295796c8dcSSimon Schubert 	offset += descr->sizeof_register[i];
1305796c8dcSSimon Schubert 	gdb_assert (MAX_REGISTER_SIZE >= descr->sizeof_register[i]);
1315796c8dcSSimon Schubert       }
132c50c785cSJohn Marino     /* Set the real size of the raw register cache buffer.  */
133c50c785cSJohn Marino     descr->sizeof_raw_registers = offset;
134c50c785cSJohn Marino 
135c50c785cSJohn Marino     for (; i < descr->nr_cooked_registers; i++)
136c50c785cSJohn Marino       {
137c50c785cSJohn Marino 	descr->sizeof_register[i] = TYPE_LENGTH (descr->register_type[i]);
138c50c785cSJohn Marino 	descr->register_offset[i] = offset;
139c50c785cSJohn Marino 	offset += descr->sizeof_register[i];
140c50c785cSJohn Marino 	gdb_assert (MAX_REGISTER_SIZE >= descr->sizeof_register[i]);
141c50c785cSJohn Marino       }
142c50c785cSJohn Marino     /* Set the real size of the readonly register cache buffer.  */
1435796c8dcSSimon Schubert     descr->sizeof_cooked_registers = offset;
1445796c8dcSSimon Schubert   }
1455796c8dcSSimon Schubert 
1465796c8dcSSimon Schubert   return descr;
1475796c8dcSSimon Schubert }
1485796c8dcSSimon Schubert 
1495796c8dcSSimon Schubert static struct regcache_descr *
regcache_descr(struct gdbarch * gdbarch)1505796c8dcSSimon Schubert regcache_descr (struct gdbarch *gdbarch)
1515796c8dcSSimon Schubert {
1525796c8dcSSimon Schubert   return gdbarch_data (gdbarch, regcache_descr_handle);
1535796c8dcSSimon Schubert }
1545796c8dcSSimon Schubert 
1555796c8dcSSimon Schubert /* Utility functions returning useful register attributes stored in
1565796c8dcSSimon Schubert    the regcache descr.  */
1575796c8dcSSimon Schubert 
1585796c8dcSSimon Schubert struct type *
register_type(struct gdbarch * gdbarch,int regnum)1595796c8dcSSimon Schubert register_type (struct gdbarch *gdbarch, int regnum)
1605796c8dcSSimon Schubert {
1615796c8dcSSimon Schubert   struct regcache_descr *descr = regcache_descr (gdbarch);
162cf7f2e2dSJohn Marino 
1635796c8dcSSimon Schubert   gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers);
1645796c8dcSSimon Schubert   return descr->register_type[regnum];
1655796c8dcSSimon Schubert }
1665796c8dcSSimon Schubert 
1675796c8dcSSimon Schubert /* Utility functions returning useful register attributes stored in
1685796c8dcSSimon Schubert    the regcache descr.  */
1695796c8dcSSimon Schubert 
1705796c8dcSSimon Schubert int
register_size(struct gdbarch * gdbarch,int regnum)1715796c8dcSSimon Schubert register_size (struct gdbarch *gdbarch, int regnum)
1725796c8dcSSimon Schubert {
1735796c8dcSSimon Schubert   struct regcache_descr *descr = regcache_descr (gdbarch);
1745796c8dcSSimon Schubert   int size;
175cf7f2e2dSJohn Marino 
1765796c8dcSSimon Schubert   gdb_assert (regnum >= 0
1775796c8dcSSimon Schubert 	      && regnum < (gdbarch_num_regs (gdbarch)
1785796c8dcSSimon Schubert 			   + gdbarch_num_pseudo_regs (gdbarch)));
1795796c8dcSSimon Schubert   size = descr->sizeof_register[regnum];
1805796c8dcSSimon Schubert   return size;
1815796c8dcSSimon Schubert }
1825796c8dcSSimon Schubert 
1835796c8dcSSimon Schubert /* The register cache for storing raw register values.  */
1845796c8dcSSimon Schubert 
1855796c8dcSSimon Schubert struct regcache
1865796c8dcSSimon Schubert {
1875796c8dcSSimon Schubert   struct regcache_descr *descr;
188cf7f2e2dSJohn Marino 
189cf7f2e2dSJohn Marino   /* The address space of this register cache (for registers where it
190cf7f2e2dSJohn Marino      makes sense, like PC or SP).  */
191cf7f2e2dSJohn Marino   struct address_space *aspace;
192cf7f2e2dSJohn Marino 
1935796c8dcSSimon Schubert   /* The register buffers.  A read-only register cache can hold the
1945796c8dcSSimon Schubert      full [0 .. gdbarch_num_regs + gdbarch_num_pseudo_regs) while a read/write
1955796c8dcSSimon Schubert      register cache can only hold [0 .. gdbarch_num_regs).  */
1965796c8dcSSimon Schubert   gdb_byte *registers;
197c50c785cSJohn Marino   /* Register cache status.  */
198c50c785cSJohn Marino   signed char *register_status;
1995796c8dcSSimon Schubert   /* Is this a read-only cache?  A read-only cache is used for saving
2005796c8dcSSimon Schubert      the target's register state (e.g, across an inferior function
2015796c8dcSSimon Schubert      call or just before forcing a function return).  A read-only
2025796c8dcSSimon Schubert      cache can only be updated via the methods regcache_dup() and
2035796c8dcSSimon Schubert      regcache_cpy().  The actual contents are determined by the
2045796c8dcSSimon Schubert      reggroup_save and reggroup_restore methods.  */
2055796c8dcSSimon Schubert   int readonly_p;
2065796c8dcSSimon Schubert   /* If this is a read-write cache, which thread's registers is
2075796c8dcSSimon Schubert      it connected to?  */
2085796c8dcSSimon Schubert   ptid_t ptid;
2095796c8dcSSimon Schubert };
2105796c8dcSSimon Schubert 
211c50c785cSJohn Marino static struct regcache *
regcache_xmalloc_1(struct gdbarch * gdbarch,struct address_space * aspace,int readonly_p)212c50c785cSJohn Marino regcache_xmalloc_1 (struct gdbarch *gdbarch, struct address_space *aspace,
213c50c785cSJohn Marino 		    int readonly_p)
2145796c8dcSSimon Schubert {
2155796c8dcSSimon Schubert   struct regcache_descr *descr;
2165796c8dcSSimon Schubert   struct regcache *regcache;
217cf7f2e2dSJohn Marino 
2185796c8dcSSimon Schubert   gdb_assert (gdbarch != NULL);
2195796c8dcSSimon Schubert   descr = regcache_descr (gdbarch);
2205796c8dcSSimon Schubert   regcache = XMALLOC (struct regcache);
2215796c8dcSSimon Schubert   regcache->descr = descr;
222c50c785cSJohn Marino   regcache->readonly_p = readonly_p;
223c50c785cSJohn Marino   if (readonly_p)
224c50c785cSJohn Marino     {
225c50c785cSJohn Marino       regcache->registers
226c50c785cSJohn Marino 	= XCALLOC (descr->sizeof_cooked_registers, gdb_byte);
227c50c785cSJohn Marino       regcache->register_status
228*ef5ccd6cSJohn Marino 	= XCALLOC (descr->sizeof_cooked_register_status, signed char);
229c50c785cSJohn Marino     }
230c50c785cSJohn Marino   else
231c50c785cSJohn Marino     {
2325796c8dcSSimon Schubert       regcache->registers
2335796c8dcSSimon Schubert 	= XCALLOC (descr->sizeof_raw_registers, gdb_byte);
234c50c785cSJohn Marino       regcache->register_status
235*ef5ccd6cSJohn Marino 	= XCALLOC (descr->sizeof_raw_register_status, signed char);
236c50c785cSJohn Marino     }
237cf7f2e2dSJohn Marino   regcache->aspace = aspace;
2385796c8dcSSimon Schubert   regcache->ptid = minus_one_ptid;
2395796c8dcSSimon Schubert   return regcache;
2405796c8dcSSimon Schubert }
2415796c8dcSSimon Schubert 
242c50c785cSJohn Marino struct regcache *
regcache_xmalloc(struct gdbarch * gdbarch,struct address_space * aspace)243c50c785cSJohn Marino regcache_xmalloc (struct gdbarch *gdbarch, struct address_space *aspace)
244c50c785cSJohn Marino {
245c50c785cSJohn Marino   return regcache_xmalloc_1 (gdbarch, aspace, 1);
246c50c785cSJohn Marino }
247c50c785cSJohn Marino 
2485796c8dcSSimon Schubert void
regcache_xfree(struct regcache * regcache)2495796c8dcSSimon Schubert regcache_xfree (struct regcache *regcache)
2505796c8dcSSimon Schubert {
2515796c8dcSSimon Schubert   if (regcache == NULL)
2525796c8dcSSimon Schubert     return;
2535796c8dcSSimon Schubert   xfree (regcache->registers);
254c50c785cSJohn Marino   xfree (regcache->register_status);
2555796c8dcSSimon Schubert   xfree (regcache);
2565796c8dcSSimon Schubert }
2575796c8dcSSimon Schubert 
2585796c8dcSSimon Schubert static void
do_regcache_xfree(void * data)2595796c8dcSSimon Schubert do_regcache_xfree (void *data)
2605796c8dcSSimon Schubert {
2615796c8dcSSimon Schubert   regcache_xfree (data);
2625796c8dcSSimon Schubert }
2635796c8dcSSimon Schubert 
2645796c8dcSSimon Schubert struct cleanup *
make_cleanup_regcache_xfree(struct regcache * regcache)2655796c8dcSSimon Schubert make_cleanup_regcache_xfree (struct regcache *regcache)
2665796c8dcSSimon Schubert {
2675796c8dcSSimon Schubert   return make_cleanup (do_regcache_xfree, regcache);
2685796c8dcSSimon Schubert }
2695796c8dcSSimon Schubert 
2705796c8dcSSimon Schubert /* Return REGCACHE's architecture.  */
2715796c8dcSSimon Schubert 
2725796c8dcSSimon Schubert struct gdbarch *
get_regcache_arch(const struct regcache * regcache)2735796c8dcSSimon Schubert get_regcache_arch (const struct regcache *regcache)
2745796c8dcSSimon Schubert {
2755796c8dcSSimon Schubert   return regcache->descr->gdbarch;
2765796c8dcSSimon Schubert }
2775796c8dcSSimon Schubert 
278cf7f2e2dSJohn Marino struct address_space *
get_regcache_aspace(const struct regcache * regcache)279cf7f2e2dSJohn Marino get_regcache_aspace (const struct regcache *regcache)
280cf7f2e2dSJohn Marino {
281cf7f2e2dSJohn Marino   return regcache->aspace;
282cf7f2e2dSJohn Marino }
283cf7f2e2dSJohn Marino 
2845796c8dcSSimon Schubert /* Return  a pointer to register REGNUM's buffer cache.  */
2855796c8dcSSimon Schubert 
2865796c8dcSSimon Schubert static gdb_byte *
register_buffer(const struct regcache * regcache,int regnum)2875796c8dcSSimon Schubert register_buffer (const struct regcache *regcache, int regnum)
2885796c8dcSSimon Schubert {
2895796c8dcSSimon Schubert   return regcache->registers + regcache->descr->register_offset[regnum];
2905796c8dcSSimon Schubert }
2915796c8dcSSimon Schubert 
2925796c8dcSSimon Schubert void
regcache_save(struct regcache * dst,regcache_cooked_read_ftype * cooked_read,void * src)2935796c8dcSSimon Schubert regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
2945796c8dcSSimon Schubert 	       void *src)
2955796c8dcSSimon Schubert {
2965796c8dcSSimon Schubert   struct gdbarch *gdbarch = dst->descr->gdbarch;
2975796c8dcSSimon Schubert   gdb_byte buf[MAX_REGISTER_SIZE];
2985796c8dcSSimon Schubert   int regnum;
299cf7f2e2dSJohn Marino 
3005796c8dcSSimon Schubert   /* The DST should be `read-only', if it wasn't then the save would
3015796c8dcSSimon Schubert      end up trying to write the register values back out to the
3025796c8dcSSimon Schubert      target.  */
3035796c8dcSSimon Schubert   gdb_assert (dst->readonly_p);
3045796c8dcSSimon Schubert   /* Clear the dest.  */
3055796c8dcSSimon Schubert   memset (dst->registers, 0, dst->descr->sizeof_cooked_registers);
306c50c785cSJohn Marino   memset (dst->register_status, 0,
307c50c785cSJohn Marino 	  dst->descr->sizeof_cooked_register_status);
3085796c8dcSSimon Schubert   /* Copy over any registers (identified by their membership in the
3095796c8dcSSimon Schubert      save_reggroup) and mark them as valid.  The full [0 .. gdbarch_num_regs +
3105796c8dcSSimon Schubert      gdbarch_num_pseudo_regs) range is checked since some architectures need
3115796c8dcSSimon Schubert      to save/restore `cooked' registers that live in memory.  */
3125796c8dcSSimon Schubert   for (regnum = 0; regnum < dst->descr->nr_cooked_registers; regnum++)
3135796c8dcSSimon Schubert     {
3145796c8dcSSimon Schubert       if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup))
3155796c8dcSSimon Schubert 	{
316c50c785cSJohn Marino 	  enum register_status status = cooked_read (src, regnum, buf);
317cf7f2e2dSJohn Marino 
318c50c785cSJohn Marino 	  if (status == REG_VALID)
3195796c8dcSSimon Schubert 	    memcpy (register_buffer (dst, regnum), buf,
3205796c8dcSSimon Schubert 		    register_size (gdbarch, regnum));
321c50c785cSJohn Marino 	  else
322c50c785cSJohn Marino 	    {
323c50c785cSJohn Marino 	      gdb_assert (status != REG_UNKNOWN);
324c50c785cSJohn Marino 
325c50c785cSJohn Marino 	      memset (register_buffer (dst, regnum), 0,
326c50c785cSJohn Marino 		      register_size (gdbarch, regnum));
3275796c8dcSSimon Schubert 	    }
328c50c785cSJohn Marino 	  dst->register_status[regnum] = status;
3295796c8dcSSimon Schubert 	}
3305796c8dcSSimon Schubert     }
3315796c8dcSSimon Schubert }
3325796c8dcSSimon Schubert 
333a45ae5f8SJohn Marino static void
regcache_restore(struct regcache * dst,regcache_cooked_read_ftype * cooked_read,void * cooked_read_context)3345796c8dcSSimon Schubert regcache_restore (struct regcache *dst,
3355796c8dcSSimon Schubert 		  regcache_cooked_read_ftype *cooked_read,
3365796c8dcSSimon Schubert 		  void *cooked_read_context)
3375796c8dcSSimon Schubert {
3385796c8dcSSimon Schubert   struct gdbarch *gdbarch = dst->descr->gdbarch;
3395796c8dcSSimon Schubert   gdb_byte buf[MAX_REGISTER_SIZE];
3405796c8dcSSimon Schubert   int regnum;
341cf7f2e2dSJohn Marino 
3425796c8dcSSimon Schubert   /* The dst had better not be read-only.  If it is, the `restore'
3435796c8dcSSimon Schubert      doesn't make much sense.  */
3445796c8dcSSimon Schubert   gdb_assert (!dst->readonly_p);
3455796c8dcSSimon Schubert   /* Copy over any registers, being careful to only restore those that
3465796c8dcSSimon Schubert      were both saved and need to be restored.  The full [0 .. gdbarch_num_regs
3475796c8dcSSimon Schubert      + gdbarch_num_pseudo_regs) range is checked since some architectures need
3485796c8dcSSimon Schubert      to save/restore `cooked' registers that live in memory.  */
3495796c8dcSSimon Schubert   for (regnum = 0; regnum < dst->descr->nr_cooked_registers; regnum++)
3505796c8dcSSimon Schubert     {
3515796c8dcSSimon Schubert       if (gdbarch_register_reggroup_p (gdbarch, regnum, restore_reggroup))
3525796c8dcSSimon Schubert 	{
353a45ae5f8SJohn Marino 	  enum register_status status;
354cf7f2e2dSJohn Marino 
355a45ae5f8SJohn Marino 	  status = cooked_read (cooked_read_context, regnum, buf);
356a45ae5f8SJohn Marino 	  if (status == REG_VALID)
3575796c8dcSSimon Schubert 	    regcache_cooked_write (dst, regnum, buf);
3585796c8dcSSimon Schubert 	}
3595796c8dcSSimon Schubert     }
3605796c8dcSSimon Schubert }
3615796c8dcSSimon Schubert 
362c50c785cSJohn Marino static enum register_status
do_cooked_read(void * src,int regnum,gdb_byte * buf)3635796c8dcSSimon Schubert do_cooked_read (void *src, int regnum, gdb_byte *buf)
3645796c8dcSSimon Schubert {
3655796c8dcSSimon Schubert   struct regcache *regcache = src;
366cf7f2e2dSJohn Marino 
367c50c785cSJohn Marino   return regcache_cooked_read (regcache, regnum, buf);
3685796c8dcSSimon Schubert }
3695796c8dcSSimon Schubert 
3705796c8dcSSimon Schubert void
regcache_cpy(struct regcache * dst,struct regcache * src)3715796c8dcSSimon Schubert regcache_cpy (struct regcache *dst, struct regcache *src)
3725796c8dcSSimon Schubert {
3735796c8dcSSimon Schubert   gdb_assert (src != NULL && dst != NULL);
3745796c8dcSSimon Schubert   gdb_assert (src->descr->gdbarch == dst->descr->gdbarch);
3755796c8dcSSimon Schubert   gdb_assert (src != dst);
3765796c8dcSSimon Schubert   gdb_assert (src->readonly_p || dst->readonly_p);
377cf7f2e2dSJohn Marino 
3785796c8dcSSimon Schubert   if (!src->readonly_p)
3795796c8dcSSimon Schubert     regcache_save (dst, do_cooked_read, src);
3805796c8dcSSimon Schubert   else if (!dst->readonly_p)
3815796c8dcSSimon Schubert     regcache_restore (dst, do_cooked_read, src);
3825796c8dcSSimon Schubert   else
3835796c8dcSSimon Schubert     regcache_cpy_no_passthrough (dst, src);
3845796c8dcSSimon Schubert }
3855796c8dcSSimon Schubert 
3865796c8dcSSimon Schubert void
regcache_cpy_no_passthrough(struct regcache * dst,struct regcache * src)3875796c8dcSSimon Schubert regcache_cpy_no_passthrough (struct regcache *dst, struct regcache *src)
3885796c8dcSSimon Schubert {
3895796c8dcSSimon Schubert   gdb_assert (src != NULL && dst != NULL);
3905796c8dcSSimon Schubert   gdb_assert (src->descr->gdbarch == dst->descr->gdbarch);
3915796c8dcSSimon Schubert   /* NOTE: cagney/2002-05-17: Don't let the caller do a no-passthrough
392c50c785cSJohn Marino      move of data into a thread's regcache.  Doing this would be silly
393c50c785cSJohn Marino      - it would mean that regcache->register_status would be
394c50c785cSJohn Marino      completely invalid.  */
395c50c785cSJohn Marino   gdb_assert (dst->readonly_p && src->readonly_p);
396cf7f2e2dSJohn Marino 
397c50c785cSJohn Marino   memcpy (dst->registers, src->registers,
398c50c785cSJohn Marino 	  dst->descr->sizeof_cooked_registers);
399c50c785cSJohn Marino   memcpy (dst->register_status, src->register_status,
400c50c785cSJohn Marino 	  dst->descr->sizeof_cooked_register_status);
4015796c8dcSSimon Schubert }
4025796c8dcSSimon Schubert 
4035796c8dcSSimon Schubert struct regcache *
regcache_dup(struct regcache * src)4045796c8dcSSimon Schubert regcache_dup (struct regcache *src)
4055796c8dcSSimon Schubert {
4065796c8dcSSimon Schubert   struct regcache *newbuf;
407cf7f2e2dSJohn Marino 
408cf7f2e2dSJohn Marino   newbuf = regcache_xmalloc (src->descr->gdbarch, get_regcache_aspace (src));
4095796c8dcSSimon Schubert   regcache_cpy (newbuf, src);
4105796c8dcSSimon Schubert   return newbuf;
4115796c8dcSSimon Schubert }
4125796c8dcSSimon Schubert 
413*ef5ccd6cSJohn Marino enum register_status
regcache_register_status(const struct regcache * regcache,int regnum)414c50c785cSJohn Marino regcache_register_status (const struct regcache *regcache, int regnum)
4155796c8dcSSimon Schubert {
4165796c8dcSSimon Schubert   gdb_assert (regcache != NULL);
4175796c8dcSSimon Schubert   gdb_assert (regnum >= 0);
4185796c8dcSSimon Schubert   if (regcache->readonly_p)
4195796c8dcSSimon Schubert     gdb_assert (regnum < regcache->descr->nr_cooked_registers);
4205796c8dcSSimon Schubert   else
4215796c8dcSSimon Schubert     gdb_assert (regnum < regcache->descr->nr_raw_registers);
4225796c8dcSSimon Schubert 
423c50c785cSJohn Marino   return regcache->register_status[regnum];
4245796c8dcSSimon Schubert }
4255796c8dcSSimon Schubert 
4265796c8dcSSimon Schubert void
regcache_invalidate(struct regcache * regcache,int regnum)4275796c8dcSSimon Schubert regcache_invalidate (struct regcache *regcache, int regnum)
4285796c8dcSSimon Schubert {
4295796c8dcSSimon Schubert   gdb_assert (regcache != NULL);
4305796c8dcSSimon Schubert   gdb_assert (regnum >= 0);
4315796c8dcSSimon Schubert   gdb_assert (!regcache->readonly_p);
4325796c8dcSSimon Schubert   gdb_assert (regnum < regcache->descr->nr_raw_registers);
433c50c785cSJohn Marino   regcache->register_status[regnum] = REG_UNKNOWN;
4345796c8dcSSimon Schubert }
4355796c8dcSSimon Schubert 
4365796c8dcSSimon Schubert 
4375796c8dcSSimon Schubert /* Global structure containing the current regcache.  */
4385796c8dcSSimon Schubert 
4395796c8dcSSimon Schubert /* NOTE: this is a write-through cache.  There is no "dirty" bit for
4405796c8dcSSimon Schubert    recording if the register values have been changed (eg. by the
4415796c8dcSSimon Schubert    user).  Therefore all registers must be written back to the
4425796c8dcSSimon Schubert    target when appropriate.  */
4435796c8dcSSimon Schubert 
4445796c8dcSSimon Schubert struct regcache_list
4455796c8dcSSimon Schubert {
4465796c8dcSSimon Schubert   struct regcache *regcache;
4475796c8dcSSimon Schubert   struct regcache_list *next;
4485796c8dcSSimon Schubert };
4495796c8dcSSimon Schubert 
4505796c8dcSSimon Schubert static struct regcache_list *current_regcache;
4515796c8dcSSimon Schubert 
4525796c8dcSSimon Schubert struct regcache *
get_thread_arch_aspace_regcache(ptid_t ptid,struct gdbarch * gdbarch,struct address_space * aspace)453a45ae5f8SJohn Marino get_thread_arch_aspace_regcache (ptid_t ptid, struct gdbarch *gdbarch,
454a45ae5f8SJohn Marino 				 struct address_space *aspace)
4555796c8dcSSimon Schubert {
4565796c8dcSSimon Schubert   struct regcache_list *list;
4575796c8dcSSimon Schubert   struct regcache *new_regcache;
4585796c8dcSSimon Schubert 
4595796c8dcSSimon Schubert   for (list = current_regcache; list; list = list->next)
4605796c8dcSSimon Schubert     if (ptid_equal (list->regcache->ptid, ptid)
4615796c8dcSSimon Schubert 	&& get_regcache_arch (list->regcache) == gdbarch)
4625796c8dcSSimon Schubert       return list->regcache;
4635796c8dcSSimon Schubert 
464a45ae5f8SJohn Marino   new_regcache = regcache_xmalloc_1 (gdbarch, aspace, 0);
465a45ae5f8SJohn Marino   new_regcache->ptid = ptid;
466a45ae5f8SJohn Marino 
467a45ae5f8SJohn Marino   list = xmalloc (sizeof (struct regcache_list));
468a45ae5f8SJohn Marino   list->regcache = new_regcache;
469a45ae5f8SJohn Marino   list->next = current_regcache;
470a45ae5f8SJohn Marino   current_regcache = list;
471a45ae5f8SJohn Marino 
472a45ae5f8SJohn Marino   return new_regcache;
473a45ae5f8SJohn Marino }
474a45ae5f8SJohn Marino 
475a45ae5f8SJohn Marino struct regcache *
get_thread_arch_regcache(ptid_t ptid,struct gdbarch * gdbarch)476a45ae5f8SJohn Marino get_thread_arch_regcache (ptid_t ptid, struct gdbarch *gdbarch)
477a45ae5f8SJohn Marino {
478a45ae5f8SJohn Marino   struct address_space *aspace;
479a45ae5f8SJohn Marino 
480c50c785cSJohn Marino   /* For the benefit of "maint print registers" & co when debugging an
481c50c785cSJohn Marino      executable, allow dumping the regcache even when there is no
482c50c785cSJohn Marino      thread selected (target_thread_address_space internal-errors if
483c50c785cSJohn Marino      no address space is found).  Note that normal user commands will
484c50c785cSJohn Marino      fail higher up on the call stack due to no
485c50c785cSJohn Marino      target_has_registers.  */
486c50c785cSJohn Marino   aspace = (ptid_equal (null_ptid, ptid)
487c50c785cSJohn Marino 	    ? NULL
488c50c785cSJohn Marino 	    : target_thread_address_space (ptid));
489c50c785cSJohn Marino 
490a45ae5f8SJohn Marino   return get_thread_arch_aspace_regcache  (ptid, gdbarch, aspace);
4915796c8dcSSimon Schubert }
4925796c8dcSSimon Schubert 
4935796c8dcSSimon Schubert static ptid_t current_thread_ptid;
4945796c8dcSSimon Schubert static struct gdbarch *current_thread_arch;
4955796c8dcSSimon Schubert 
4965796c8dcSSimon Schubert struct regcache *
get_thread_regcache(ptid_t ptid)4975796c8dcSSimon Schubert get_thread_regcache (ptid_t ptid)
4985796c8dcSSimon Schubert {
4995796c8dcSSimon Schubert   if (!current_thread_arch || !ptid_equal (current_thread_ptid, ptid))
5005796c8dcSSimon Schubert     {
5015796c8dcSSimon Schubert       current_thread_ptid = ptid;
5025796c8dcSSimon Schubert       current_thread_arch = target_thread_architecture (ptid);
5035796c8dcSSimon Schubert     }
5045796c8dcSSimon Schubert 
5055796c8dcSSimon Schubert   return get_thread_arch_regcache (ptid, current_thread_arch);
5065796c8dcSSimon Schubert }
5075796c8dcSSimon Schubert 
5085796c8dcSSimon Schubert struct regcache *
get_current_regcache(void)5095796c8dcSSimon Schubert get_current_regcache (void)
5105796c8dcSSimon Schubert {
5115796c8dcSSimon Schubert   return get_thread_regcache (inferior_ptid);
5125796c8dcSSimon Schubert }
5135796c8dcSSimon Schubert 
5145796c8dcSSimon Schubert 
5155796c8dcSSimon Schubert /* Observer for the target_changed event.  */
5165796c8dcSSimon Schubert 
5175796c8dcSSimon Schubert static void
regcache_observer_target_changed(struct target_ops * target)5185796c8dcSSimon Schubert regcache_observer_target_changed (struct target_ops *target)
5195796c8dcSSimon Schubert {
5205796c8dcSSimon Schubert   registers_changed ();
5215796c8dcSSimon Schubert }
5225796c8dcSSimon Schubert 
5235796c8dcSSimon Schubert /* Update global variables old ptids to hold NEW_PTID if they were
5245796c8dcSSimon Schubert    holding OLD_PTID.  */
5255796c8dcSSimon Schubert static void
regcache_thread_ptid_changed(ptid_t old_ptid,ptid_t new_ptid)5265796c8dcSSimon Schubert regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid)
5275796c8dcSSimon Schubert {
5285796c8dcSSimon Schubert   struct regcache_list *list;
5295796c8dcSSimon Schubert 
5305796c8dcSSimon Schubert   for (list = current_regcache; list; list = list->next)
5315796c8dcSSimon Schubert     if (ptid_equal (list->regcache->ptid, old_ptid))
5325796c8dcSSimon Schubert       list->regcache->ptid = new_ptid;
5335796c8dcSSimon Schubert }
5345796c8dcSSimon Schubert 
5355796c8dcSSimon Schubert /* Low level examining and depositing of registers.
5365796c8dcSSimon Schubert 
5375796c8dcSSimon Schubert    The caller is responsible for making sure that the inferior is
5385796c8dcSSimon Schubert    stopped before calling the fetching routines, or it will get
5395796c8dcSSimon Schubert    garbage.  (a change from GDB version 3, in which the caller got the
5405796c8dcSSimon Schubert    value from the last stop).  */
5415796c8dcSSimon Schubert 
5425796c8dcSSimon Schubert /* REGISTERS_CHANGED ()
5435796c8dcSSimon Schubert 
5445796c8dcSSimon Schubert    Indicate that registers may have changed, so invalidate the cache.  */
5455796c8dcSSimon Schubert 
5465796c8dcSSimon Schubert void
registers_changed_ptid(ptid_t ptid)547cf7f2e2dSJohn Marino registers_changed_ptid (ptid_t ptid)
5485796c8dcSSimon Schubert {
549cf7f2e2dSJohn Marino   struct regcache_list *list, **list_link;
5505796c8dcSSimon Schubert 
551cf7f2e2dSJohn Marino   list = current_regcache;
552cf7f2e2dSJohn Marino   list_link = &current_regcache;
553cf7f2e2dSJohn Marino   while (list)
5545796c8dcSSimon Schubert     {
555cf7f2e2dSJohn Marino       if (ptid_match (list->regcache->ptid, ptid))
556cf7f2e2dSJohn Marino 	{
557cf7f2e2dSJohn Marino 	  struct regcache_list *dead = list;
558cf7f2e2dSJohn Marino 
559cf7f2e2dSJohn Marino 	  *list_link = list->next;
5605796c8dcSSimon Schubert 	  regcache_xfree (list->regcache);
561cf7f2e2dSJohn Marino 	  list = *list_link;
562cf7f2e2dSJohn Marino 	  xfree (dead);
563cf7f2e2dSJohn Marino 	  continue;
564cf7f2e2dSJohn Marino 	}
565cf7f2e2dSJohn Marino 
566cf7f2e2dSJohn Marino       list_link = &list->next;
567cf7f2e2dSJohn Marino       list = *list_link;
5685796c8dcSSimon Schubert     }
5695796c8dcSSimon Schubert 
570a45ae5f8SJohn Marino   if (ptid_match (current_thread_ptid, ptid))
571c50c785cSJohn Marino     {
5725796c8dcSSimon Schubert       current_thread_ptid = null_ptid;
5735796c8dcSSimon Schubert       current_thread_arch = NULL;
574c50c785cSJohn Marino     }
5755796c8dcSSimon Schubert 
576a45ae5f8SJohn Marino   if (ptid_match (inferior_ptid, ptid))
577c50c785cSJohn Marino     {
578c50c785cSJohn Marino       /* We just deleted the regcache of the current thread.  Need to
579c50c785cSJohn Marino 	 forget about any frames we have cached, too.  */
5805796c8dcSSimon Schubert       reinit_frame_cache ();
581c50c785cSJohn Marino     }
582c50c785cSJohn Marino }
583c50c785cSJohn Marino 
584c50c785cSJohn Marino void
registers_changed(void)585c50c785cSJohn Marino registers_changed (void)
586c50c785cSJohn Marino {
587c50c785cSJohn Marino   registers_changed_ptid (minus_one_ptid);
5885796c8dcSSimon Schubert 
5895796c8dcSSimon Schubert   /* Force cleanup of any alloca areas if using C alloca instead of
5905796c8dcSSimon Schubert      a builtin alloca.  This particular call is used to clean up
5915796c8dcSSimon Schubert      areas allocated by low level target code which may build up
5925796c8dcSSimon Schubert      during lengthy interactions between gdb and the target before
5935796c8dcSSimon Schubert      gdb gives control to the user (ie watchpoints).  */
5945796c8dcSSimon Schubert   alloca (0);
5955796c8dcSSimon Schubert }
5965796c8dcSSimon Schubert 
597c50c785cSJohn Marino enum register_status
regcache_raw_read(struct regcache * regcache,int regnum,gdb_byte * buf)5985796c8dcSSimon Schubert regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
5995796c8dcSSimon Schubert {
6005796c8dcSSimon Schubert   gdb_assert (regcache != NULL && buf != NULL);
6015796c8dcSSimon Schubert   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
6025796c8dcSSimon Schubert   /* Make certain that the register cache is up-to-date with respect
6035796c8dcSSimon Schubert      to the current thread.  This switching shouldn't be necessary
6045796c8dcSSimon Schubert      only there is still only one target side register cache.  Sigh!
6055796c8dcSSimon Schubert      On the bright side, at least there is a regcache object.  */
606c50c785cSJohn Marino   if (!regcache->readonly_p
607c50c785cSJohn Marino       && regcache_register_status (regcache, regnum) == REG_UNKNOWN)
6085796c8dcSSimon Schubert     {
6095796c8dcSSimon Schubert       struct cleanup *old_chain = save_inferior_ptid ();
610cf7f2e2dSJohn Marino 
6115796c8dcSSimon Schubert       inferior_ptid = regcache->ptid;
6125796c8dcSSimon Schubert       target_fetch_registers (regcache, regnum);
6135796c8dcSSimon Schubert       do_cleanups (old_chain);
614c50c785cSJohn Marino 
615c50c785cSJohn Marino       /* A number of targets can't access the whole set of raw
616c50c785cSJohn Marino 	 registers (because the debug API provides no means to get at
617c50c785cSJohn Marino 	 them).  */
618c50c785cSJohn Marino       if (regcache->register_status[regnum] == REG_UNKNOWN)
619c50c785cSJohn Marino 	regcache->register_status[regnum] = REG_UNAVAILABLE;
6205796c8dcSSimon Schubert     }
6215796c8dcSSimon Schubert 
622c50c785cSJohn Marino   if (regcache->register_status[regnum] != REG_VALID)
623c50c785cSJohn Marino     memset (buf, 0, regcache->descr->sizeof_register[regnum]);
624c50c785cSJohn Marino   else
625c50c785cSJohn Marino     memcpy (buf, register_buffer (regcache, regnum),
626c50c785cSJohn Marino 	    regcache->descr->sizeof_register[regnum]);
627c50c785cSJohn Marino 
628c50c785cSJohn Marino   return regcache->register_status[regnum];
629c50c785cSJohn Marino }
630c50c785cSJohn Marino 
631c50c785cSJohn Marino enum register_status
regcache_raw_read_signed(struct regcache * regcache,int regnum,LONGEST * val)6325796c8dcSSimon Schubert regcache_raw_read_signed (struct regcache *regcache, int regnum, LONGEST *val)
6335796c8dcSSimon Schubert {
6345796c8dcSSimon Schubert   gdb_byte *buf;
635c50c785cSJohn Marino   enum register_status status;
636cf7f2e2dSJohn Marino 
6375796c8dcSSimon Schubert   gdb_assert (regcache != NULL);
6385796c8dcSSimon Schubert   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
6395796c8dcSSimon Schubert   buf = alloca (regcache->descr->sizeof_register[regnum]);
640c50c785cSJohn Marino   status = regcache_raw_read (regcache, regnum, buf);
641c50c785cSJohn Marino   if (status == REG_VALID)
642c50c785cSJohn Marino     *val = extract_signed_integer
6435796c8dcSSimon Schubert       (buf, regcache->descr->sizeof_register[regnum],
6445796c8dcSSimon Schubert        gdbarch_byte_order (regcache->descr->gdbarch));
645c50c785cSJohn Marino   else
646c50c785cSJohn Marino     *val = 0;
647c50c785cSJohn Marino   return status;
6485796c8dcSSimon Schubert }
6495796c8dcSSimon Schubert 
650c50c785cSJohn Marino enum register_status
regcache_raw_read_unsigned(struct regcache * regcache,int regnum,ULONGEST * val)6515796c8dcSSimon Schubert regcache_raw_read_unsigned (struct regcache *regcache, int regnum,
6525796c8dcSSimon Schubert 			    ULONGEST *val)
6535796c8dcSSimon Schubert {
6545796c8dcSSimon Schubert   gdb_byte *buf;
655c50c785cSJohn Marino   enum register_status status;
656cf7f2e2dSJohn Marino 
6575796c8dcSSimon Schubert   gdb_assert (regcache != NULL);
6585796c8dcSSimon Schubert   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
6595796c8dcSSimon Schubert   buf = alloca (regcache->descr->sizeof_register[regnum]);
660c50c785cSJohn Marino   status = regcache_raw_read (regcache, regnum, buf);
661c50c785cSJohn Marino   if (status == REG_VALID)
662c50c785cSJohn Marino     *val = extract_unsigned_integer
6635796c8dcSSimon Schubert       (buf, regcache->descr->sizeof_register[regnum],
6645796c8dcSSimon Schubert        gdbarch_byte_order (regcache->descr->gdbarch));
665c50c785cSJohn Marino   else
666c50c785cSJohn Marino     *val = 0;
667c50c785cSJohn Marino   return status;
6685796c8dcSSimon Schubert }
6695796c8dcSSimon Schubert 
6705796c8dcSSimon Schubert void
regcache_raw_write_signed(struct regcache * regcache,int regnum,LONGEST val)6715796c8dcSSimon Schubert regcache_raw_write_signed (struct regcache *regcache, int regnum, LONGEST val)
6725796c8dcSSimon Schubert {
6735796c8dcSSimon Schubert   void *buf;
674cf7f2e2dSJohn Marino 
6755796c8dcSSimon Schubert   gdb_assert (regcache != NULL);
6765796c8dcSSimon Schubert   gdb_assert (regnum >=0 && regnum < regcache->descr->nr_raw_registers);
6775796c8dcSSimon Schubert   buf = alloca (regcache->descr->sizeof_register[regnum]);
6785796c8dcSSimon Schubert   store_signed_integer (buf, regcache->descr->sizeof_register[regnum],
6795796c8dcSSimon Schubert 			gdbarch_byte_order (regcache->descr->gdbarch), val);
6805796c8dcSSimon Schubert   regcache_raw_write (regcache, regnum, buf);
6815796c8dcSSimon Schubert }
6825796c8dcSSimon Schubert 
6835796c8dcSSimon Schubert void
regcache_raw_write_unsigned(struct regcache * regcache,int regnum,ULONGEST val)6845796c8dcSSimon Schubert regcache_raw_write_unsigned (struct regcache *regcache, int regnum,
6855796c8dcSSimon Schubert 			     ULONGEST val)
6865796c8dcSSimon Schubert {
6875796c8dcSSimon Schubert   void *buf;
688cf7f2e2dSJohn Marino 
6895796c8dcSSimon Schubert   gdb_assert (regcache != NULL);
6905796c8dcSSimon Schubert   gdb_assert (regnum >=0 && regnum < regcache->descr->nr_raw_registers);
6915796c8dcSSimon Schubert   buf = alloca (regcache->descr->sizeof_register[regnum]);
6925796c8dcSSimon Schubert   store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum],
6935796c8dcSSimon Schubert 			  gdbarch_byte_order (regcache->descr->gdbarch), val);
6945796c8dcSSimon Schubert   regcache_raw_write (regcache, regnum, buf);
6955796c8dcSSimon Schubert }
6965796c8dcSSimon Schubert 
697c50c785cSJohn Marino enum register_status
regcache_cooked_read(struct regcache * regcache,int regnum,gdb_byte * buf)6985796c8dcSSimon Schubert regcache_cooked_read (struct regcache *regcache, int regnum, gdb_byte *buf)
6995796c8dcSSimon Schubert {
7005796c8dcSSimon Schubert   gdb_assert (regnum >= 0);
7015796c8dcSSimon Schubert   gdb_assert (regnum < regcache->descr->nr_cooked_registers);
7025796c8dcSSimon Schubert   if (regnum < regcache->descr->nr_raw_registers)
703c50c785cSJohn Marino     return regcache_raw_read (regcache, regnum, buf);
7045796c8dcSSimon Schubert   else if (regcache->readonly_p
705c50c785cSJohn Marino 	   && regcache->register_status[regnum] != REG_UNKNOWN)
706c50c785cSJohn Marino     {
707c50c785cSJohn Marino       /* Read-only register cache, perhaps the cooked value was
708c50c785cSJohn Marino 	 cached?  */
709c50c785cSJohn Marino       if (regcache->register_status[regnum] == REG_VALID)
7105796c8dcSSimon Schubert 	memcpy (buf, register_buffer (regcache, regnum),
7115796c8dcSSimon Schubert 		regcache->descr->sizeof_register[regnum]);
7125796c8dcSSimon Schubert       else
713c50c785cSJohn Marino 	memset (buf, 0, regcache->descr->sizeof_register[regnum]);
714c50c785cSJohn Marino 
715c50c785cSJohn Marino       return regcache->register_status[regnum];
716c50c785cSJohn Marino     }
717a45ae5f8SJohn Marino   else if (gdbarch_pseudo_register_read_value_p (regcache->descr->gdbarch))
718a45ae5f8SJohn Marino     {
719a45ae5f8SJohn Marino       struct value *mark, *computed;
720a45ae5f8SJohn Marino       enum register_status result = REG_VALID;
721a45ae5f8SJohn Marino 
722a45ae5f8SJohn Marino       mark = value_mark ();
723a45ae5f8SJohn Marino 
724a45ae5f8SJohn Marino       computed = gdbarch_pseudo_register_read_value (regcache->descr->gdbarch,
725a45ae5f8SJohn Marino 						     regcache, regnum);
726a45ae5f8SJohn Marino       if (value_entirely_available (computed))
727a45ae5f8SJohn Marino 	memcpy (buf, value_contents_raw (computed),
728a45ae5f8SJohn Marino 		regcache->descr->sizeof_register[regnum]);
729a45ae5f8SJohn Marino       else
730a45ae5f8SJohn Marino 	{
731a45ae5f8SJohn Marino 	  memset (buf, 0, regcache->descr->sizeof_register[regnum]);
732a45ae5f8SJohn Marino 	  result = REG_UNAVAILABLE;
733a45ae5f8SJohn Marino 	}
734a45ae5f8SJohn Marino 
735a45ae5f8SJohn Marino       value_free_to_mark (mark);
736a45ae5f8SJohn Marino 
737a45ae5f8SJohn Marino       return result;
738a45ae5f8SJohn Marino     }
739c50c785cSJohn Marino   else
740c50c785cSJohn Marino     return gdbarch_pseudo_register_read (regcache->descr->gdbarch, regcache,
7415796c8dcSSimon Schubert 					 regnum, buf);
7425796c8dcSSimon Schubert }
7435796c8dcSSimon Schubert 
744a45ae5f8SJohn Marino struct value *
regcache_cooked_read_value(struct regcache * regcache,int regnum)745a45ae5f8SJohn Marino regcache_cooked_read_value (struct regcache *regcache, int regnum)
746a45ae5f8SJohn Marino {
747a45ae5f8SJohn Marino   gdb_assert (regnum >= 0);
748a45ae5f8SJohn Marino   gdb_assert (regnum < regcache->descr->nr_cooked_registers);
749a45ae5f8SJohn Marino 
750a45ae5f8SJohn Marino   if (regnum < regcache->descr->nr_raw_registers
751a45ae5f8SJohn Marino       || (regcache->readonly_p
752a45ae5f8SJohn Marino 	  && regcache->register_status[regnum] != REG_UNKNOWN)
753a45ae5f8SJohn Marino       || !gdbarch_pseudo_register_read_value_p (regcache->descr->gdbarch))
754a45ae5f8SJohn Marino     {
755a45ae5f8SJohn Marino       struct value *result;
756a45ae5f8SJohn Marino 
757a45ae5f8SJohn Marino       result = allocate_value (register_type (regcache->descr->gdbarch,
758a45ae5f8SJohn Marino 					      regnum));
759a45ae5f8SJohn Marino       VALUE_LVAL (result) = lval_register;
760a45ae5f8SJohn Marino       VALUE_REGNUM (result) = regnum;
761a45ae5f8SJohn Marino 
762a45ae5f8SJohn Marino       /* It is more efficient in general to do this delegation in this
763a45ae5f8SJohn Marino 	 direction than in the other one, even though the value-based
764a45ae5f8SJohn Marino 	 API is preferred.  */
765a45ae5f8SJohn Marino       if (regcache_cooked_read (regcache, regnum,
766a45ae5f8SJohn Marino 				value_contents_raw (result)) == REG_UNAVAILABLE)
767a45ae5f8SJohn Marino 	mark_value_bytes_unavailable (result, 0,
768a45ae5f8SJohn Marino 				      TYPE_LENGTH (value_type (result)));
769a45ae5f8SJohn Marino 
770a45ae5f8SJohn Marino       return result;
771a45ae5f8SJohn Marino     }
772a45ae5f8SJohn Marino   else
773a45ae5f8SJohn Marino     return gdbarch_pseudo_register_read_value (regcache->descr->gdbarch,
774a45ae5f8SJohn Marino 					       regcache, regnum);
775a45ae5f8SJohn Marino }
776a45ae5f8SJohn Marino 
777c50c785cSJohn Marino enum register_status
regcache_cooked_read_signed(struct regcache * regcache,int regnum,LONGEST * val)7785796c8dcSSimon Schubert regcache_cooked_read_signed (struct regcache *regcache, int regnum,
7795796c8dcSSimon Schubert 			     LONGEST *val)
7805796c8dcSSimon Schubert {
781c50c785cSJohn Marino   enum register_status status;
7825796c8dcSSimon Schubert   gdb_byte *buf;
783cf7f2e2dSJohn Marino 
7845796c8dcSSimon Schubert   gdb_assert (regcache != NULL);
7855796c8dcSSimon Schubert   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_cooked_registers);
7865796c8dcSSimon Schubert   buf = alloca (regcache->descr->sizeof_register[regnum]);
787c50c785cSJohn Marino   status = regcache_cooked_read (regcache, regnum, buf);
788c50c785cSJohn Marino   if (status == REG_VALID)
789c50c785cSJohn Marino     *val = extract_signed_integer
7905796c8dcSSimon Schubert       (buf, regcache->descr->sizeof_register[regnum],
7915796c8dcSSimon Schubert        gdbarch_byte_order (regcache->descr->gdbarch));
792c50c785cSJohn Marino   else
793c50c785cSJohn Marino     *val = 0;
794c50c785cSJohn Marino   return status;
7955796c8dcSSimon Schubert }
7965796c8dcSSimon Schubert 
797c50c785cSJohn Marino enum register_status
regcache_cooked_read_unsigned(struct regcache * regcache,int regnum,ULONGEST * val)7985796c8dcSSimon Schubert regcache_cooked_read_unsigned (struct regcache *regcache, int regnum,
7995796c8dcSSimon Schubert 			       ULONGEST *val)
8005796c8dcSSimon Schubert {
801c50c785cSJohn Marino   enum register_status status;
8025796c8dcSSimon Schubert   gdb_byte *buf;
803cf7f2e2dSJohn Marino 
8045796c8dcSSimon Schubert   gdb_assert (regcache != NULL);
8055796c8dcSSimon Schubert   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_cooked_registers);
8065796c8dcSSimon Schubert   buf = alloca (regcache->descr->sizeof_register[regnum]);
807c50c785cSJohn Marino   status = regcache_cooked_read (regcache, regnum, buf);
808c50c785cSJohn Marino   if (status == REG_VALID)
809c50c785cSJohn Marino     *val = extract_unsigned_integer
8105796c8dcSSimon Schubert       (buf, regcache->descr->sizeof_register[regnum],
8115796c8dcSSimon Schubert        gdbarch_byte_order (regcache->descr->gdbarch));
812c50c785cSJohn Marino   else
813c50c785cSJohn Marino     *val = 0;
814c50c785cSJohn Marino   return status;
8155796c8dcSSimon Schubert }
8165796c8dcSSimon Schubert 
8175796c8dcSSimon Schubert void
regcache_cooked_write_signed(struct regcache * regcache,int regnum,LONGEST val)8185796c8dcSSimon Schubert regcache_cooked_write_signed (struct regcache *regcache, int regnum,
8195796c8dcSSimon Schubert 			      LONGEST val)
8205796c8dcSSimon Schubert {
8215796c8dcSSimon Schubert   void *buf;
822cf7f2e2dSJohn Marino 
8235796c8dcSSimon Schubert   gdb_assert (regcache != NULL);
8245796c8dcSSimon Schubert   gdb_assert (regnum >=0 && regnum < regcache->descr->nr_cooked_registers);
8255796c8dcSSimon Schubert   buf = alloca (regcache->descr->sizeof_register[regnum]);
8265796c8dcSSimon Schubert   store_signed_integer (buf, regcache->descr->sizeof_register[regnum],
8275796c8dcSSimon Schubert 			gdbarch_byte_order (regcache->descr->gdbarch), val);
8285796c8dcSSimon Schubert   regcache_cooked_write (regcache, regnum, buf);
8295796c8dcSSimon Schubert }
8305796c8dcSSimon Schubert 
8315796c8dcSSimon Schubert void
regcache_cooked_write_unsigned(struct regcache * regcache,int regnum,ULONGEST val)8325796c8dcSSimon Schubert regcache_cooked_write_unsigned (struct regcache *regcache, int regnum,
8335796c8dcSSimon Schubert 				ULONGEST val)
8345796c8dcSSimon Schubert {
8355796c8dcSSimon Schubert   void *buf;
836cf7f2e2dSJohn Marino 
8375796c8dcSSimon Schubert   gdb_assert (regcache != NULL);
8385796c8dcSSimon Schubert   gdb_assert (regnum >=0 && regnum < regcache->descr->nr_cooked_registers);
8395796c8dcSSimon Schubert   buf = alloca (regcache->descr->sizeof_register[regnum]);
8405796c8dcSSimon Schubert   store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum],
8415796c8dcSSimon Schubert 			  gdbarch_byte_order (regcache->descr->gdbarch), val);
8425796c8dcSSimon Schubert   regcache_cooked_write (regcache, regnum, buf);
8435796c8dcSSimon Schubert }
8445796c8dcSSimon Schubert 
8455796c8dcSSimon Schubert void
regcache_raw_write(struct regcache * regcache,int regnum,const gdb_byte * buf)8465796c8dcSSimon Schubert regcache_raw_write (struct regcache *regcache, int regnum,
8475796c8dcSSimon Schubert 		    const gdb_byte *buf)
8485796c8dcSSimon Schubert {
8495796c8dcSSimon Schubert   struct cleanup *old_chain;
8505796c8dcSSimon Schubert 
8515796c8dcSSimon Schubert   gdb_assert (regcache != NULL && buf != NULL);
8525796c8dcSSimon Schubert   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
8535796c8dcSSimon Schubert   gdb_assert (!regcache->readonly_p);
8545796c8dcSSimon Schubert 
8555796c8dcSSimon Schubert   /* On the sparc, writing %g0 is a no-op, so we don't even want to
8565796c8dcSSimon Schubert      change the registers array if something writes to this register.  */
8575796c8dcSSimon Schubert   if (gdbarch_cannot_store_register (get_regcache_arch (regcache), regnum))
8585796c8dcSSimon Schubert     return;
8595796c8dcSSimon Schubert 
8605796c8dcSSimon Schubert   /* If we have a valid copy of the register, and new value == old
8615796c8dcSSimon Schubert      value, then don't bother doing the actual store.  */
862c50c785cSJohn Marino   if (regcache_register_status (regcache, regnum) == REG_VALID
8635796c8dcSSimon Schubert       && (memcmp (register_buffer (regcache, regnum), buf,
8645796c8dcSSimon Schubert 		  regcache->descr->sizeof_register[regnum]) == 0))
8655796c8dcSSimon Schubert     return;
8665796c8dcSSimon Schubert 
8675796c8dcSSimon Schubert   old_chain = save_inferior_ptid ();
8685796c8dcSSimon Schubert   inferior_ptid = regcache->ptid;
8695796c8dcSSimon Schubert 
8705796c8dcSSimon Schubert   target_prepare_to_store (regcache);
8715796c8dcSSimon Schubert   memcpy (register_buffer (regcache, regnum), buf,
8725796c8dcSSimon Schubert 	  regcache->descr->sizeof_register[regnum]);
873c50c785cSJohn Marino   regcache->register_status[regnum] = REG_VALID;
8745796c8dcSSimon Schubert   target_store_registers (regcache, regnum);
8755796c8dcSSimon Schubert 
8765796c8dcSSimon Schubert   do_cleanups (old_chain);
8775796c8dcSSimon Schubert }
8785796c8dcSSimon Schubert 
8795796c8dcSSimon Schubert void
regcache_cooked_write(struct regcache * regcache,int regnum,const gdb_byte * buf)8805796c8dcSSimon Schubert regcache_cooked_write (struct regcache *regcache, int regnum,
8815796c8dcSSimon Schubert 		       const gdb_byte *buf)
8825796c8dcSSimon Schubert {
8835796c8dcSSimon Schubert   gdb_assert (regnum >= 0);
8845796c8dcSSimon Schubert   gdb_assert (regnum < regcache->descr->nr_cooked_registers);
8855796c8dcSSimon Schubert   if (regnum < regcache->descr->nr_raw_registers)
8865796c8dcSSimon Schubert     regcache_raw_write (regcache, regnum, buf);
8875796c8dcSSimon Schubert   else
8885796c8dcSSimon Schubert     gdbarch_pseudo_register_write (regcache->descr->gdbarch, regcache,
8895796c8dcSSimon Schubert 				   regnum, buf);
8905796c8dcSSimon Schubert }
8915796c8dcSSimon Schubert 
8925796c8dcSSimon Schubert /* Perform a partial register transfer using a read, modify, write
8935796c8dcSSimon Schubert    operation.  */
8945796c8dcSSimon Schubert 
8955796c8dcSSimon Schubert typedef void (regcache_read_ftype) (struct regcache *regcache, int regnum,
8965796c8dcSSimon Schubert 				    void *buf);
8975796c8dcSSimon Schubert typedef void (regcache_write_ftype) (struct regcache *regcache, int regnum,
8985796c8dcSSimon Schubert 				     const void *buf);
8995796c8dcSSimon Schubert 
900c50c785cSJohn Marino static enum register_status
regcache_xfer_part(struct regcache * regcache,int regnum,int offset,int len,void * in,const void * out,enum register_status (* read)(struct regcache * regcache,int regnum,gdb_byte * buf),void (* write)(struct regcache * regcache,int regnum,const gdb_byte * buf))9015796c8dcSSimon Schubert regcache_xfer_part (struct regcache *regcache, int regnum,
9025796c8dcSSimon Schubert 		    int offset, int len, void *in, const void *out,
903c50c785cSJohn Marino 		    enum register_status (*read) (struct regcache *regcache,
904c50c785cSJohn Marino 						  int regnum,
9055796c8dcSSimon Schubert 						  gdb_byte *buf),
9065796c8dcSSimon Schubert 		    void (*write) (struct regcache *regcache, int regnum,
9075796c8dcSSimon Schubert 				   const gdb_byte *buf))
9085796c8dcSSimon Schubert {
9095796c8dcSSimon Schubert   struct regcache_descr *descr = regcache->descr;
9105796c8dcSSimon Schubert   gdb_byte reg[MAX_REGISTER_SIZE];
911cf7f2e2dSJohn Marino 
9125796c8dcSSimon Schubert   gdb_assert (offset >= 0 && offset <= descr->sizeof_register[regnum]);
9135796c8dcSSimon Schubert   gdb_assert (len >= 0 && offset + len <= descr->sizeof_register[regnum]);
9145796c8dcSSimon Schubert   /* Something to do?  */
9155796c8dcSSimon Schubert   if (offset + len == 0)
916c50c785cSJohn Marino     return REG_VALID;
9175796c8dcSSimon Schubert   /* Read (when needed) ...  */
9185796c8dcSSimon Schubert   if (in != NULL
9195796c8dcSSimon Schubert       || offset > 0
9205796c8dcSSimon Schubert       || offset + len < descr->sizeof_register[regnum])
9215796c8dcSSimon Schubert     {
922c50c785cSJohn Marino       enum register_status status;
923c50c785cSJohn Marino 
9245796c8dcSSimon Schubert       gdb_assert (read != NULL);
925c50c785cSJohn Marino       status = read (regcache, regnum, reg);
926c50c785cSJohn Marino       if (status != REG_VALID)
927c50c785cSJohn Marino 	return status;
9285796c8dcSSimon Schubert     }
9295796c8dcSSimon Schubert   /* ... modify ...  */
9305796c8dcSSimon Schubert   if (in != NULL)
9315796c8dcSSimon Schubert     memcpy (in, reg + offset, len);
9325796c8dcSSimon Schubert   if (out != NULL)
9335796c8dcSSimon Schubert     memcpy (reg + offset, out, len);
9345796c8dcSSimon Schubert   /* ... write (when needed).  */
9355796c8dcSSimon Schubert   if (out != NULL)
9365796c8dcSSimon Schubert     {
9375796c8dcSSimon Schubert       gdb_assert (write != NULL);
9385796c8dcSSimon Schubert       write (regcache, regnum, reg);
9395796c8dcSSimon Schubert     }
940c50c785cSJohn Marino 
941c50c785cSJohn Marino   return REG_VALID;
9425796c8dcSSimon Schubert }
9435796c8dcSSimon Schubert 
944c50c785cSJohn Marino enum register_status
regcache_raw_read_part(struct regcache * regcache,int regnum,int offset,int len,gdb_byte * buf)9455796c8dcSSimon Schubert regcache_raw_read_part (struct regcache *regcache, int regnum,
9465796c8dcSSimon Schubert 			int offset, int len, gdb_byte *buf)
9475796c8dcSSimon Schubert {
9485796c8dcSSimon Schubert   struct regcache_descr *descr = regcache->descr;
949cf7f2e2dSJohn Marino 
9505796c8dcSSimon Schubert   gdb_assert (regnum >= 0 && regnum < descr->nr_raw_registers);
951c50c785cSJohn Marino   return regcache_xfer_part (regcache, regnum, offset, len, buf, NULL,
9525796c8dcSSimon Schubert 			     regcache_raw_read, regcache_raw_write);
9535796c8dcSSimon Schubert }
9545796c8dcSSimon Schubert 
9555796c8dcSSimon Schubert void
regcache_raw_write_part(struct regcache * regcache,int regnum,int offset,int len,const gdb_byte * buf)9565796c8dcSSimon Schubert regcache_raw_write_part (struct regcache *regcache, int regnum,
9575796c8dcSSimon Schubert 			 int offset, int len, const gdb_byte *buf)
9585796c8dcSSimon Schubert {
9595796c8dcSSimon Schubert   struct regcache_descr *descr = regcache->descr;
960cf7f2e2dSJohn Marino 
9615796c8dcSSimon Schubert   gdb_assert (regnum >= 0 && regnum < descr->nr_raw_registers);
9625796c8dcSSimon Schubert   regcache_xfer_part (regcache, regnum, offset, len, NULL, buf,
9635796c8dcSSimon Schubert 		      regcache_raw_read, regcache_raw_write);
9645796c8dcSSimon Schubert }
9655796c8dcSSimon Schubert 
966c50c785cSJohn Marino enum register_status
regcache_cooked_read_part(struct regcache * regcache,int regnum,int offset,int len,gdb_byte * buf)9675796c8dcSSimon Schubert regcache_cooked_read_part (struct regcache *regcache, int regnum,
9685796c8dcSSimon Schubert 			   int offset, int len, gdb_byte *buf)
9695796c8dcSSimon Schubert {
9705796c8dcSSimon Schubert   struct regcache_descr *descr = regcache->descr;
971cf7f2e2dSJohn Marino 
9725796c8dcSSimon Schubert   gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers);
973c50c785cSJohn Marino   return regcache_xfer_part (regcache, regnum, offset, len, buf, NULL,
9745796c8dcSSimon Schubert 			     regcache_cooked_read, regcache_cooked_write);
9755796c8dcSSimon Schubert }
9765796c8dcSSimon Schubert 
9775796c8dcSSimon Schubert void
regcache_cooked_write_part(struct regcache * regcache,int regnum,int offset,int len,const gdb_byte * buf)9785796c8dcSSimon Schubert regcache_cooked_write_part (struct regcache *regcache, int regnum,
9795796c8dcSSimon Schubert 			    int offset, int len, const gdb_byte *buf)
9805796c8dcSSimon Schubert {
9815796c8dcSSimon Schubert   struct regcache_descr *descr = regcache->descr;
982cf7f2e2dSJohn Marino 
9835796c8dcSSimon Schubert   gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers);
9845796c8dcSSimon Schubert   regcache_xfer_part (regcache, regnum, offset, len, NULL, buf,
9855796c8dcSSimon Schubert 		      regcache_cooked_read, regcache_cooked_write);
9865796c8dcSSimon Schubert }
9875796c8dcSSimon Schubert 
9885796c8dcSSimon Schubert /* Supply register REGNUM, whose contents are stored in BUF, to REGCACHE.  */
9895796c8dcSSimon Schubert 
9905796c8dcSSimon Schubert void
regcache_raw_supply(struct regcache * regcache,int regnum,const void * buf)9915796c8dcSSimon Schubert regcache_raw_supply (struct regcache *regcache, int regnum, const void *buf)
9925796c8dcSSimon Schubert {
9935796c8dcSSimon Schubert   void *regbuf;
9945796c8dcSSimon Schubert   size_t size;
9955796c8dcSSimon Schubert 
9965796c8dcSSimon Schubert   gdb_assert (regcache != NULL);
9975796c8dcSSimon Schubert   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
9985796c8dcSSimon Schubert   gdb_assert (!regcache->readonly_p);
9995796c8dcSSimon Schubert 
10005796c8dcSSimon Schubert   regbuf = register_buffer (regcache, regnum);
10015796c8dcSSimon Schubert   size = regcache->descr->sizeof_register[regnum];
10025796c8dcSSimon Schubert 
10035796c8dcSSimon Schubert   if (buf)
1004c50c785cSJohn Marino     {
10055796c8dcSSimon Schubert       memcpy (regbuf, buf, size);
1006c50c785cSJohn Marino       regcache->register_status[regnum] = REG_VALID;
1007c50c785cSJohn Marino     }
10085796c8dcSSimon Schubert   else
1009c50c785cSJohn Marino     {
1010c50c785cSJohn Marino       /* This memset not strictly necessary, but better than garbage
1011c50c785cSJohn Marino 	 in case the register value manages to escape somewhere (due
1012c50c785cSJohn Marino 	 to a bug, no less).  */
10135796c8dcSSimon Schubert       memset (regbuf, 0, size);
1014c50c785cSJohn Marino       regcache->register_status[regnum] = REG_UNAVAILABLE;
1015c50c785cSJohn Marino     }
10165796c8dcSSimon Schubert }
10175796c8dcSSimon Schubert 
10185796c8dcSSimon Schubert /* Collect register REGNUM from REGCACHE and store its contents in BUF.  */
10195796c8dcSSimon Schubert 
10205796c8dcSSimon Schubert void
regcache_raw_collect(const struct regcache * regcache,int regnum,void * buf)10215796c8dcSSimon Schubert regcache_raw_collect (const struct regcache *regcache, int regnum, void *buf)
10225796c8dcSSimon Schubert {
10235796c8dcSSimon Schubert   const void *regbuf;
10245796c8dcSSimon Schubert   size_t size;
10255796c8dcSSimon Schubert 
10265796c8dcSSimon Schubert   gdb_assert (regcache != NULL && buf != NULL);
10275796c8dcSSimon Schubert   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
10285796c8dcSSimon Schubert 
10295796c8dcSSimon Schubert   regbuf = register_buffer (regcache, regnum);
10305796c8dcSSimon Schubert   size = regcache->descr->sizeof_register[regnum];
10315796c8dcSSimon Schubert   memcpy (buf, regbuf, size);
10325796c8dcSSimon Schubert }
10335796c8dcSSimon Schubert 
10345796c8dcSSimon Schubert 
10355796c8dcSSimon Schubert /* Special handling for register PC.  */
10365796c8dcSSimon Schubert 
10375796c8dcSSimon Schubert CORE_ADDR
regcache_read_pc(struct regcache * regcache)10385796c8dcSSimon Schubert regcache_read_pc (struct regcache *regcache)
10395796c8dcSSimon Schubert {
10405796c8dcSSimon Schubert   struct gdbarch *gdbarch = get_regcache_arch (regcache);
10415796c8dcSSimon Schubert 
10425796c8dcSSimon Schubert   CORE_ADDR pc_val;
10435796c8dcSSimon Schubert 
10445796c8dcSSimon Schubert   if (gdbarch_read_pc_p (gdbarch))
10455796c8dcSSimon Schubert     pc_val = gdbarch_read_pc (gdbarch, regcache);
10465796c8dcSSimon Schubert   /* Else use per-frame method on get_current_frame.  */
10475796c8dcSSimon Schubert   else if (gdbarch_pc_regnum (gdbarch) >= 0)
10485796c8dcSSimon Schubert     {
10495796c8dcSSimon Schubert       ULONGEST raw_val;
1050cf7f2e2dSJohn Marino 
1051c50c785cSJohn Marino       if (regcache_cooked_read_unsigned (regcache,
10525796c8dcSSimon Schubert 					 gdbarch_pc_regnum (gdbarch),
1053c50c785cSJohn Marino 					 &raw_val) == REG_UNAVAILABLE)
1054c50c785cSJohn Marino 	throw_error (NOT_AVAILABLE_ERROR, _("PC register is not available"));
1055c50c785cSJohn Marino 
10565796c8dcSSimon Schubert       pc_val = gdbarch_addr_bits_remove (gdbarch, raw_val);
10575796c8dcSSimon Schubert     }
10585796c8dcSSimon Schubert   else
10595796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
10605796c8dcSSimon Schubert 		    _("regcache_read_pc: Unable to find PC"));
10615796c8dcSSimon Schubert   return pc_val;
10625796c8dcSSimon Schubert }
10635796c8dcSSimon Schubert 
10645796c8dcSSimon Schubert void
regcache_write_pc(struct regcache * regcache,CORE_ADDR pc)10655796c8dcSSimon Schubert regcache_write_pc (struct regcache *regcache, CORE_ADDR pc)
10665796c8dcSSimon Schubert {
10675796c8dcSSimon Schubert   struct gdbarch *gdbarch = get_regcache_arch (regcache);
10685796c8dcSSimon Schubert 
10695796c8dcSSimon Schubert   if (gdbarch_write_pc_p (gdbarch))
10705796c8dcSSimon Schubert     gdbarch_write_pc (gdbarch, regcache, pc);
10715796c8dcSSimon Schubert   else if (gdbarch_pc_regnum (gdbarch) >= 0)
10725796c8dcSSimon Schubert     regcache_cooked_write_unsigned (regcache,
10735796c8dcSSimon Schubert 				    gdbarch_pc_regnum (gdbarch), pc);
10745796c8dcSSimon Schubert   else
10755796c8dcSSimon Schubert     internal_error (__FILE__, __LINE__,
10765796c8dcSSimon Schubert 		    _("regcache_write_pc: Unable to update PC"));
10775796c8dcSSimon Schubert 
10785796c8dcSSimon Schubert   /* Writing the PC (for instance, from "load") invalidates the
10795796c8dcSSimon Schubert      current frame.  */
10805796c8dcSSimon Schubert   reinit_frame_cache ();
10815796c8dcSSimon Schubert }
10825796c8dcSSimon Schubert 
10835796c8dcSSimon Schubert 
10845796c8dcSSimon Schubert static void
reg_flush_command(char * command,int from_tty)10855796c8dcSSimon Schubert reg_flush_command (char *command, int from_tty)
10865796c8dcSSimon Schubert {
10875796c8dcSSimon Schubert   /* Force-flush the register cache.  */
10885796c8dcSSimon Schubert   registers_changed ();
10895796c8dcSSimon Schubert   if (from_tty)
10905796c8dcSSimon Schubert     printf_filtered (_("Register cache flushed.\n"));
10915796c8dcSSimon Schubert }
10925796c8dcSSimon Schubert 
10935796c8dcSSimon Schubert static void
dump_endian_bytes(struct ui_file * file,enum bfd_endian endian,const gdb_byte * buf,long len)10945796c8dcSSimon Schubert dump_endian_bytes (struct ui_file *file, enum bfd_endian endian,
1095*ef5ccd6cSJohn Marino 		   const gdb_byte *buf, long len)
10965796c8dcSSimon Schubert {
10975796c8dcSSimon Schubert   int i;
1098cf7f2e2dSJohn Marino 
10995796c8dcSSimon Schubert   switch (endian)
11005796c8dcSSimon Schubert     {
11015796c8dcSSimon Schubert     case BFD_ENDIAN_BIG:
11025796c8dcSSimon Schubert       for (i = 0; i < len; i++)
11035796c8dcSSimon Schubert 	fprintf_unfiltered (file, "%02x", buf[i]);
11045796c8dcSSimon Schubert       break;
11055796c8dcSSimon Schubert     case BFD_ENDIAN_LITTLE:
11065796c8dcSSimon Schubert       for (i = len - 1; i >= 0; i--)
11075796c8dcSSimon Schubert 	fprintf_unfiltered (file, "%02x", buf[i]);
11085796c8dcSSimon Schubert       break;
11095796c8dcSSimon Schubert     default:
11105796c8dcSSimon Schubert       internal_error (__FILE__, __LINE__, _("Bad switch"));
11115796c8dcSSimon Schubert     }
11125796c8dcSSimon Schubert }
11135796c8dcSSimon Schubert 
11145796c8dcSSimon Schubert enum regcache_dump_what
11155796c8dcSSimon Schubert {
1116c50c785cSJohn Marino   regcache_dump_none, regcache_dump_raw,
1117a45ae5f8SJohn Marino   regcache_dump_cooked, regcache_dump_groups,
1118a45ae5f8SJohn Marino   regcache_dump_remote
11195796c8dcSSimon Schubert };
11205796c8dcSSimon Schubert 
11215796c8dcSSimon Schubert static void
regcache_dump(struct regcache * regcache,struct ui_file * file,enum regcache_dump_what what_to_dump)11225796c8dcSSimon Schubert regcache_dump (struct regcache *regcache, struct ui_file *file,
11235796c8dcSSimon Schubert 	       enum regcache_dump_what what_to_dump)
11245796c8dcSSimon Schubert {
11255796c8dcSSimon Schubert   struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
11265796c8dcSSimon Schubert   struct gdbarch *gdbarch = regcache->descr->gdbarch;
11275796c8dcSSimon Schubert   int regnum;
11285796c8dcSSimon Schubert   int footnote_nr = 0;
11295796c8dcSSimon Schubert   int footnote_register_size = 0;
11305796c8dcSSimon Schubert   int footnote_register_offset = 0;
11315796c8dcSSimon Schubert   int footnote_register_type_name_null = 0;
11325796c8dcSSimon Schubert   long register_offset = 0;
1133*ef5ccd6cSJohn Marino   gdb_byte buf[MAX_REGISTER_SIZE];
11345796c8dcSSimon Schubert 
11355796c8dcSSimon Schubert #if 0
11365796c8dcSSimon Schubert   fprintf_unfiltered (file, "nr_raw_registers %d\n",
11375796c8dcSSimon Schubert 		      regcache->descr->nr_raw_registers);
11385796c8dcSSimon Schubert   fprintf_unfiltered (file, "nr_cooked_registers %d\n",
11395796c8dcSSimon Schubert 		      regcache->descr->nr_cooked_registers);
11405796c8dcSSimon Schubert   fprintf_unfiltered (file, "sizeof_raw_registers %ld\n",
11415796c8dcSSimon Schubert 		      regcache->descr->sizeof_raw_registers);
1142c50c785cSJohn Marino   fprintf_unfiltered (file, "sizeof_raw_register_status %ld\n",
1143c50c785cSJohn Marino 		      regcache->descr->sizeof_raw_register_status);
11445796c8dcSSimon Schubert   fprintf_unfiltered (file, "gdbarch_num_regs %d\n",
11455796c8dcSSimon Schubert 		      gdbarch_num_regs (gdbarch));
11465796c8dcSSimon Schubert   fprintf_unfiltered (file, "gdbarch_num_pseudo_regs %d\n",
11475796c8dcSSimon Schubert 		      gdbarch_num_pseudo_regs (gdbarch));
11485796c8dcSSimon Schubert #endif
11495796c8dcSSimon Schubert 
11505796c8dcSSimon Schubert   gdb_assert (regcache->descr->nr_cooked_registers
11515796c8dcSSimon Schubert 	      == (gdbarch_num_regs (gdbarch)
11525796c8dcSSimon Schubert 		  + gdbarch_num_pseudo_regs (gdbarch)));
11535796c8dcSSimon Schubert 
11545796c8dcSSimon Schubert   for (regnum = -1; regnum < regcache->descr->nr_cooked_registers; regnum++)
11555796c8dcSSimon Schubert     {
11565796c8dcSSimon Schubert       /* Name.  */
11575796c8dcSSimon Schubert       if (regnum < 0)
11585796c8dcSSimon Schubert 	fprintf_unfiltered (file, " %-10s", "Name");
11595796c8dcSSimon Schubert       else
11605796c8dcSSimon Schubert 	{
11615796c8dcSSimon Schubert 	  const char *p = gdbarch_register_name (gdbarch, regnum);
1162cf7f2e2dSJohn Marino 
11635796c8dcSSimon Schubert 	  if (p == NULL)
11645796c8dcSSimon Schubert 	    p = "";
11655796c8dcSSimon Schubert 	  else if (p[0] == '\0')
11665796c8dcSSimon Schubert 	    p = "''";
11675796c8dcSSimon Schubert 	  fprintf_unfiltered (file, " %-10s", p);
11685796c8dcSSimon Schubert 	}
11695796c8dcSSimon Schubert 
11705796c8dcSSimon Schubert       /* Number.  */
11715796c8dcSSimon Schubert       if (regnum < 0)
11725796c8dcSSimon Schubert 	fprintf_unfiltered (file, " %4s", "Nr");
11735796c8dcSSimon Schubert       else
11745796c8dcSSimon Schubert 	fprintf_unfiltered (file, " %4d", regnum);
11755796c8dcSSimon Schubert 
11765796c8dcSSimon Schubert       /* Relative number.  */
11775796c8dcSSimon Schubert       if (regnum < 0)
11785796c8dcSSimon Schubert 	fprintf_unfiltered (file, " %4s", "Rel");
11795796c8dcSSimon Schubert       else if (regnum < gdbarch_num_regs (gdbarch))
11805796c8dcSSimon Schubert 	fprintf_unfiltered (file, " %4d", regnum);
11815796c8dcSSimon Schubert       else
11825796c8dcSSimon Schubert 	fprintf_unfiltered (file, " %4d",
11835796c8dcSSimon Schubert 			    (regnum - gdbarch_num_regs (gdbarch)));
11845796c8dcSSimon Schubert 
11855796c8dcSSimon Schubert       /* Offset.  */
11865796c8dcSSimon Schubert       if (regnum < 0)
11875796c8dcSSimon Schubert 	fprintf_unfiltered (file, " %6s  ", "Offset");
11885796c8dcSSimon Schubert       else
11895796c8dcSSimon Schubert 	{
11905796c8dcSSimon Schubert 	  fprintf_unfiltered (file, " %6ld",
11915796c8dcSSimon Schubert 			      regcache->descr->register_offset[regnum]);
11925796c8dcSSimon Schubert 	  if (register_offset != regcache->descr->register_offset[regnum]
11935796c8dcSSimon Schubert 	      || (regnum > 0
11945796c8dcSSimon Schubert 		  && (regcache->descr->register_offset[regnum]
11955796c8dcSSimon Schubert 		      != (regcache->descr->register_offset[regnum - 1]
11965796c8dcSSimon Schubert 			  + regcache->descr->sizeof_register[regnum - 1])))
11975796c8dcSSimon Schubert 	      )
11985796c8dcSSimon Schubert 	    {
11995796c8dcSSimon Schubert 	      if (!footnote_register_offset)
12005796c8dcSSimon Schubert 		footnote_register_offset = ++footnote_nr;
12015796c8dcSSimon Schubert 	      fprintf_unfiltered (file, "*%d", footnote_register_offset);
12025796c8dcSSimon Schubert 	    }
12035796c8dcSSimon Schubert 	  else
12045796c8dcSSimon Schubert 	    fprintf_unfiltered (file, "  ");
12055796c8dcSSimon Schubert 	  register_offset = (regcache->descr->register_offset[regnum]
12065796c8dcSSimon Schubert 			     + regcache->descr->sizeof_register[regnum]);
12075796c8dcSSimon Schubert 	}
12085796c8dcSSimon Schubert 
12095796c8dcSSimon Schubert       /* Size.  */
12105796c8dcSSimon Schubert       if (regnum < 0)
12115796c8dcSSimon Schubert 	fprintf_unfiltered (file, " %5s ", "Size");
12125796c8dcSSimon Schubert       else
12135796c8dcSSimon Schubert 	fprintf_unfiltered (file, " %5ld",
12145796c8dcSSimon Schubert 			    regcache->descr->sizeof_register[regnum]);
12155796c8dcSSimon Schubert 
12165796c8dcSSimon Schubert       /* Type.  */
12175796c8dcSSimon Schubert       {
12185796c8dcSSimon Schubert 	const char *t;
1219cf7f2e2dSJohn Marino 
12205796c8dcSSimon Schubert 	if (regnum < 0)
12215796c8dcSSimon Schubert 	  t = "Type";
12225796c8dcSSimon Schubert 	else
12235796c8dcSSimon Schubert 	  {
12245796c8dcSSimon Schubert 	    static const char blt[] = "builtin_type";
1225cf7f2e2dSJohn Marino 
12265796c8dcSSimon Schubert 	    t = TYPE_NAME (register_type (regcache->descr->gdbarch, regnum));
12275796c8dcSSimon Schubert 	    if (t == NULL)
12285796c8dcSSimon Schubert 	      {
12295796c8dcSSimon Schubert 		char *n;
1230cf7f2e2dSJohn Marino 
12315796c8dcSSimon Schubert 		if (!footnote_register_type_name_null)
12325796c8dcSSimon Schubert 		  footnote_register_type_name_null = ++footnote_nr;
12335796c8dcSSimon Schubert 		n = xstrprintf ("*%d", footnote_register_type_name_null);
12345796c8dcSSimon Schubert 		make_cleanup (xfree, n);
12355796c8dcSSimon Schubert 		t = n;
12365796c8dcSSimon Schubert 	      }
12375796c8dcSSimon Schubert 	    /* Chop a leading builtin_type.  */
12385796c8dcSSimon Schubert 	    if (strncmp (t, blt, strlen (blt)) == 0)
12395796c8dcSSimon Schubert 	      t += strlen (blt);
12405796c8dcSSimon Schubert 	  }
12415796c8dcSSimon Schubert 	fprintf_unfiltered (file, " %-15s", t);
12425796c8dcSSimon Schubert       }
12435796c8dcSSimon Schubert 
12445796c8dcSSimon Schubert       /* Leading space always present.  */
12455796c8dcSSimon Schubert       fprintf_unfiltered (file, " ");
12465796c8dcSSimon Schubert 
12475796c8dcSSimon Schubert       /* Value, raw.  */
12485796c8dcSSimon Schubert       if (what_to_dump == regcache_dump_raw)
12495796c8dcSSimon Schubert 	{
12505796c8dcSSimon Schubert 	  if (regnum < 0)
12515796c8dcSSimon Schubert 	    fprintf_unfiltered (file, "Raw value");
12525796c8dcSSimon Schubert 	  else if (regnum >= regcache->descr->nr_raw_registers)
12535796c8dcSSimon Schubert 	    fprintf_unfiltered (file, "<cooked>");
1254c50c785cSJohn Marino 	  else if (regcache_register_status (regcache, regnum) == REG_UNKNOWN)
12555796c8dcSSimon Schubert 	    fprintf_unfiltered (file, "<invalid>");
1256c50c785cSJohn Marino 	  else if (regcache_register_status (regcache, regnum) == REG_UNAVAILABLE)
1257c50c785cSJohn Marino 	    fprintf_unfiltered (file, "<unavailable>");
12585796c8dcSSimon Schubert 	  else
12595796c8dcSSimon Schubert 	    {
12605796c8dcSSimon Schubert 	      regcache_raw_read (regcache, regnum, buf);
12615796c8dcSSimon Schubert 	      fprintf_unfiltered (file, "0x");
12625796c8dcSSimon Schubert 	      dump_endian_bytes (file,
12635796c8dcSSimon Schubert 				 gdbarch_byte_order (gdbarch), buf,
12645796c8dcSSimon Schubert 				 regcache->descr->sizeof_register[regnum]);
12655796c8dcSSimon Schubert 	    }
12665796c8dcSSimon Schubert 	}
12675796c8dcSSimon Schubert 
12685796c8dcSSimon Schubert       /* Value, cooked.  */
12695796c8dcSSimon Schubert       if (what_to_dump == regcache_dump_cooked)
12705796c8dcSSimon Schubert 	{
12715796c8dcSSimon Schubert 	  if (regnum < 0)
12725796c8dcSSimon Schubert 	    fprintf_unfiltered (file, "Cooked value");
12735796c8dcSSimon Schubert 	  else
12745796c8dcSSimon Schubert 	    {
1275c50c785cSJohn Marino 	      enum register_status status;
1276c50c785cSJohn Marino 
1277c50c785cSJohn Marino 	      status = regcache_cooked_read (regcache, regnum, buf);
1278c50c785cSJohn Marino 	      if (status == REG_UNKNOWN)
1279c50c785cSJohn Marino 		fprintf_unfiltered (file, "<invalid>");
1280c50c785cSJohn Marino 	      else if (status == REG_UNAVAILABLE)
1281c50c785cSJohn Marino 		fprintf_unfiltered (file, "<unavailable>");
1282c50c785cSJohn Marino 	      else
1283c50c785cSJohn Marino 		{
12845796c8dcSSimon Schubert 		  fprintf_unfiltered (file, "0x");
12855796c8dcSSimon Schubert 		  dump_endian_bytes (file,
12865796c8dcSSimon Schubert 				     gdbarch_byte_order (gdbarch), buf,
12875796c8dcSSimon Schubert 				     regcache->descr->sizeof_register[regnum]);
12885796c8dcSSimon Schubert 		}
12895796c8dcSSimon Schubert 	    }
1290c50c785cSJohn Marino 	}
12915796c8dcSSimon Schubert 
12925796c8dcSSimon Schubert       /* Group members.  */
12935796c8dcSSimon Schubert       if (what_to_dump == regcache_dump_groups)
12945796c8dcSSimon Schubert 	{
12955796c8dcSSimon Schubert 	  if (regnum < 0)
12965796c8dcSSimon Schubert 	    fprintf_unfiltered (file, "Groups");
12975796c8dcSSimon Schubert 	  else
12985796c8dcSSimon Schubert 	    {
12995796c8dcSSimon Schubert 	      const char *sep = "";
13005796c8dcSSimon Schubert 	      struct reggroup *group;
1301cf7f2e2dSJohn Marino 
13025796c8dcSSimon Schubert 	      for (group = reggroup_next (gdbarch, NULL);
13035796c8dcSSimon Schubert 		   group != NULL;
13045796c8dcSSimon Schubert 		   group = reggroup_next (gdbarch, group))
13055796c8dcSSimon Schubert 		{
13065796c8dcSSimon Schubert 		  if (gdbarch_register_reggroup_p (gdbarch, regnum, group))
13075796c8dcSSimon Schubert 		    {
1308c50c785cSJohn Marino 		      fprintf_unfiltered (file,
1309c50c785cSJohn Marino 					  "%s%s", sep, reggroup_name (group));
13105796c8dcSSimon Schubert 		      sep = ",";
13115796c8dcSSimon Schubert 		    }
13125796c8dcSSimon Schubert 		}
13135796c8dcSSimon Schubert 	    }
13145796c8dcSSimon Schubert 	}
13155796c8dcSSimon Schubert 
1316a45ae5f8SJohn Marino       /* Remote packet configuration.  */
1317a45ae5f8SJohn Marino       if (what_to_dump == regcache_dump_remote)
1318a45ae5f8SJohn Marino 	{
1319a45ae5f8SJohn Marino 	  if (regnum < 0)
1320a45ae5f8SJohn Marino 	    {
1321a45ae5f8SJohn Marino 	      fprintf_unfiltered (file, "Rmt Nr  g/G Offset");
1322a45ae5f8SJohn Marino 	    }
1323a45ae5f8SJohn Marino 	  else if (regnum < regcache->descr->nr_raw_registers)
1324a45ae5f8SJohn Marino 	    {
1325a45ae5f8SJohn Marino 	      int pnum, poffset;
1326a45ae5f8SJohn Marino 
1327a45ae5f8SJohn Marino 	      if (remote_register_number_and_offset (get_regcache_arch (regcache), regnum,
1328a45ae5f8SJohn Marino 						     &pnum, &poffset))
1329a45ae5f8SJohn Marino 		fprintf_unfiltered (file, "%7d %11d", pnum, poffset);
1330a45ae5f8SJohn Marino 	    }
1331a45ae5f8SJohn Marino 	}
1332a45ae5f8SJohn Marino 
13335796c8dcSSimon Schubert       fprintf_unfiltered (file, "\n");
13345796c8dcSSimon Schubert     }
13355796c8dcSSimon Schubert 
13365796c8dcSSimon Schubert   if (footnote_register_size)
13375796c8dcSSimon Schubert     fprintf_unfiltered (file, "*%d: Inconsistent register sizes.\n",
13385796c8dcSSimon Schubert 			footnote_register_size);
13395796c8dcSSimon Schubert   if (footnote_register_offset)
13405796c8dcSSimon Schubert     fprintf_unfiltered (file, "*%d: Inconsistent register offsets.\n",
13415796c8dcSSimon Schubert 			footnote_register_offset);
13425796c8dcSSimon Schubert   if (footnote_register_type_name_null)
13435796c8dcSSimon Schubert     fprintf_unfiltered (file,
13445796c8dcSSimon Schubert 			"*%d: Register type's name NULL.\n",
13455796c8dcSSimon Schubert 			footnote_register_type_name_null);
13465796c8dcSSimon Schubert   do_cleanups (cleanups);
13475796c8dcSSimon Schubert }
13485796c8dcSSimon Schubert 
13495796c8dcSSimon Schubert static void
regcache_print(char * args,enum regcache_dump_what what_to_dump)13505796c8dcSSimon Schubert regcache_print (char *args, enum regcache_dump_what what_to_dump)
13515796c8dcSSimon Schubert {
13525796c8dcSSimon Schubert   if (args == NULL)
13535796c8dcSSimon Schubert     regcache_dump (get_current_regcache (), gdb_stdout, what_to_dump);
13545796c8dcSSimon Schubert   else
13555796c8dcSSimon Schubert     {
13565796c8dcSSimon Schubert       struct cleanup *cleanups;
13575796c8dcSSimon Schubert       struct ui_file *file = gdb_fopen (args, "w");
1358cf7f2e2dSJohn Marino 
13595796c8dcSSimon Schubert       if (file == NULL)
13605796c8dcSSimon Schubert 	perror_with_name (_("maintenance print architecture"));
13615796c8dcSSimon Schubert       cleanups = make_cleanup_ui_file_delete (file);
13625796c8dcSSimon Schubert       regcache_dump (get_current_regcache (), file, what_to_dump);
13635796c8dcSSimon Schubert       do_cleanups (cleanups);
13645796c8dcSSimon Schubert     }
13655796c8dcSSimon Schubert }
13665796c8dcSSimon Schubert 
13675796c8dcSSimon Schubert static void
maintenance_print_registers(char * args,int from_tty)13685796c8dcSSimon Schubert maintenance_print_registers (char *args, int from_tty)
13695796c8dcSSimon Schubert {
13705796c8dcSSimon Schubert   regcache_print (args, regcache_dump_none);
13715796c8dcSSimon Schubert }
13725796c8dcSSimon Schubert 
13735796c8dcSSimon Schubert static void
maintenance_print_raw_registers(char * args,int from_tty)13745796c8dcSSimon Schubert maintenance_print_raw_registers (char *args, int from_tty)
13755796c8dcSSimon Schubert {
13765796c8dcSSimon Schubert   regcache_print (args, regcache_dump_raw);
13775796c8dcSSimon Schubert }
13785796c8dcSSimon Schubert 
13795796c8dcSSimon Schubert static void
maintenance_print_cooked_registers(char * args,int from_tty)13805796c8dcSSimon Schubert maintenance_print_cooked_registers (char *args, int from_tty)
13815796c8dcSSimon Schubert {
13825796c8dcSSimon Schubert   regcache_print (args, regcache_dump_cooked);
13835796c8dcSSimon Schubert }
13845796c8dcSSimon Schubert 
13855796c8dcSSimon Schubert static void
maintenance_print_register_groups(char * args,int from_tty)13865796c8dcSSimon Schubert maintenance_print_register_groups (char *args, int from_tty)
13875796c8dcSSimon Schubert {
13885796c8dcSSimon Schubert   regcache_print (args, regcache_dump_groups);
13895796c8dcSSimon Schubert }
13905796c8dcSSimon Schubert 
1391a45ae5f8SJohn Marino static void
maintenance_print_remote_registers(char * args,int from_tty)1392a45ae5f8SJohn Marino maintenance_print_remote_registers (char *args, int from_tty)
1393a45ae5f8SJohn Marino {
1394a45ae5f8SJohn Marino   regcache_print (args, regcache_dump_remote);
1395a45ae5f8SJohn Marino }
1396a45ae5f8SJohn Marino 
13975796c8dcSSimon Schubert extern initialize_file_ftype _initialize_regcache; /* -Wmissing-prototype */
13985796c8dcSSimon Schubert 
13995796c8dcSSimon Schubert void
_initialize_regcache(void)14005796c8dcSSimon Schubert _initialize_regcache (void)
14015796c8dcSSimon Schubert {
1402c50c785cSJohn Marino   regcache_descr_handle
1403c50c785cSJohn Marino     = gdbarch_data_register_post_init (init_regcache_descr);
14045796c8dcSSimon Schubert 
14055796c8dcSSimon Schubert   observer_attach_target_changed (regcache_observer_target_changed);
14065796c8dcSSimon Schubert   observer_attach_thread_ptid_changed (regcache_thread_ptid_changed);
14075796c8dcSSimon Schubert 
14085796c8dcSSimon Schubert   add_com ("flushregs", class_maintenance, reg_flush_command,
14095796c8dcSSimon Schubert 	   _("Force gdb to flush its register cache (maintainer command)"));
14105796c8dcSSimon Schubert 
1411c50c785cSJohn Marino   add_cmd ("registers", class_maintenance, maintenance_print_registers,
1412c50c785cSJohn Marino 	   _("Print the internal register configuration.\n"
1413c50c785cSJohn Marino 	     "Takes an optional file parameter."), &maintenanceprintlist);
14145796c8dcSSimon Schubert   add_cmd ("raw-registers", class_maintenance,
1415c50c785cSJohn Marino 	   maintenance_print_raw_registers,
1416c50c785cSJohn Marino 	   _("Print the internal register configuration "
1417c50c785cSJohn Marino 	     "including raw values.\n"
1418c50c785cSJohn Marino 	     "Takes an optional file parameter."), &maintenanceprintlist);
14195796c8dcSSimon Schubert   add_cmd ("cooked-registers", class_maintenance,
1420c50c785cSJohn Marino 	   maintenance_print_cooked_registers,
1421c50c785cSJohn Marino 	   _("Print the internal register configuration "
1422c50c785cSJohn Marino 	     "including cooked values.\n"
1423c50c785cSJohn Marino 	     "Takes an optional file parameter."), &maintenanceprintlist);
14245796c8dcSSimon Schubert   add_cmd ("register-groups", class_maintenance,
1425c50c785cSJohn Marino 	   maintenance_print_register_groups,
1426c50c785cSJohn Marino 	   _("Print the internal register configuration "
1427c50c785cSJohn Marino 	     "including each register's group.\n"
1428c50c785cSJohn Marino 	     "Takes an optional file parameter."),
14295796c8dcSSimon Schubert 	   &maintenanceprintlist);
1430a45ae5f8SJohn Marino   add_cmd ("remote-registers", class_maintenance,
1431a45ae5f8SJohn Marino 	   maintenance_print_remote_registers, _("\
1432a45ae5f8SJohn Marino Print the internal register configuration including each register's\n\
1433a45ae5f8SJohn Marino remote register number and buffer offset in the g/G packets.\n\
1434a45ae5f8SJohn Marino Takes an optional file parameter."),
1435a45ae5f8SJohn Marino 	   &maintenanceprintlist);
14365796c8dcSSimon Schubert 
14375796c8dcSSimon Schubert }
1438