From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12470 invoked by alias); 12 Aug 2004 23:40:34 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 12462 invoked from network); 12 Aug 2004 23:40:32 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org with SMTP; 12 Aug 2004 23:40:32 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i7CNeWe1029389 for ; Thu, 12 Aug 2004 19:40:32 -0400 Received: from zenia.home.redhat.com (porkchop.devel.redhat.com [172.16.58.2]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i7CNeOa07010; Thu, 12 Aug 2004 19:40:24 -0400 To: gdb-patches@sources.redhat.com Subject: RFA: Define PowerPC E500 SPE xregset From: Jim Blandy Date: Thu, 12 Aug 2004 23:40:00 -0000 Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2004-08/txt/msg00478.txt.bz2 This patch depends on the patch I just posted to implement the generic libthread_db xregs functions. 2004-06-08 Jim Blandy 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)