This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: Define PowerPC E500 SPE xregset


This patch depends on the patch I just posted to implement the generic
libthread_db xregs functions.

2004-06-08  Jim Blandy  <jimb@redhat.com>
	
	Allow access to all 64 bits of the SPE GPR's in multi-threaded
	programs.
	* ppc-tdep.h (struct speregset): New struct type.
	* ppc-linux-tdep.c: #include "gdb_assert.h".
	(ppc_linux_supply_speregset, ppc_linux_collect_speregset): New
	functions.
	(ppc_linux_speregset): New structure.
	(ppc_linux_init_abi): Describe how to pass the full 64-bit values
	of the SPE GPRs across the thread-db interface.
	* ppc-linux-nat.c (struct gdb_evrregset_t): Doc fix.
	* Makefile.in (ppc-linux-tdep.o): Update dependencies.

Index: gdb/ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.66
diff -c -p -r1.66 ppc-linux-tdep.c
*** gdb/ppc-linux-tdep.c	31 Jul 2004 21:53:17 -0000	1.66
--- gdb/ppc-linux-tdep.c	12 Aug 2004 23:15:11 -0000
***************
*** 37,42 ****
--- 37,43 ----
  #include "ppc-tdep.h"
  #include "trad-frame.h"
  #include "frame-unwind.h"
+ #include "gdb_assert.h"
  
  /* The following instructions are used in the signal trampoline code
     on GNU/Linux PPC. The kernel used to use magic syscalls 0x6666 and
*************** ppc_linux_regset_from_core_section (stru
*** 1057,1062 ****
--- 1058,1155 ----
  }
  
  static void
+ ppc_linux_supply_speregset (const struct regset *regset,
+                             struct regcache *regcache,
+                             int regnum,
+                             const void *buf,
+                             size_t len)
+ {
+   struct gdbarch *arch = get_regcache_arch (regcache);
+   struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
+   const struct speregset *speregset = buf;
+ 
+   gdb_assert (len == sizeof (*speregset));
+   gdb_assert (register_size (arch, tdep->ppc_ev0_regnum)
+               == sizeof (speregset->gpr[0]));
+   gdb_assert (register_size (arch, tdep->ppc_acc_regnum)
+               == sizeof (speregset->acc));
+   gdb_assert (register_size (arch, tdep->ppc_spefscr_regnum)
+               == sizeof (speregset->spefscr));
+ 
+   if (regnum == -1)
+     {
+       int i;
+ 
+       for (i = 0; i < 32; i++)
+         regcache_raw_supply (regcache, tdep->ppc_ev0_regnum + i,
+                              &speregset->gpr[i]);
+     }
+   else if (tdep->ppc_ev0_regnum <= regnum
+            && regnum <= tdep->ppc_ev31_regnum)
+     regcache_raw_supply (regcache,  tdep->ppc_ev0_regnum + regnum,
+                          &speregset->gpr[regnum - tdep->ppc_ev0_regnum]);
+ 
+   if (regnum == tdep->ppc_acc_regnum
+       || regnum == -1)
+     regcache_raw_supply (regcache, tdep->ppc_acc_regnum,
+                          &speregset->acc);
+ 
+   if (regnum == tdep->ppc_spefscr_regnum
+       || regnum == -1)
+     regcache_raw_supply (regcache, tdep->ppc_spefscr_regnum,
+                          &speregset->spefscr);
+ }
+ 
+ static void
+ ppc_linux_collect_speregset (const struct regset *regset,
+                              const struct regcache *regcache,
+                              int regnum,
+                              void *buf,
+                              size_t len)
+ {
+   struct gdbarch *arch = get_regcache_arch (regcache);
+   struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
+   struct speregset *speregset = buf;
+ 
+   gdb_assert (len == sizeof (*speregset));
+   gdb_assert (register_size (arch, tdep->ppc_ev0_regnum)
+               == sizeof (speregset->gpr[0]));
+   gdb_assert (register_size (arch, tdep->ppc_acc_regnum)
+               == sizeof (speregset->acc));
+   gdb_assert (register_size (arch, tdep->ppc_spefscr_regnum)
+               == sizeof (speregset->spefscr));
+ 
+   if (regnum == -1)
+     {
+       int i;
+ 
+       for (i = 0; i < 32; i++)
+         regcache_raw_collect (regcache, tdep->ppc_ev0_regnum + i,
+                               &speregset->gpr[i]);
+     }
+   else if (tdep->ppc_ev0_regnum <= regnum
+            && regnum <= tdep->ppc_ev31_regnum)
+     regcache_raw_collect (regcache, regnum,
+                           &speregset->gpr[regnum - tdep->ppc_ev0_regnum]);
+ 
+   if (regnum == tdep->ppc_acc_regnum
+       || regnum == -1)
+     regcache_raw_collect (regcache, tdep->ppc_acc_regnum, &speregset->acc);
+     
+   if (regnum == tdep->ppc_spefscr_regnum
+       || regnum == -1)
+     regcache_raw_collect (regcache, tdep->ppc_spefscr_regnum,
+                           &speregset->spefscr);
+ }
+ 
+ static const struct regset ppc_linux_speregset =
+ {
+   0,
+   ppc_linux_supply_speregset,
+   ppc_linux_collect_speregset
+ };
+ 
+ static void
  ppc_linux_init_abi (struct gdbarch_info info,
                      struct gdbarch *gdbarch)
  {
*************** ppc_linux_init_abi (struct gdbarch_info 
*** 1092,1097 ****
--- 1185,1202 ----
        set_solib_svr4_fetch_link_map_offsets
          (gdbarch, ppc_linux_svr4_fetch_link_map_offsets);
      }
+ 
+   if (info.bfd_arch_info->arch == bfd_arch_powerpc
+       && info.bfd_arch_info->mach == bfd_mach_ppc_e500)
+     {
+       /* On the e500, the GPR's are really 64 bits long.  However, we
+          continue to treat the gpr's as if they were 32 bits long, and
+          handle the upper haves separately.  This means that we need a
+          special way to pass the upper halves through thread_db.  */
+       set_gdbarch_xregs_regset (gdbarch, &ppc_linux_speregset);
+       set_gdbarch_xregs_size (gdbarch, sizeof (struct speregset));
+       set_gdbarch_xregs_name (gdbarch, "SPE vector");
+     }
    
    if (tdep->wordsize == 8)
      {
Index: gdb/ppc-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/ppc-tdep.h,v
retrieving revision 1.45
diff -c -p -r1.45 ppc-tdep.h
*** gdb/ppc-tdep.h	4 Aug 2004 17:17:55 -0000	1.45
--- gdb/ppc-tdep.h	12 Aug 2004 23:15:12 -0000
*************** enum
*** 373,376 ****
--- 373,388 ----
      ppc_spr_pbu2      = 1023
    };
  
