* gas/mips/macro-warn-[1234].[sdl]: New tests.
[deliverable/binutils-gdb.git] / gdb / s390-nat.c
index 00f6eccf3466106bdae645d1dbaaa64dbcd3b42a..732cf94451a33a002be6b9eb190bba8f5b72c048 100644 (file)
 
 #include "defs.h"
 #include "tm.h"
+#include "regcache.h"
 #include <asm/ptrace.h>
 #include <sys/ptrace.h>
 #include <asm/processor.h>
+#include <asm/types.h>
 #include <sys/procfs.h>
 #include <sys/user.h>
 #include <value.h>
@@ -58,19 +60,14 @@ s390_register_u_addr (int blockend, int regnum)
     retval = PT_CR_9 + ((regnum - (S390_FIRST_CR + 9)) * S390_CR_SIZE);
   else
     {
-#ifdef GDBSERVER
-      error
-#else
-      internal_error
-#endif
-       ("s390_register_u_addr invalid regnum %s %d regnum=%d", __FILE__,
-        (int) __LINE__, regnum);
+      internal_error (__FILE__, __LINE__,
+                      "s390_register_u_addr invalid regnum regnum=%d",
+                      regnum);
       retval = 0;
     }
   return retval + blockend;
 }
 
-#ifndef GDBSERVER
 /* watch_areas are required if you put 2 or more watchpoints on the same 
    address or overlapping areas gdb will call us to delete the watchpoint 
    more than once when we try to delete them.
@@ -248,9 +245,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);
@@ -271,14 +285,45 @@ supply_fpregset (fpregset_t * fpregsetp)
 void
 fill_gregset (gregset_t * gregsetp, int regno)
 {
+  int regi;
   greg_t *gregp = (greg_t *) gregsetp;
 
-  if (regno >= S390_FIRST_CR && regno <= S390_LAST_CR)
-    supply_register (regno, NULL);
-  else if (regno != -1)
-    supply_register (regno, (char *) &gregp[regno]);
-  else
-    supply_gregset (gregsetp);
+  if (regno < 0) 
+    {
+      regcache_collect (S390_PSWM_REGNUM, &gregp[S390_PSWM_REGNUM]);
+      regcache_collect (S390_PC_REGNUM, &gregp[S390_PC_REGNUM]);
+      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_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
@@ -289,12 +334,18 @@ fill_gregset (gregset_t * gregsetp, int regno)
 void
 fill_fpregset (fpregset_t * fpregsetp, int regno)
 {
-  if (regno == -1)
-    supply_fpregset (fpregsetp);
-  else
-    supply_register (regno,
-                    &((char *) fpregsetp)[REGISTER_BYTE (regno) -
-                                          REGISTER_BYTE (S390_FPC_REGNUM)]);
+  int regi;
+
+  if (regno < 0) 
+    {
+      regcache_collect (S390_FPC_REGNUM, &fpregsetp->fpc);
+      for (regi = 0; regi < S390_NUM_FPRS; regi++)
+        regcache_collect (S390_FP0_REGNUM + regi, &fpregsetp->fprs[regi]);
+    }
+  else if (regno == S390_FPC_REGNUM)
+    regcache_collect (S390_FPC_REGNUM, &fpregsetp->fpc);
+  else if (regno >= S390_FP0_REGNUM && regno <= S390_FPLAST_REGNUM)
+    regcache_collect (regno, &fpregsetp->fprs[regno - S390_FP0_REGNUM]);
 }
 
 
@@ -305,4 +356,3 @@ fill_fpregset (fpregset_t * fpregsetp, int regno)
 #error "libc files are inconsistent with linux/include/asm-s390/"
 #error "3) you didn't do a completely clean build & delete config.cache."
 #endif
-#endif /* GDBSERVER */
This page took 0.02511 seconds and 4 git commands to generate.