This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Allow all NUM_REGS + NUM_PSEUDO_REGS in the regcache


Hello,

Following up a proposal in gdb@, the attatched patch adjusts regcache so 
that it is tolerant of raw registers in the range 
[0..NUM_REGS+NUM_PSEUDO_REGS).

remote.c is next.

look ok?
Andrew
2001-12-04  Andrew Cagney  <ac131313@redhat.com>

	* regcache.c (store_register, fetch_register): Only use fetch/store
	pseudo-register when function is present.  Assume target can
	handle all registers.
	(registers_changed): Simplify invalidate loop.
	(registers_fetched): Add comments.
	(register_buffer): Add regnum range assertion.  Remove code
	handling -ve regnum.
	(build_regcache): Make space for pseudo-registers when computing
	sizeof_registers.  Initialize register_offset.

	* gdbarch.sh (FETCH_PSEUDO_REGISTER): Change to a function with
	predicate.
	(STORE_PSEUDO_REGISTER): Ditto.
	* gdbarch.h, gdbarch.c: Re-generate.
	
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.93
diff -p -r1.93 gdbarch.sh
*** gdbarch.sh	2001/11/22 00:23:12	1.93
--- gdbarch.sh	2001/12/04 22:32:19
*************** f:2:REGISTER_CONVERT_TO_RAW:void:registe
*** 468,478 ****
  # This function is called when the value of a pseudo-register needs to
  # be updated.  Typically it will be defined on a per-architecture
  # basis.
! f:2:FETCH_PSEUDO_REGISTER:void:fetch_pseudo_register:int regnum:regnum:::0::0
  # This function is called when the value of a pseudo-register needs to
  # be set or stored.  Typically it will be defined on a
  # per-architecture basis.
! f:2:STORE_PSEUDO_REGISTER:void:store_pseudo_register:int regnum:regnum:::0::0
  #
  f:2:POINTER_TO_ADDRESS:CORE_ADDR:pointer_to_address:struct type *type, void *buf:type, buf:::unsigned_pointer_to_address::0
  f:2:ADDRESS_TO_POINTER:void:address_to_pointer:struct type *type, void *buf, CORE_ADDR addr:type, buf, addr:::unsigned_address_to_pointer::0
--- 468,478 ----
  # This function is called when the value of a pseudo-register needs to
  # be updated.  Typically it will be defined on a per-architecture
  # basis.
! F:2:FETCH_PSEUDO_REGISTER:void:fetch_pseudo_register:int regnum:regnum:
  # This function is called when the value of a pseudo-register needs to
  # be set or stored.  Typically it will be defined on a
  # per-architecture basis.
! F:2:STORE_PSEUDO_REGISTER:void:store_pseudo_register:int regnum:regnum:
  #
  f:2:POINTER_TO_ADDRESS:CORE_ADDR:pointer_to_address:struct type *type, void *buf:type, buf:::unsigned_pointer_to_address::0
  f:2:ADDRESS_TO_POINTER:void:address_to_pointer:struct type *type, void *buf, CORE_ADDR addr:type, buf, addr:::unsigned_address_to_pointer::0
Index: regcache.c
===================================================================
RCS file: /cvs/src/src/gdb/regcache.c,v
retrieving revision 1.27
diff -p -r1.27 regcache.c
*** regcache.c	2001/11/15 06:43:10	1.27
--- regcache.c	2001/12/04 22:32:20
*************** register_changed (int regnum)
*** 93,102 ****
  static char *
  register_buffer (int regnum)
  {
!   if (regnum < 0)
!     return registers;
!   else
!     return &registers[REGISTER_BYTE (regnum)];
  }
  
  /* Return whether register REGNUM is a real register.  */
--- 93,100 ----
  static char *
  register_buffer (int regnum)
  {
!   gdb_assert (regnum >= 0 && regnum < (NUM_REGS + NUM_PSEUDO_REGS));
!   return &registers[REGISTER_BYTE (regnum)];
  }
  
  /* Return whether register REGNUM is a real register.  */
*************** pseudo_register (int regnum)
*** 120,129 ****
  static void
  fetch_register (int regnum)
  {
!   if (real_register (regnum))
!     target_fetch_registers (regnum);
!   else if (pseudo_register (regnum))
      FETCH_PSEUDO_REGISTER (regnum);
  }
  
  /* Write register REGNUM cached value to the target.  */
--- 118,131 ----
  static void
  fetch_register (int regnum)
  {
!   /* NOTE: cagney/2001-12-04: Legacy targets were using fetch/store
!      pseudo-register as a way of handling registers that needed to be
!      constructed from one or more raw registers.  New targets instead
!      use gdbarch register read/write.  */
!   if (FETCH_PSEUDO_REGISTER_P ()
!       && pseudo_register (regnum))
      FETCH_PSEUDO_REGISTER (regnum);
+   target_fetch_registers (regnum);
  }
  
  /* Write register REGNUM cached value to the target.  */
