* mips-tdep.c (mips_pseudo_register_write): Sign extend 32-bit
authorKevin Buettner <kevinb@redhat.com>
Wed, 15 Dec 2010 20:53:08 +0000 (20:53 +0000)
committerKevin Buettner <kevinb@redhat.com>
Wed, 15 Dec 2010 20:53:08 +0000 (20:53 +0000)
cooked values that are being transferred to 64-bit raw registers.
(mips_pseudo_register_read): Revise to preserve symmetry with
mips_pseudo_register_write().

gdb/ChangeLog
gdb/mips-tdep.c

index 013ff837c890feb5635a4dbe0a475433d08e3dfe..629abfef445c6d9a785a870e6eff7c851964fe11 100644 (file)
@@ -1,3 +1,10 @@
+2010-12-15  Kevin Buettner  <kevinb@redhat.com>
+
+       * mips-tdep.c (mips_pseudo_register_write): Sign extend 32-bit
+       cooked values that are being transferred to 64-bit raw registers.
+       (mips_pseudo_register_read): Revise to preserve symmetry with
+       mips_pseudo_register_write().
+
 2010-12-15  Greg Watson  <g.watson@computer.org>
 
        * f-exp.y (yylex): Check entire token against keywords.
index 98e7a3e05663ee534862a504e42c75d47800b6da..36d59ddd4ff54e79f9386c3154c3d46fb586302f 100644 (file)
@@ -559,11 +559,15 @@ mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
   else if (register_size (gdbarch, rawnum) >
           register_size (gdbarch, cookednum))
     {
-      if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
-         || gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+      if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p)
        regcache_raw_read_part (regcache, rawnum, 0, 4, buf);
       else
-       regcache_raw_read_part (regcache, rawnum, 4, 4, buf);
+       {
+         enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+         LONGEST regval;
+         regcache_raw_read_signed (regcache, rawnum, &regval);
+         store_signed_integer (buf, 4, byte_order, regval);
+       }
     }
   else
     internal_error (__FILE__, __LINE__, _("bad register size"));
@@ -582,11 +586,17 @@ mips_pseudo_register_write (struct gdbarch *gdbarch,
   else if (register_size (gdbarch, rawnum) >
           register_size (gdbarch, cookednum))
     {
-      if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
-         || gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+      if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p)
        regcache_raw_write_part (regcache, rawnum, 0, 4, buf);
       else
-       regcache_raw_write_part (regcache, rawnum, 4, 4, buf);
+       {
+         /* Sign extend the shortened version of the register prior
+            to placing it in the raw register.  This is required for
+            some mips64 parts in order to avoid unpredictable behavior.  */
+         enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+         LONGEST regval = extract_signed_integer (buf, 4, byte_order);
+         regcache_raw_write_signed (regcache, rawnum, regval);
+       }
     }
   else
     internal_error (__FILE__, __LINE__, _("bad register size"));