* s390-nat.c (supply_gregset, fill_gregset): On the s390x, the
authorJim Blandy <jimb@codesourcery.com>
Tue, 3 Jun 2003 05:36:53 +0000 (05:36 +0000)
committerJim Blandy <jimb@codesourcery.com>
Tue, 3 Jun 2003 05:36:53 +0000 (05:36 +0000)
elements of gregset_t are 64 bits each, but access registers
are still 32 bits, so they're packed two per gregset_t
element.  Unpack/pack them properly.

gdb/ChangeLog
gdb/s390-nat.c

index cb5ab22f022f8dc1863cb0c98aad36650c2caa5e..279becbb097726626ec622126f2c57a18a030bff 100644 (file)
@@ -1,3 +1,10 @@
+2003-06-03  Jim Blandy  <jimb@redhat.com>
+
+       * s390-nat.c (supply_gregset, fill_gregset): On the s390x, the
+       elements of gregset_t are 64 bits each, but access registers
+       are still 32 bits, so they're packed two per gregset_t
+       element.  Unpack/pack them properly.
+
 2003-06-02  David Carlton  <carlton@bactrian.org>
 
        * linespec.c (find_methods): Break out code into
index 63e779bc19ec1b2e3b752b14c3ffa54992eac8e9..4dc8045f35cd95bcf3391b4f61bfb002650452bd 100644 (file)
@@ -251,9 +251,26 @@ supply_gregset (gregset_t * gregsetp)
   for (regi = 0; regi < S390_NUM_GPRS; regi++)
     supply_register (S390_GP0_REGNUM + regi,
                     (char *) &gregp[S390_GP0_REGNUM + regi]);
+
+#if defined (CONFIG_ARCH_S390X)
+  /* On the s390x, each element of gregset_t is 8 bytes long, but
+     each access register is still only 32 bits long.  So they're
+     packed two per element.  It's apparently traditional that
+     gregset_t must be an array, so when the registers it provides
+     have different sizes, something has to get strange
+     somewhere.  */
+  {
+    unsigned int *acrs = (unsigned int *) &gregp[S390_FIRST_ACR];
+
+    for (regi = 0; regi < S390_NUM_ACRS; regi++)
+      supply_register (S390_FIRST_ACR + regi, (char *) &acrs[regi]);
+  }
+#else
   for (regi = 0; regi < S390_NUM_ACRS; regi++)
     supply_register (S390_FIRST_ACR + regi,
-                    (char *) &gregp[S390_FIRST_ACR + regi]);
+                     (char *) &gregp[S390_FIRST_ACR + regi]);
+#endif
+
   /* unfortunately this isn't in gregsetp */
   for (regi = 0; regi < S390_NUM_CRS; regi++)
     supply_register (S390_FIRST_CR + regi, NULL);
@@ -284,12 +301,35 @@ fill_gregset (gregset_t * gregsetp, int regno)
       for (regi = 0; regi < S390_NUM_GPRS; regi++)
         regcache_collect (S390_GP0_REGNUM + regi,
                          &gregp[S390_GP0_REGNUM + regi]);
+#if defined (CONFIG_ARCH_S390X)
+      /* See the comments about the access registers in
+         supply_gregset, above.  */
+      {
+        unsigned int *acrs = (unsigned int *) &gregp[S390_FIRST_ACR];
+        
+        for (regi = 0; regi < S390_NUM_ACRS; regi++)
+          regcache_collect (S390_FIRST_ACR + regi, &acrs[regi]);
+      }
+#else
       for (regi = 0; regi < S390_NUM_ACRS; regi++)
         regcache_collect (S390_FIRST_ACR + regi,
                          &gregp[S390_FIRST_ACR + regi]);
+#endif
     }
-  else if (regno >= S390_PSWM_REGNUM && regno <= S390_LAST_ACR)
+  else if (regno >= S390_PSWM_REGNUM && regno < S390_FIRST_ACR)
     regcache_collect (regno, &gregp[regno]);
+  else if (regno >= S390_FIRST_ACR && regno <= S390_LAST_ACR)
+    {
+#if defined (CONFIG_ARCH_S390X)
+      /* See the comments about the access registers in
+         supply_gregset, above.  */
+      unsigned int *acrs = (unsigned int *) &gregp[S390_FIRST_ACR];
+        
+      regcache_collect (regno, &acrs[regno - S390_FIRST_ACR]);
+#else
+      regcache_collect (regno, &gregp[regno]);
+#endif
+    }
 }
 
 /*  Given a pointer to a floating point register set in /proc format