*************** fetch_register (int regnum)
*** 131,140 ****
  static void
  store_register (int regnum)
  {
!   if (real_register (regnum))
!     target_store_registers (regnum);
!   else if (pseudo_register (regnum))
      STORE_PSEUDO_REGISTER (regnum);
  }
  
  /* Low level examining and depositing of registers.
--- 133,146 ----
  static void
  store_register (int regnum)
  {
!   /* NOTE: cagney/2001-12-04: Legacy targets were using fetch/store
!      pseudo-register as a way of handling registers that needed to be
!      constructed from one or more raw registers.  New targets instead
!      use gdbarch register read/write.  */
!   if (STORE_PSEUDO_REGISTER_P ()
!       && pseudo_register (regnum))
      STORE_PSEUDO_REGISTER (regnum);
+   target_store_registers (regnum);
  }
  
  /* Low level examining and depositing of registers.
*************** registers_changed (void)
*** 162,175 ****
       gdb gives control to the user (ie watchpoints).  */
    alloca (0);
  
!   for (i = 0; i < NUM_REGS; i++)
      set_register_cached (i, 0);
  
-   /* Assume that if all the hardware regs have changed, 
-      then so have the pseudo-registers.  */
-   for (i = NUM_REGS; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
-     set_register_cached (i, 0);
- 
    if (registers_changed_hook)
      registers_changed_hook ();
  }
--- 168,176 ----
       gdb gives control to the user (ie watchpoints).  */
    alloca (0);
  
!   for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
      set_register_cached (i, 0);
  
    if (registers_changed_hook)
      registers_changed_hook ();
  }
*************** registers_changed (void)
*** 178,183 ****
--- 179,191 ----
  
     Indicate that all registers have been fetched, so mark them all valid.  */
  
+ /* NOTE: cagney/2001-12-04: This function does not set valid on the
+    pseudo-register range since pseudo registers are always supplied
+    using supply_register().  */
+ /* FIXME: cagney/2001-12-04: This function is DEPRECATED.  The target
+    code was blatting the registers[] array and then calling this.
+    Since targets should only be using supply_register() the need for
+    this function/hack is eliminated.  */
  
  void
  registers_fetched (void)
*************** registers_fetched (void)
*** 187,193 ****
    for (i = 0; i < NUM_REGS; i++)
      set_register_cached (i, 1);
    /* Do not assume that the pseudo-regs have also been fetched.
!      Fetching all real regs might not account for all pseudo-regs.  */
  }
  
  /* read_register_bytes and write_register_bytes are generally a *BAD*
--- 195,201 ----
    for (i = 0; i < NUM_REGS; i++)
      set_register_cached (i, 1);
    /* Do not assume that the pseudo-regs have also been fetched.
!      Fetching all real regs NEVER accounts for pseudo-regs.  */
  }
  
  /* read_register_bytes and write_register_bytes are generally a *BAD*
*************** reg_flush_command (char *command, int fr
*** 758,774 ****
      printf_filtered ("Register cache flushed.\n");
  }
  
  
  static void
  build_regcache (void)
  {
!   /* We allocate some extra slop since we do a lot of memcpy's around
!      `registers', and failing-soft is better than failing hard.  */
!   int sizeof_registers = REGISTER_BYTES + /* SLOP */ 256;
!   int sizeof_register_valid = 
!     (NUM_REGS + NUM_PSEUDO_REGS) * sizeof (*register_valid);
    registers = xmalloc (sizeof_registers);
!   memset (registers, 0, sizeof_registers);
    register_valid = xmalloc (sizeof_register_valid);
    memset (register_valid, 0, sizeof_register_valid);
  }
--- 766,801 ----
      printf_filtered ("Register cache flushed.\n");
  }
  
+ #undef XCALLOC
+ #define XCALLOC(NR,TYPE) ((TYPE*) xcalloc ((NR), sizeof (TYPE)))
  
  static void
  build_regcache (void)
  {
!   int i;
!   int sizeof_register_valid;
!   /* Come up with the real size of the registers buffer.  */
!   int sizeof_registers = REGISTER_BYTES; /* OK use.  */
!   for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
!     {
!       long regend;
!       /* Keep extending the buffer so that there is always enough
!          space for all registers.  The comparison is necessary since
!          legacy code is free to put registers in random places in the
!          buffer separated by holes.  Once REGISTER_BYTE() is killed
!          this can be greatly simplified.  */
!       /* FIXME: cagney/2001-12-04: This code shouldn't need to use
!          REGISTER_BYTE().  Unfortunatly, legacy code likes to lay the
!          buffer out so that certain registers just happen to overlap.
!          Ulgh!  New targets use gdbarch's register read/write and
!          entirely avoid this uglyness.  */
!       regend = REGISTER_BYTE (i) + REGISTER_RAW_SIZE (i);
!       if (sizeof_registers < regend)
! 	sizeof_registers = regend;
!     }
    registers = xmalloc (sizeof_registers);
!   sizeof_register_valid = ((NUM_REGS + NUM_PSEUDO_REGS)
! 			   * sizeof (*register_valid));
    register_valid = xmalloc (sizeof_register_valid);
    memset (register_valid, 0, sizeof_register_valid);
  }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]