xtensa_pseudo_register_read/write - Use regcache_raw_read_unsigned
[deliverable/binutils-gdb.git] / gdb / regcache.c
index b2b9524d742a477f89195cf657085833054cbb38..966f0c718b30036269770477f66d21dd149616bc 100644 (file)
@@ -209,15 +209,25 @@ struct regcache
      cache can only be updated via the methods regcache_dup() and
      regcache_cpy().  The actual contents are determined by the
      reggroup_save and reggroup_restore methods.  */
-  int readonly_p;
+  bool readonly_p;
   /* If this is a read-write cache, which thread's registers is
      it connected to?  */
   ptid_t ptid;
 };
 
+/* See regcache.h.  */
+
+ptid_t
+regcache_get_ptid (const struct regcache *regcache)
+{
+  gdb_assert (!ptid_equal (regcache->ptid, minus_one_ptid));
+
+  return regcache->ptid;
+}
+
 static struct regcache *
 regcache_xmalloc_1 (struct gdbarch *gdbarch, struct address_space *aspace,
-                   int readonly_p)
+                   bool readonly_p)
 {
   struct regcache_descr *descr;
   struct regcache *regcache;
@@ -249,7 +259,7 @@ regcache_xmalloc_1 (struct gdbarch *gdbarch, struct address_space *aspace,
 struct regcache *
 regcache_xmalloc (struct gdbarch *gdbarch, struct address_space *aspace)
 {
-  return regcache_xmalloc_1 (gdbarch, aspace, 1);
+  return regcache_xmalloc_1 (gdbarch, aspace, true);
 }
 
 void
@@ -364,17 +374,15 @@ regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
 }
 
 static void
-regcache_restore (struct regcache *dst,
-                 regcache_cooked_read_ftype *cooked_read,
-                 void *cooked_read_context)
+regcache_restore (struct regcache *dst, struct regcache *src)
 {
   struct gdbarch *gdbarch = dst->descr->gdbarch;
-  gdb_byte buf[MAX_REGISTER_SIZE];
   int regnum;
 
   /* The dst had better not be read-only.  If it is, the `restore'
      doesn't make much sense.  */
   gdb_assert (!dst->readonly_p);
+  gdb_assert (src->readonly_p);
   /* Copy over any registers, being careful to only restore those that
      were both saved and need to be restored.  The full [0 .. gdbarch_num_regs
      + gdbarch_num_pseudo_regs) range is checked since some architectures need
@@ -383,11 +391,8 @@ regcache_restore (struct regcache *dst,
     {
       if (gdbarch_register_reggroup_p (gdbarch, regnum, restore_reggroup))
        {
-         enum register_status status;
-
-         status = cooked_read (cooked_read_context, regnum, buf);
-         if (status == REG_VALID)
-           regcache_cooked_write (dst, regnum, buf);
+         if (src->register_status[regnum] == REG_VALID)
+           regcache_cooked_write (dst, regnum, register_buffer (src, regnum));
        }
     }
 }
@@ -414,7 +419,7 @@ regcache_cpy (struct regcache *dst, struct regcache *src)
   if (!src->readonly_p)
     regcache_save (dst, do_cooked_read, src);
   else if (!dst->readonly_p)
-    regcache_restore (dst, do_cooked_read, src);
+    regcache_restore (dst, src);
   else
     regcache_cpy_no_passthrough (dst, src);
 }
@@ -502,7 +507,7 @@ get_thread_arch_aspace_regcache (ptid_t ptid, struct gdbarch *gdbarch,
        && get_regcache_arch (list->regcache) == gdbarch)
       return list->regcache;
 
-  new_regcache = regcache_xmalloc_1 (gdbarch, aspace, 0);
+  new_regcache = regcache_xmalloc_1 (gdbarch, aspace, false);
   new_regcache->ptid = ptid;
 
   list = XNEW (struct regcache_list);
@@ -642,23 +647,21 @@ registers_changed (void)
   alloca (0);
 }
 
-enum register_status
-regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
+void
+regcache_raw_update (struct regcache *regcache, int regnum)
 {
-  gdb_assert (regcache != NULL && buf != NULL);
+  gdb_assert (regcache != NULL);
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
+
   /* Make certain that the register cache is up-to-date with respect
      to the current thread.  This switching shouldn't be necessary
      only there is still only one target side register cache.  Sigh!
      On the bright side, at least there is a regcache object.  */
+
   if (!regcache->readonly_p
       && regcache_register_status (regcache, regnum) == REG_UNKNOWN)
     {
-      struct cleanup *old_chain = save_inferior_ptid ();
-
-      inferior_ptid = regcache->ptid;
       target_fetch_registers (regcache, regnum);
-      do_cleanups (old_chain);
 
       /* A number of targets can't access the whole set of raw
         registers (because the debug API provides no means to get at
@@ -666,6 +669,13 @@ regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
       if (regcache->register_status[regnum] == REG_UNKNOWN)
        regcache->register_status[regnum] = REG_UNAVAILABLE;
     }
+}
+
+enum register_status
+regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
+{
+  gdb_assert (buf != NULL);
+  regcache_raw_update (regcache, regnum);
 
   if (regcache->register_status[regnum] != REG_VALID)
     memset (buf, 0, regcache->descr->sizeof_register[regnum]);
@@ -918,8 +928,7 @@ void
 regcache_raw_write (struct regcache *regcache, int regnum,
                    const gdb_byte *buf)
 {
-  struct cleanup *chain_before_save_inferior;
-  struct cleanup *chain_before_invalidate_register;
+  struct cleanup *old_chain;
 
   gdb_assert (regcache != NULL && buf != NULL);
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
@@ -937,24 +946,18 @@ regcache_raw_write (struct regcache *regcache, int regnum,
                  regcache->descr->sizeof_register[regnum]) == 0))
     return;
 
-  chain_before_save_inferior = save_inferior_ptid ();
-  inferior_ptid = regcache->ptid;
-
   target_prepare_to_store (regcache);
   regcache_raw_set_cached_value (regcache, regnum, buf);
 
   /* Register a cleanup function for invalidating the register after it is
      written, in case of a failure.  */
-  chain_before_invalidate_register
-    = make_cleanup_regcache_invalidate (regcache, regnum);
+  old_chain = make_cleanup_regcache_invalidate (regcache, regnum);
 
   target_store_registers (regcache, regnum);
 
   /* The target did not throw an error so we can discard invalidating the
      register and restore the cleanup chain to what it was.  */
-  discard_cleanups (chain_before_invalidate_register);
-
-  do_cleanups (chain_before_save_inferior);
+  discard_cleanups (old_chain);
 }
 
 void
@@ -988,7 +991,8 @@ regcache_xfer_part (struct regcache *regcache, int regnum,
                                   const gdb_byte *buf))
 {
   struct regcache_descr *descr = regcache->descr;
-  gdb_byte reg[MAX_REGISTER_SIZE];
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  gdb_byte *reg = (gdb_byte *) alloca (register_size (gdbarch, regnum));
 
   gdb_assert (offset >= 0 && offset <= descr->sizeof_register[regnum]);
   gdb_assert (len >= 0 && offset + len <= descr->sizeof_register[regnum]);
@@ -1249,6 +1253,41 @@ regcache_write_pc (struct regcache *regcache, CORE_ADDR pc)
   reinit_frame_cache ();
 }
 
+void
+regcache_debug_print_register (const char *func, struct regcache *regcache,
+                              int regno)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+  fprintf_unfiltered (gdb_stdlog, "%s ", func);
+  if (regno >= 0 && regno < gdbarch_num_regs (gdbarch)
+      && gdbarch_register_name (gdbarch, regno) != NULL
+      && gdbarch_register_name (gdbarch, regno)[0] != '\0')
+    fprintf_unfiltered (gdb_stdlog, "(%s)",
+                       gdbarch_register_name (gdbarch, regno));
+  else
+    fprintf_unfiltered (gdb_stdlog, "(%d)", regno);
+  if (regno >= 0 && regno < gdbarch_num_regs (gdbarch))
+    {
+      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+      int size = register_size (gdbarch, regno);
+      gdb_byte *buf = register_buffer (regcache, regno);
+
+      fprintf_unfiltered (gdb_stdlog, " = ");
+      for (int i = 0; i < size; i++)
+       {
+         fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
+       }
+      if (size <= sizeof (LONGEST))
+       {
+         ULONGEST val = extract_unsigned_integer (buf, size, byte_order);
+
+         fprintf_unfiltered (gdb_stdlog, " %s %s",
+                             core_addr_to_string_nz (val), plongest (val));
+       }
+    }
+  fprintf_unfiltered (gdb_stdlog, "\n");
+}
 
 static void
 reg_flush_command (char *command, int from_tty)
@@ -1497,14 +1536,11 @@ regcache_print (char *args, enum regcache_dump_what what_to_dump)
     regcache_dump (get_current_regcache (), gdb_stdout, what_to_dump);
   else
     {
-      struct cleanup *cleanups;
-      struct ui_file *file = gdb_fopen (args, "w");
+      stdio_file file;
 
-      if (file == NULL)
+      if (!file.open (args, "w"))
        perror_with_name (_("maintenance print architecture"));
-      cleanups = make_cleanup_ui_file_delete (file);
-      regcache_dump (get_current_regcache (), file, what_to_dump);
-      do_cleanups (cleanups);
+      regcache_dump (get_current_regcache (), &file, what_to_dump);
     }
 }
 
This page took 0.026809 seconds and 4 git commands to generate.