diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 0947100..58ab741 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -2225,7 +2225,7 @@ aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 
 static struct value *
 aarch64_pseudo_read_value (struct gdbarch *gdbarch,
-			   struct regcache *regcache,
+			   regcache_read *regcache,
 			   int regnum)
 {
   gdb_byte reg_buf[V_REGISTER_SIZE];
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index 57dc979..a8c43b2 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -347,7 +347,7 @@ amd64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
 
 static struct value *
 amd64_pseudo_register_read_value (struct gdbarch *gdbarch,
-				  struct regcache *regcache,
+				  regcache_read *regcache,
 				  int regnum)
 {
   gdb_byte *raw_buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 20da423..bde199a 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -227,7 +227,7 @@ static void show_disassembly_style_sfunc (struct ui_file *, int,
 					  const char *);
 
 static enum register_status arm_neon_quad_read (struct gdbarch *gdbarch,
-						struct regcache *regcache,
+						regcache_read *regcache,
 						int regnum, gdb_byte *buf);
 static void arm_neon_quad_write (struct gdbarch *gdbarch,
 				 struct regcache *regcache,
@@ -8678,7 +8678,7 @@ arm_write_pc (struct regcache *regcache, CORE_ADDR pc)
    the quad register, in [0, 15].  */
 
 static enum register_status
-arm_neon_quad_read (struct gdbarch *gdbarch, struct regcache *regcache,
+arm_neon_quad_read (struct gdbarch *gdbarch, regcache_read *regcache,
 		    int regnum, gdb_byte *buf)
 {
   char name_buf[4];
@@ -8711,7 +8711,7 @@ arm_neon_quad_read (struct gdbarch *gdbarch, struct regcache *regcache,
 }
 
 static enum register_status
-arm_pseudo_read (struct gdbarch *gdbarch, struct regcache *regcache,
+arm_pseudo_read (struct gdbarch *gdbarch, regcache_read *regcache,
 		 int regnum, gdb_byte *buf)
 {
   const int num_regs = gdbarch_num_regs (gdbarch);
diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c
index bcf844a..40cb724 100644
--- a/gdb/avr-tdep.c
+++ b/gdb/avr-tdep.c
@@ -382,7 +382,7 @@ avr_write_pc (struct regcache *regcache, CORE_ADDR val)
 }
 
 static enum register_status
-avr_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+avr_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache,
                           int regnum, gdb_byte *buf)
 {
   ULONGEST val;
diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c
index 9e37898..fc4d246 100644
--- a/gdb/bfin-tdep.c
+++ b/gdb/bfin-tdep.c
@@ -688,7 +688,7 @@ bfin_register_name (struct gdbarch *gdbarch, int i)
 }
 
 static enum register_status
-bfin_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+bfin_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache,
 			   int regnum, gdb_byte *buffer)
 {
   gdb_byte buf[BFIN_MAX_REGISTER_SIZE];
diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c
index 9e552eb..1b7b1f8 100644
--- a/gdb/frv-tdep.c
+++ b/gdb/frv-tdep.c
@@ -295,7 +295,7 @@ frv_register_type (struct gdbarch *gdbarch, int reg)
 }
 
 static enum register_status
-frv_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+frv_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache,
                           int reg, gdb_byte *buffer)
 {
   enum register_status status;
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 007392c..525e8bd 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -1965,7 +1965,7 @@ gdbarch_pseudo_register_read_p (struct gdbarch *gdbarch)
 }
 
 enum register_status
-gdbarch_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, gdb_byte *buf)
+gdbarch_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache, int cookednum, gdb_byte *buf)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->pseudo_register_read != NULL);
@@ -1989,7 +1989,7 @@ gdbarch_pseudo_register_read_value_p (struct gdbarch *gdbarch)
 }
 
 struct value *
-gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum)
+gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, regcache_read *regcache, int cookednum)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->pseudo_register_read_value != NULL);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index d2e6b6f..7499917 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -265,8 +265,8 @@ extern void set_gdbarch_virtual_frame_pointer (struct gdbarch *gdbarch, gdbarch_
 
 extern int gdbarch_pseudo_register_read_p (struct gdbarch *gdbarch);
 
-typedef enum register_status (gdbarch_pseudo_register_read_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, gdb_byte *buf);
-extern enum register_status gdbarch_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum, gdb_byte *buf);
+typedef enum register_status (gdbarch_pseudo_register_read_ftype) (struct gdbarch *gdbarch, regcache_read *regcache, int cookednum, gdb_byte *buf);
+extern enum register_status gdbarch_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache, int cookednum, gdb_byte *buf);
 extern void set_gdbarch_pseudo_register_read (struct gdbarch *gdbarch, gdbarch_pseudo_register_read_ftype *pseudo_register_read);
 
 /* Read a register into a new struct value.  If the register is wholly
@@ -276,8 +276,8 @@ extern void set_gdbarch_pseudo_register_read (struct gdbarch *gdbarch, gdbarch_p
 
 extern int gdbarch_pseudo_register_read_value_p (struct gdbarch *gdbarch);
 
-typedef struct value * (gdbarch_pseudo_register_read_value_ftype) (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum);
-extern struct value * gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, struct regcache *regcache, int cookednum);
+typedef struct value * (gdbarch_pseudo_register_read_value_ftype) (struct gdbarch *gdbarch, regcache_read *regcache, int cookednum);
+extern struct value * gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, regcache_read *regcache, int cookednum);
 extern void set_gdbarch_pseudo_register_read_value (struct gdbarch *gdbarch, gdbarch_pseudo_register_read_value_ftype *pseudo_register_read_value);
 
 extern int gdbarch_pseudo_register_write_p (struct gdbarch *gdbarch);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 6459b12..9da7328 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -429,12 +429,12 @@ F;void;write_pc;struct regcache *regcache, CORE_ADDR val;regcache, val
 # serious shakedown.
 m;void;virtual_frame_pointer;CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset;pc, frame_regnum, frame_offset;0;legacy_virtual_frame_pointer;;0
 #
-M;enum register_status;pseudo_register_read;struct regcache *regcache, int cookednum, gdb_byte *buf;regcache, cookednum, buf
+M;enum register_status;pseudo_register_read;regcache_read *regcache, int cookednum, gdb_byte *buf;regcache, cookednum, buf
 # Read a register into a new struct value.  If the register is wholly
 # or partly unavailable, this should call mark_value_bytes_unavailable
 # as appropriate.  If this is defined, then pseudo_register_read will
 # never be called.
-M;struct value *;pseudo_register_read_value;struct regcache *regcache, int cookednum;regcache, cookednum
+M;struct value *;pseudo_register_read_value;regcache_read *regcache, int cookednum;regcache, cookednum
 M;void;pseudo_register_write;struct regcache *regcache, int cookednum, const gdb_byte *buf;regcache, cookednum, buf
 #
 v;int;num_regs;;;0;-1
diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c
index fc8c72f..15ee458 100644
--- a/gdb/h8300-tdep.c
+++ b/gdb/h8300-tdep.c
@@ -1160,7 +1160,7 @@ h8300_register_type (struct gdbarch *gdbarch, int regno)
    raw registers.  These helpers extend/narrow the values.  */
 
 static enum register_status
-pseudo_from_raw_register (struct gdbarch *gdbarch, struct regcache *regcache,
+pseudo_from_raw_register (struct gdbarch *gdbarch, regcache_read *regcache,
 			  gdb_byte *buf, int pseudo_regno, int raw_regno)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -1191,7 +1191,7 @@ raw_from_pseudo_register (struct gdbarch *gdbarch, struct regcache *regcache,
 
 static enum register_status
 h8300_pseudo_register_read (struct gdbarch *gdbarch,
-			    struct regcache *regcache, int regno,
+			    regcache_read *regcache, int regno,
 			    gdb_byte *buf)
 {
   if (regno == E_PSEUDO_CCR_REGNUM (gdbarch))
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index 1e007d9..f6a2f50 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -2747,7 +2747,7 @@ hppa_fetch_pointer_argument (struct frame_info *frame, int argi,
 }
 
 static enum register_status
-hppa_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+hppa_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache,
 			   int regnum, gdb_byte *buf)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 2a9e4a7..913bdc8 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -3248,7 +3248,7 @@ i386_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
    the MMX registers need to be mapped onto floating point registers.  */
 
 static int
-i386_mmx_regnum_to_fp_regnum (struct regcache *regcache, int regnum)
+i386_mmx_regnum_to_fp_regnum (regcache_read *regcache, int regnum)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
   int mmxreg, fpreg;
@@ -3269,7 +3269,7 @@ i386_mmx_regnum_to_fp_regnum (struct regcache *regcache, int regnum)
 
 void
 i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
-				      struct regcache *regcache,
+				      regcache_read *regcache,
 				      int regnum,
 				      struct value *result_value)
 {
@@ -3448,7 +3448,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
 
 static struct value *
 i386_pseudo_register_read_value (struct gdbarch *gdbarch,
-				 struct regcache *regcache,
+				 regcache_read *regcache,
 				 int regnum)
 {
   struct value *result;
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index f190bb3..f5c2194 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -364,7 +364,7 @@ extern struct type *i386_pseudo_register_type (struct gdbarch *gdbarch,
 					       int regnum);
 
 extern void i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
-						  struct regcache *regcache,
+						  regcache_read *regcache,
 						  int regnum,
 						  struct value *result);
 
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index 5bce751..acd0909 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -927,7 +927,7 @@ rse_address_add(CORE_ADDR addr, int nslots)
 }
 
 static enum register_status
-ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+ia64_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache,
                            int regnum, gdb_byte *buf)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index e04fdfd..8efc142 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -51,7 +51,7 @@ typedef enum register_status (m32c_write_reg_t) (struct m32c_reg *reg,
 						 const gdb_byte *buf);
 
 typedef enum register_status (m32c_read_reg_t) (struct m32c_reg *reg,
-						struct regcache *cache,
+						regcache_read *cache,
 						gdb_byte *buf);
 
 struct m32c_reg