+ 
+ /* The ABI for Motorola's PowerPC Signal Processing Extension (SPE)
+    APU specifies this structure for holding SPE registers in core files.
+ 
+    At the moment, the kernel doesn't actually dump these, but we use
+    this for passing those registers through libthread_db.  */
+ struct speregset {
+   unsigned char gpr[32][8]; /* The full 64-bit general-purpose registers  */ 
+   unsigned char acc[8];     /* accumulator */
+   unsigned char spefscr[4]; /* SPR 512: SPE float status control reg */
+ };
+ 
  #endif
Index: gdb/ppc-linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-nat.c,v
retrieving revision 1.52
diff -c -p -r1.52 ppc-linux-nat.c
*** gdb/ppc-linux-nat.c	4 Aug 2004 17:45:30 -0000	1.52
--- gdb/ppc-linux-nat.c	12 Aug 2004 23:15:10 -0000
*************** typedef char gdb_vrregset_t[SIZEOF_VRREG
*** 129,135 ****
     bottom halves together.
  
     This is the structure filled in by PTRACE_GETEVRREGS and written to
!    the inferior's registers by PTRACE_SETEVRREGS.  */
  struct gdb_evrregset_t
  {
    unsigned long evr[32];
--- 129,140 ----
     bottom halves together.
  
     This is the structure filled in by PTRACE_GETEVRREGS and written to
!    the inferior's registers by PTRACE_SETEVRREGS.
! 
!    Note that this is not the same as 'struct speregset', which
!    describes how the ABI says the kernel dumps SPE-style 64-bit GPR's
!    in core files.  It would be nicer if PTRACE_{GET,SET}EVRREGS and
!    core files used the same layout, but they don't.  */
  struct gdb_evrregset_t
  {
    unsigned long evr[32];
Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.607
diff -c -p -r1.607 Makefile.in
*** gdb/Makefile.in	8 Aug 2004 19:27:09 -0000	1.607
--- gdb/Makefile.in	12 Aug 2004 23:15:06 -0000
*************** ppc-linux-nat.o: ppc-linux-nat.c $(defs_
*** 2279,2285 ****
  ppc-linux-tdep.o: ppc-linux-tdep.c $(defs_h) $(frame_h) $(inferior_h) \
  	$(symtab_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(symfile_h) \
  	$(objfiles_h) $(regcache_h) $(value_h) $(osabi_h) $(regset_h) \
! 	$(solib_svr4_h) $(ppc_tdep_h) $(trad_frame_h) $(frame_unwind_h)
  ppcnbsd-nat.o: ppcnbsd-nat.c $(defs_h) $(inferior_h) $(gdb_assert_h) \
  	$(ppc_tdep_h) $(ppcnbsd_tdep_h) $(gdbcore.h) $(regcache_h) \
  	$(bsd_kvm_h)
--- 2279,2286 ----
  ppc-linux-tdep.o: ppc-linux-tdep.c $(defs_h) $(frame_h) $(inferior_h) \
  	$(symtab_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(symfile_h) \
  	$(objfiles_h) $(regcache_h) $(value_h) $(osabi_h) $(regset_h) \
! 	$(solib_svr4_h) $(ppc_tdep_h) $(trad_frame_h) $(frame_unwind_h) \
! 	$(gdb_assert_h)
  ppcnbsd-nat.o: ppcnbsd-nat.c $(defs_h) $(inferior_h) $(gdb_assert_h) \
  	$(ppc_tdep_h) $(ppcnbsd_tdep_h) $(gdbcore.h) $(regcache_h) \
  	$(bsd_kvm_h)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]