@@ -310,7 +310,7 @@ static m32c_write_reg_t m32c_r3r2r1r0_write;
 
 /* Copy the value of the raw register REG from CACHE to BUF.  */
 static enum register_status
-m32c_raw_read (struct m32c_reg *reg, struct regcache *cache, gdb_byte *buf)
+m32c_raw_read (struct m32c_reg *reg, regcache_read *cache, gdb_byte *buf)
 {
   return cache->raw_read (reg->num, buf);
 }
@@ -329,7 +329,7 @@ m32c_raw_write (struct m32c_reg *reg, struct regcache *cache,
 
 /* Return the value of the 'flg' register in CACHE.  */
 static int
-m32c_read_flg (struct regcache *cache)
+m32c_read_flg (regcache_read *cache)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (cache->arch ());
   ULONGEST flg;
@@ -341,7 +341,7 @@ m32c_read_flg (struct regcache *cache)
 
 /* Evaluate the real register number of a banked register.  */
 static struct m32c_reg *
-m32c_banked_register (struct m32c_reg *reg, struct regcache *cache)
+m32c_banked_register (struct m32c_reg *reg, regcache_read *cache)
 {
   return ((m32c_read_flg (cache) & reg->n) ? reg->ry : reg->rx);
 }
@@ -352,7 +352,7 @@ m32c_banked_register (struct m32c_reg *reg, struct regcache *cache)
    masked in REG->n set, then read REG->ry.  Otherwise, read
    REG->rx.  */
 static enum register_status
-m32c_banked_read (struct m32c_reg *reg, struct regcache *cache, gdb_byte *buf)
+m32c_banked_read (struct m32c_reg *reg, regcache_read *cache, gdb_byte *buf)
 {
   struct m32c_reg *bank_reg = m32c_banked_register (reg, cache);
   return cache->raw_read (bank_reg->num, buf);
@@ -377,7 +377,7 @@ m32c_banked_write (struct m32c_reg *reg, struct regcache *cache,
 /* Move the value of SB from CACHE to BUF.  On bfd_mach_m32c, SB is a
    banked register; on bfd_mach_m16c, it's not.  */
 static enum register_status
-m32c_sb_read (struct m32c_reg *reg, struct regcache *cache, gdb_byte *buf)
+m32c_sb_read (struct m32c_reg *reg, regcache_read *cache, gdb_byte *buf)
 {
   if (gdbarch_bfd_arch_info (reg->arch)->mach == bfd_mach_m16c)
     return m32c_raw_read (reg->rx, cache, buf);
@@ -442,7 +442,7 @@ m32c_find_part (struct m32c_reg *reg, int *offset_p, int *len_p)
    REG->type values, where higher indices refer to more significant
    bits, read the value of the REG->n'th element.  */
 static enum register_status
-m32c_part_read (struct m32c_reg *reg, struct regcache *cache, gdb_byte *buf)
+m32c_part_read (struct m32c_reg *reg, regcache_read *cache, gdb_byte *buf)
 {
   int offset, len;
 
@@ -473,7 +473,7 @@ m32c_part_write (struct m32c_reg *reg, struct regcache *cache,
    concatenation of the values of the registers REG->rx and REG->ry,
    with REG->rx contributing the more significant bits.  */
 static enum register_status
-m32c_cat_read (struct m32c_reg *reg, struct regcache *cache, gdb_byte *buf)
+m32c_cat_read (struct m32c_reg *reg, regcache_read *cache, gdb_byte *buf)
 {
   int high_bytes = TYPE_LENGTH (reg->rx->type);
   int low_bytes  = TYPE_LENGTH (reg->ry->type);
@@ -528,7 +528,7 @@ m32c_cat_write (struct m32c_reg *reg, struct regcache *cache,
    the concatenation (from most significant to least) of r3, r2, r1,
    and r0.  */
 static enum register_status
-m32c_r3r2r1r0_read (struct m32c_reg *reg, struct regcache *cache, gdb_byte *buf)
+m32c_r3r2r1r0_read (struct m32c_reg *reg, regcache_read *cache, gdb_byte *buf)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (reg->arch);
   int len = TYPE_LENGTH (tdep->r0->type);
@@ -590,7 +590,7 @@ m32c_r3r2r1r0_write (struct m32c_reg *reg, struct regcache *cache,
 
 static enum register_status
 m32c_pseudo_register_read (struct gdbarch *arch,
-			   struct regcache *cache,
+			   regcache_read *cache,
 			   int cookednum,
 			   gdb_byte *buf)
 {
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
index 3ef1fbf..878b1a9 100644
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -279,7 +279,7 @@ m68hc11_which_soft_register (CORE_ADDR addr)
    fetch into a memory read.  */
 static enum register_status
 m68hc11_pseudo_register_read (struct gdbarch *gdbarch,
-			      struct regcache *regcache,
+			      regcache_read *regcache,
 			      int regno, gdb_byte *buf)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c
index 4069d59..3c5f258 100644
--- a/gdb/mep-tdep.c
+++ b/gdb/mep-tdep.c
@@ -1125,7 +1125,7 @@ mep_read_pc (struct regcache *regcache)
 
 static enum register_status
 mep_pseudo_cr32_read (struct gdbarch *gdbarch,
-                      struct regcache *regcache,
+		      regcache_read *regcache,
                       int cookednum,
                       gdb_byte *buf)
 {
@@ -1151,7 +1151,7 @@ mep_pseudo_cr32_read (struct gdbarch *gdbarch,
 
 static enum register_status
 mep_pseudo_cr64_read (struct gdbarch *gdbarch,
-                      struct regcache *regcache,
+                      regcache_read *regcache,
                       int cookednum,
                       gdb_byte *buf)
 {
@@ -1161,7 +1161,7 @@ mep_pseudo_cr64_read (struct gdbarch *gdbarch,
 
 static enum register_status
 mep_pseudo_register_read (struct gdbarch *gdbarch,
-                          struct regcache *regcache,
+			  regcache_read *regcache,
                           int cookednum,
                           gdb_byte *buf)
 {
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 1e7cb4a..35e0132 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -737,7 +737,7 @@ mips_tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
    registers.  Take care of alignment and size problems.  */
 
 static enum register_status
-mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+mips_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache,
 			   int cookednum, gdb_byte *buf)
 {
   int rawnum = cookednum % gdbarch_num_regs (gdbarch);
diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
index 834f4e6..eebe7da 100644
--- a/gdb/msp430-tdep.c
+++ b/gdb/msp430-tdep.c
@@ -218,7 +218,7 @@ msp430_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 
 static enum register_status
 msp430_pseudo_register_read (struct gdbarch *gdbarch,
-			     struct regcache *regcache,
+			     regcache_read *regcache,
 			     int regnum, gdb_byte *buffer)
 {
   if (MSP430_NUM_REGS <= regnum && regnum < MSP430_NUM_TOTAL_REGS)
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index f4037b2..001db1f 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -437,7 +437,7 @@ nds32_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
 
 static enum register_status
 nds32_pseudo_register_read (struct gdbarch *gdbarch,
-			    struct regcache *regcache, int regnum,
+			    regcache_read *regcache, int regnum,
 			    gdb_byte *buf)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 8cc9c98..5ce6064 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -205,7 +205,7 @@ regcache::regcache (gdbarch *gdbarch, const address_space *aspace_,
 /* The register buffers.  A read-only register cache can hold the
    full [0 .. gdbarch_num_regs + gdbarch_num_pseudo_regs) while a
    read/write register cache can only hold [0 .. gdbarch_num_regs).  */
-  : reg_buffer (gdbarch, readonly_p_),
+  : regcache_read (gdbarch, readonly_p_),
     m_aspace (aspace_), m_readonly_p (readonly_p_)
 {
   m_ptid = minus_one_ptid;
@@ -581,7 +581,7 @@ regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
 }
 
 enum register_status
-regcache::raw_read (int regnum, gdb_byte *buf)
+regcache_read::raw_read (int regnum, gdb_byte *buf)
 {
   gdb_assert (buf != NULL);
   raw_update (regnum);
@@ -604,7 +604,7 @@ regcache_raw_read_signed (struct regcache *regcache, int regnum, LONGEST *val)
 
 template<typename T, typename>
 enum register_status
-regcache::raw_read (int regnum, T *val)
+regcache_read::raw_read (int regnum, T *val)
 {
   gdb_byte *buf;
   enum register_status status;
@@ -677,17 +677,15 @@ regcache_cooked_read (struct regcache *regcache, int regnum, gdb_byte *buf)
 }
 
 enum register_status
-regcache::cooked_read (int regnum, gdb_byte *buf)
+regcache_read::cooked_read (int regnum, gdb_byte *buf)
 {
   gdb_assert (regnum >= 0);
   gdb_assert (regnum < m_descr->nr_cooked_registers);
   if (regnum < num_raw_registers ())
     return raw_read (regnum, buf);
-  else if (m_readonly_p
+  else if (m_has_pseudo
 	   && m_register_status[regnum] != REG_UNKNOWN)
     {
-      /* Read-only register cache, perhaps the cooked value was
-	 cached?  */
       if (m_register_status[regnum] == REG_VALID)
 	memcpy (buf, register_buffer (regnum),
 		m_descr->sizeof_register[regnum]);
@@ -730,13 +728,13 @@ regcache_cooked_read_value (struct regcache *regcache, int regnum)
 }
 
 struct value *
-regcache::cooked_read_value (int regnum)
+regcache_read::cooked_read_value (int regnum)
 {
   gdb_assert (regnum >= 0);
   gdb_assert (regnum < m_descr->nr_cooked_registers);
 
   if (regnum < num_raw_registers ()
-      || (m_readonly_p && m_register_status[regnum] != REG_UNKNOWN)
+      || (m_has_pseudo && m_register_status[regnum] != REG_UNKNOWN)
       || !gdbarch_pseudo_register_read_value_p (m_descr->gdbarch))
     {
       struct value *result;
@@ -770,7 +768,7 @@ regcache_cooked_read_signed (struct regcache *regcache, int regnum,
 
 template<typename T, typename>
 enum register_status
-regcache::cooked_read (int regnum, T *val)
+regcache_read::cooked_read (int regnum, T *val)
 {
   enum register_status status;
   gdb_byte *buf;
@@ -910,20 +908,49 @@ typedef void (regcache_write_ftype) (struct regcache *regcache, int regnum,
 				     const void *buf);
 
 enum register_status
-regcache::xfer_part (int regnum, int offset, int len, void *in,
+regcache_read::read_part (int regnum, int offset, int len, void *in,
+			  bool is_raw)
+{
+  struct gdbarch *gdbarch = arch ();
+  gdb_byte *reg = (gdb_byte *) alloca (register_size (gdbarch, regnum));
+
+  gdb_assert (in != NULL);
+  gdb_assert (offset >= 0 && offset <= m_descr->sizeof_register[regnum]);
+  gdb_assert (len >= 0 && offset + len <= m_descr->sizeof_register[regnum]);
+  /* Something to do?  */
+  if (offset + len == 0)
+    return REG_VALID;
+  /* Read (when needed) ...  */
+  enum register_status status;
+
+  if (is_raw)
+    status = raw_read (regnum, reg);
+  else
+    status = cooked_read (regnum, reg);
+  if (status != REG_VALID)
+    return status;
+
+  /* ... modify ...  */
+  memcpy (in, reg + offset, len);
+
+  return REG_VALID;
+}
+
+enum register_status
+regcache::write_part (int regnum, int offset, int len,
 		     const void *out, bool is_raw)
 {
   struct gdbarch *gdbarch = arch ();
   gdb_byte *reg = (gdb_byte *) alloca (register_size (gdbarch, regnum));
 
+  gdb_assert (out != NULL);
   gdb_assert (offset >= 0 && offset <= m_descr->sizeof_register[regnum]);
   gdb_assert (len >= 0 && offset + len <= m_descr->sizeof_register[regnum]);
   /* Something to do?  */
   if (offset + len == 0)
     return REG_VALID;
   /* Read (when needed) ...  */
-  if (in != NULL
-      || offset > 0
+  if (offset > 0
       || offset + len < m_descr->sizeof_register[regnum])
     {
       enum register_status status;
@@ -935,19 +962,13 @@ regcache::xfer_part (int regnum, int offset, int len, void *in,
       if (status != REG_VALID)
 	return status;
     }
-  /* ... modify ...  */
-  if (in != NULL)
-    memcpy (in, reg + offset, len);
-  if (out != NULL)
-    memcpy (reg + offset, out, len);
+
+  memcpy (reg + offset, out, len);
   /* ... write (when needed).  */
-  if (out != NULL)
-    {
-      if (is_raw)
-	raw_write (regnum, reg);
-      else
-	cooked_write (regnum, reg);
-    }
+  if (is_raw)
+    raw_write (regnum, reg);
+  else
+    cooked_write (regnum, reg);
 
   return REG_VALID;
 }
@@ -960,10 +981,10 @@ regcache_raw_read_part (struct regcache *regcache, int regnum,
 }
 
 enum register_status
-regcache::raw_read_part (int regnum, int offset, int len, gdb_byte *buf)
+regcache_read::raw_read_part (int regnum, int offset, int len, gdb_byte *buf)
 {
   assert_regnum (regnum);
-  return xfer_part (regnum, offset, len, buf, NULL, true);
+  return read_part (regnum, offset, len, buf, true);
 }
 
 void
@@ -978,7 +999,7 @@ regcache::raw_write_part (int regnum, int offset, int len,
 			  const gdb_byte *buf)
 {
   assert_regnum (regnum);
-  xfer_part (regnum, offset, len, NULL, buf, true);
+  write_part (regnum, offset, len, buf, true);
 }
 
 enum register_status
@@ -990,10 +1011,11 @@ regcache_cooked_read_part (struct regcache *regcache, int regnum,
 
 
 enum register_status
-regcache::cooked_read_part (int regnum, int offset, int len, gdb_byte *buf)
+regcache_read::cooked_read_part (int regnum, int offset, int len,
+				 gdb_byte *buf)
 {
   gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers);
-  return xfer_part (regnum, offset, len, buf, NULL, false);
+  return read_part (regnum, offset, len, buf, false);
 }
 
 void
@@ -1008,7 +1030,7 @@ regcache::cooked_write_part (int regnum, int offset, int len,
 			     const gdb_byte *buf)
 {
   gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers);
-  xfer_part (regnum, offset, len, NULL, buf, false);
+  write_part (regnum, offset, len, buf, false);
 }
 
 /* Supply register REGNUM, whose contents are stored in BUF, to REGCACHE.  */
diff --git a/gdb/regcache.h b/gdb/regcache.h
index a133de1..b107bbd 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -262,9 +262,39 @@ protected:
   signed char *m_register_status;
 };
 
+class regcache_read : public reg_buffer
+{
+public:
+  regcache_read (gdbarch *gdbarch, bool has_pseudo)
+    : reg_buffer (gdbarch, has_pseudo)
+  {}
+
+  enum register_status raw_read (int regnum, gdb_byte *buf);
+  template<typename T, typename = RequireLongest<T>>
+  enum register_status raw_read (int regnum, T *val);
+
+  enum register_status raw_read_part (int regnum, int offset, int len,
+				      gdb_byte *buf);
+
+  virtual void raw_update (int regnum) = 0;
+
+  enum register_status cooked_read (int regnum, gdb_byte *buf);
+  template<typename T, typename = RequireLongest<T>>
+  enum register_status cooked_read (int regnum, T *val);
+
+  enum register_status cooked_read_part (int regnum, int offset, int len,
+					 gdb_byte *buf);
+
+  struct value *cooked_read_value (int regnum);
+
+protected:
+  enum register_status read_part (int regnum, int offset, int len, void *in,
+				  bool is_raw);
+};
+
 /* The register cache for storing raw register values.  */
 
-class regcache : public reg_buffer
+class regcache : public regcache_read
 {
 public:
   regcache (gdbarch *gdbarch)
@@ -287,28 +317,17 @@ public:
 
   void save (regcache_cooked_read_ftype *cooked_read, void *src);
 
-  enum register_status cooked_read (int regnum, gdb_byte *buf);
   void cooked_write (int regnum, const gdb_byte *buf);
 
-  enum register_status raw_read (int regnum, gdb_byte *buf);
-
   void raw_write (int regnum, const gdb_byte *buf);
 
   template<typename T, typename = RequireLongest<T>>
-  enum register_status raw_read (int regnum, T *val);
-
-  template<typename T, typename = RequireLongest<T>>
   void raw_write (int regnum, T val);
 
-  struct value *cooked_read_value (int regnum);
-
-  template<typename T, typename = RequireLongest<T>>
-  enum register_status cooked_read (int regnum, T *val);
-
   template<typename T, typename = RequireLongest<T>>
   void cooked_write (int regnum, T val);
 
-  void raw_update (int regnum);
+  void raw_update (int regnum) override;
 
   void raw_collect (int regnum, void *buf) const;
 
@@ -328,14 +347,8 @@ public:
 
   void invalidate (int regnum);
 
-  enum register_status raw_read_part (int regnum, int offset, int len,
-				      gdb_byte *buf);
-
   void raw_write_part (int regnum, int offset, int len, const gdb_byte *buf);
 
-  enum register_status cooked_read_part (int regnum, int offset, int len,
-					 gdb_byte *buf);
-
   void cooked_write_part (int regnum, int offset, int len,
 			  const gdb_byte *buf);
 
@@ -370,14 +383,15 @@ protected:
 private:
   void restore (struct regcache *src);
 
-  enum register_status xfer_part (int regnum, int offset, int len, void *in,
-				  const void *out, bool is_raw);
-
   void transfer_regset (const struct regset *regset,
 			struct regcache *out_regcache,
 			int regnum, const void *in_buf,
 			void *out_buf, size_t size) const;
 
+  enum register_status write_part (int regnum, int offset, int len,
+				   const void *out, bool is_raw);
+
+
   /* The address space of this register cache (for registers where it
      makes sense, like PC or SP).  */
   const address_space * const m_aspace;
diff --git a/gdb/rl78-tdep.c b/gdb/rl78-tdep.c
index 76630af..4c116be 100644
--- a/gdb/rl78-tdep.c
+++ b/gdb/rl78-tdep.c
@@ -640,7 +640,7 @@ rl78_make_data_address (CORE_ADDR addr)
 
 static enum register_status
 rl78_pseudo_register_read (struct gdbarch *gdbarch,
-                           struct regcache *regcache,
+			   regcache_read *regcache,
                            int reg, gdb_byte *buffer)
 {
   enum register_status status;
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index c902daf..427e6d2 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -2707,12 +2707,6 @@ e500_move_ev_register (move_ev_register_func move,
 }
 
 static enum register_status
-do_regcache_raw_read (struct regcache *regcache, int regnum, void *buffer)
-{
-  return regcache_raw_read (regcache, regnum, (gdb_byte *) buffer);
-}
-
-static enum register_status
 do_regcache_raw_write (struct regcache *regcache, int regnum, void *buffer)
 {
   regcache_raw_write (regcache, regnum, (const gdb_byte *) buffer);
@@ -2721,10 +2715,36 @@ do_regcache_raw_write (struct regcache *regcache, int regnum, void *buffer)
 }
 
 static enum register_status
-e500_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
-			   int reg_nr, gdb_byte *buffer)
+e500_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache,
+			   int ev_reg, gdb_byte *buffer)
 {
-  return e500_move_ev_register (do_regcache_raw_read, regcache, reg_nr, buffer);
+  struct gdbarch *arch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
+  int reg_index;
+  enum register_status status;
+
+  gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
+
+  reg_index = ev_reg - tdep->ppc_ev0_regnum;
+
+  if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG)
+    {
+      status = regcache->raw_read (tdep->ppc_ev0_upper_regnum + reg_index,
+				   buffer);
+      if (status == REG_VALID)
+	status = regcache->raw_read (tdep->ppc_gp0_regnum + reg_index,
+				     buffer + 4);
+    }
+  else
+    {
+      status = regcache->raw_read (tdep->ppc_gp0_regnum + reg_index, buffer);
+      if (status == REG_VALID)
+	status = regcache->raw_read (tdep->ppc_ev0_upper_regnum + reg_index,
+				     buffer + 4);
+    }
+
+  return status;
+
 }
 
 static void
@@ -2737,7 +2757,7 @@ e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 
 /* Read method for DFP pseudo-registers.  */
 static enum register_status
-dfp_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+dfp_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache,
 			   int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
@@ -2793,7 +2813,7 @@ dfp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 
 /* Read method for POWER7 VSX pseudo-registers.  */
 static enum register_status
-vsx_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+vsx_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache,
 			   int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
@@ -2858,7 +2878,7 @@ vsx_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 
 /* Read method for POWER7 Extended FP pseudo-registers.  */
 static enum register_status
-efpr_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+efpr_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache,
 			   int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
@@ -2866,9 +2886,9 @@ efpr_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
   int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
 
   /* Read the portion that overlaps the VMX register.  */
-  return regcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index,
-				 offset, register_size (gdbarch, reg_nr),
-				 buffer);
+  return regcache->raw_read_part (tdep->ppc_vr0_regnum + reg_index,
+				  offset, register_size (gdbarch, reg_nr),
+				  buffer);
 }
 
 /* Write method for POWER7 Extended FP pseudo-registers.  */
@@ -2888,7 +2908,7 @@ efpr_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 
 static enum register_status
 rs6000_pseudo_register_read (struct gdbarch *gdbarch,
-			     struct regcache *regcache,
+			     regcache_read *regcache,
 			     int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch *regcache_arch = regcache->arch ();
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index a016864..efc74d1 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -387,7 +387,7 @@ s390_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 }
 
 static enum register_status
-s390_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+s390_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache,
 			   int regnum, gdb_byte *buf)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index 6c4e5bb..2da727b 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -1628,7 +1628,7 @@ dr_reg_base_num (struct gdbarch *gdbarch, int dr_regnum)
 
 static enum register_status
 pseudo_register_read_portions (struct gdbarch *gdbarch,
-			       struct regcache *regcache,
+			       regcache_read *regcache,
 			       int portions,
 			       int base_regnum, gdb_byte *buffer)
 {
@@ -1649,7 +1649,7 @@ pseudo_register_read_portions (struct gdbarch *gdbarch,
 }
 
 static enum register_status
-sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+sh_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache,
 			 int reg_nr, gdb_byte *buffer)
 {
   int base_regnum;
diff --git a/gdb/sh64-tdep.c b/gdb/sh64-tdep.c
index ec87902..a900dce 100644
--- a/gdb/sh64-tdep.c
+++ b/gdb/sh64-tdep.c
@@ -1504,7 +1504,7 @@ sh64_register_convert_to_raw (struct gdbarch *gdbarch, struct type *type,
 
 static enum register_status
 pseudo_register_read_portions (struct gdbarch *gdbarch,
-			       struct regcache *regcache,
+			       regcache_read *regcache,
 			       int portions,
 			       int base_regnum, gdb_byte *buffer)
 {
@@ -1525,7 +1525,7 @@ pseudo_register_read_portions (struct gdbarch *gdbarch,
 }
 
 static enum register_status
-sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+sh64_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache,
 			   int reg_nr, gdb_byte *buffer)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 0fb3481..90bee1a 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -503,7 +503,7 @@ sparc32_register_type (struct gdbarch *gdbarch, int regnum)
 
 static enum register_status
 sparc32_pseudo_register_read (struct gdbarch *gdbarch,
-			      struct regcache *regcache,
+			      regcache_read *regcache,
 			      int regnum, gdb_byte *buf)
 {
   enum register_status status;
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index 54af887..60dd644 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -899,7 +899,7 @@ sparc64_register_type (struct gdbarch *gdbarch, int regnum)
 
 static enum register_status
 sparc64_pseudo_register_read (struct gdbarch *gdbarch,
-			      struct regcache *regcache,
+			      regcache_read *regcache,
 			      int regnum, gdb_byte *buf)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c
index bc7ac77..fb7b089 100644
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -182,7 +182,7 @@ spu_register_type (struct gdbarch *gdbarch, int reg_nr)
 /* Pseudo registers for preferred slots - stack pointer.  */
 
 static enum register_status
-spu_pseudo_register_read_spu (struct regcache *regcache, const char *regname,
+spu_pseudo_register_read_spu (regcache_read *regcache, const char *regname,
 			      gdb_byte *buf)
 {
   struct gdbarch *gdbarch = regcache->arch ();
@@ -207,7 +207,7 @@ spu_pseudo_register_read_spu (struct regcache *regcache, const char *regname,
 }
 
 static enum register_status
-spu_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+spu_pseudo_register_read (struct gdbarch *gdbarch, regcache_read *regcache,
                           int regnum, gdb_byte *buf)
 {
   gdb_byte reg[16];
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index f582708..892873b 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -453,7 +453,7 @@ xtensa_register_write_masked (struct regcache *regcache,
    of the registers and assemble them into a single value.  */
 
 static enum register_status
-xtensa_register_read_masked (struct regcache *regcache,
+xtensa_register_read_masked (regcache_read *regcache,
 			     xtensa_register_t *reg, gdb_byte *buffer)
 {
   unsigned int value[(XTENSA_MAX_REGISTER_SIZE + 3) / 4];
@@ -547,7 +547,7 @@ xtensa_register_read_masked (struct regcache *regcache,
 
 static enum register_status
 xtensa_pseudo_register_read (struct gdbarch *gdbarch,
-			     struct regcache *regcache,
+			     regcache_read *regcache,
 			     int regnum,
 			     gdb_byte *buffer)
 {
