From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 835 invoked by alias); 11 Apr 2002 19:17:31 -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 816 invoked from network); 11 Apr 2002 19:17:25 -0000 Received: from unknown (HELO cygnus.com) (205.180.230.5) by sources.redhat.com with SMTP; 11 Apr 2002 19:17:25 -0000 Received: from romulus.sfbay.redhat.com (romulus.sfbay.redhat.com [172.16.27.251]) by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id MAA21906 for ; Thu, 11 Apr 2002 12:17:23 -0700 (PDT) Received: (from kev@localhost) by romulus.sfbay.redhat.com (8.11.6/8.11.6) id g3BJH6703110 for gdb-patches@sources.redhat.com; Thu, 11 Apr 2002 12:17:06 -0700 Date: Thu, 11 Apr 2002 12:17:00 -0000 From: Kevin Buettner Message-Id: <1020411191706.ZM3109@localhost.localdomain> To: gdb-patches@sources.redhat.com Subject: [PATCH] Add support for fpscr for Power / PowerPC targets MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2002-04/txt/msg00423.txt.bz2 I've just committed the patch below. It adds support for the fpscr register for Power and PowerPC targets. I've tested this patch on GNU/Linux/PPC (native). For PowerPC, the fpscr regnum is 70, which was an unused slot. For Power, I chose to use the first available slot (71). The other change that this patch makes is to make MQ unavailable for all PowerPC targets except for the 601 processors (which is as it should be). * ppc-tdep.h (struct gdbarch_tdep): Add new field ``ppc_fpscr_regnum''. * ppc-bdm.c (bdm_ppc_fetch_registers, bdm_ppc_store_registers): Add fpscr as an invalid/unfetchable register. * ppc-linux-nat.c (ppc_register_u_addr, store_register) (fetch_ppc_registers, store_ppc_registers, supply_fpregset) (fill_fpregset): Add support for register fpscr. (fetch_ppc_registers, store_ppc_registers, supply_gregset) (fill_gregset): Account for the fact that register ``mq'' might not exist. * rs6000-tdep.c (PPC_UISA_SPRS): Use (unused) slot 70 for fpscr. (registers_power): Add fpscr to register set at slot 71. (rs6000_gdbarch_init): Account for the fact that ``mq'' doesn't exist on most PPC architectures. Initialize ppc_fpscr_regnum. Index: ppc-bdm.c =================================================================== RCS file: /cvs/src/src/gdb/ppc-bdm.c,v retrieving revision 1.12 diff -u -p -r1.12 ppc-bdm.c --- ppc-bdm.c 9 Dec 2001 21:39:53 -0000 1.12 +++ ppc-bdm.c 11 Apr 2002 08:34:35 -0000 @@ -201,6 +201,7 @@ bdm_ppc_fetch_registers (int regno) /* if asking for an invalid register */ if ((first_regno == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum) + || (first_regno == gdbarch_tdep (current_gdbarch)->fpscr_regnum) || ((first_regno >= FP0_REGNUM) && (first_regno <= FPLAST_REGNUM))) { /* printf("invalid reg request!\n"); */ @@ -289,7 +290,9 @@ bdm_ppc_store_registers (int regno) /* only attempt to write if it's a valid ppc 8xx register */ /* (need to avoid FP regs and MQ reg) */ - if ((i != gdbarch_tdep (current_gdbarch)->ppc_mq_regnum) && ((i < FP0_REGNUM) || (i > FPLAST_REGNUM))) + if ((i != gdbarch_tdep (current_gdbarch)->ppc_mq_regnum) + && (i != gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum) + && ((i < FP0_REGNUM) || (i > FPLAST_REGNUM))) { /* printf("write valid reg %d\n", bdm_regno); */ ocd_write_bdm_registers (bdm_regno, registers + REGISTER_BYTE (i), 4); Index: ppc-linux-nat.c =================================================================== RCS file: /cvs/src/src/gdb/ppc-linux-nat.c,v retrieving revision 1.16 diff -u -p -r1.16 ppc-linux-nat.c --- ppc-linux-nat.c 21 Feb 2002 22:04:46 -0000 1.16 +++ ppc-linux-nat.c 11 Apr 2002 08:34:36 -0000 @@ -149,6 +149,8 @@ ppc_register_u_addr (int regno) u_addr = PT_MQ * 4; if (regno == tdep->ppc_ps_regnum) u_addr = PT_MSR * 4; + if (regno == tdep->ppc_fpscr_regnum) + u_addr = PT_FPSCR * 4; return u_addr; } @@ -290,8 +292,10 @@ fetch_ppc_registers (int tid) int i; struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - for (i = 0; i <= tdep->ppc_mq_regnum; i++) + for (i = 0; i <= tdep->ppc_fpscr_regnum; i++) fetch_register (tid, i); + if (tdep->ppc_mq_regnum != -1) + fetch_register (tid, tdep->ppc_mq_regnum); if (have_ptrace_getvrregs) if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1) fetch_altivec_registers (tid); @@ -376,6 +380,14 @@ store_register (int tid, int regno) ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr, *(PTRACE_XFER_TYPE *) & buf[i]); regaddr += sizeof (PTRACE_XFER_TYPE); + + if (errno == EIO + && regno == gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum) + { + /* Some older kernel versions don't allow fpscr to be written. */ + continue; + } + if (errno != 0) { sprintf (mess, "writing register %s (#%d)", @@ -435,8 +447,10 @@ store_ppc_registers (int tid) int i; struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - for (i = 0; i <= tdep->ppc_mq_regnum; i++) + for (i = 0; i <= tdep->ppc_fpscr_regnum; i++) store_register (tid, i); + if (tdep->ppc_mq_regnum != -1) + store_register (tid, tdep->ppc_mq_regnum); if (have_ptrace_getvrregs) if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1) store_altivec_registers (tid); @@ -473,7 +487,8 @@ supply_gregset (gdb_gregset_t *gregsetp) supply_register (tdep->ppc_cr_regnum, (char *) (regp + PT_CCR)); supply_register (tdep->ppc_xer_regnum, (char *) (regp + PT_XER)); supply_register (tdep->ppc_ctr_regnum, (char *) (regp + PT_CTR)); - supply_register (tdep->ppc_mq_regnum, (char *) (regp + PT_MQ)); + if (tdep->ppc_mq_regnum != -1) + supply_register (tdep->ppc_mq_regnum, (char *) (regp + PT_MQ)); supply_register (tdep->ppc_ps_regnum, (char *) (regp + PT_MSR)); } @@ -500,7 +515,8 @@ fill_gregset (gdb_gregset_t *gregsetp, i regcache_collect (tdep->ppc_xer_regnum, regp + PT_XER); if ((regno == -1) || regno == tdep->ppc_ctr_regnum) regcache_collect (tdep->ppc_ctr_regnum, regp + PT_CTR); - if ((regno == -1) || regno == tdep->ppc_mq_regnum) + if (((regno == -1) || regno == tdep->ppc_mq_regnum) + && (tdep->ppc_mq_regnum != -1)) regcache_collect (tdep->ppc_mq_regnum, regp + PT_MQ); if ((regno == -1) || regno == tdep->ppc_ps_regnum) regcache_collect (tdep->ppc_ps_regnum, regp + PT_MSR); @@ -510,9 +526,11 @@ void supply_fpregset (gdb_fpregset_t * fpregsetp) { int regi; + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); for (regi = 0; regi < 32; regi++) supply_register (FP0_REGNUM + regi, (char *) (*fpregsetp + regi)); + supply_register (tdep->ppc_fpscr_regnum, (char *) (*fpregsetp + 32)); } /* Given a pointer to a floating point register set in /proc format @@ -523,10 +541,13 @@ void fill_fpregset (gdb_fpregset_t *fpregsetp, int regno) { int regi; + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); for (regi = 0; regi < 32; regi++) { if ((regno == -1) || (regno == FP0_REGNUM + regi)) regcache_collect (FP0_REGNUM + regi, (char *) (*fpregsetp + regi)); } + if ((regno == -1) || regno == tdep->ppc_fpscr_regnum) + regcache_collect (tdep->ppc_fpscr_regnum, (char *) (*fpregsetp + regi)); } Index: ppc-tdep.h =================================================================== RCS file: /cvs/src/src/gdb/ppc-tdep.h,v retrieving revision 1.7 diff -u -p -r1.7 ppc-tdep.h --- ppc-tdep.h 22 Mar 2002 21:58:16 -0000 1.7 +++ ppc-tdep.h 11 Apr 2002 08:34:36 -0000 @@ -62,6 +62,8 @@ struct gdbarch_tdep int ppc_lr_regnum; /* Link register */ int ppc_ctr_regnum; /* Count register */ int ppc_xer_regnum; /* Integer exception register */ + int ppc_fpscr_regnum; /* Floating point status and condition + register */ int ppc_mq_regnum; /* Multiply/Divide extension register */ int ppc_vr0_regnum; /* First AltiVec register */ int ppc_vrsave_regnum; /* Last AltiVec register */ Index: rs6000-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v retrieving revision 1.49 diff -u -p -r1.49 rs6000-tdep.c --- rs6000-tdep.c 9 Apr 2002 02:26:10 -0000 1.49 +++ rs6000-tdep.c 11 Apr 2002 08:34:40 -0000 @@ -2075,7 +2075,7 @@ rs6000_convert_from_func_ptr_addr (CORE_ /* UISA-level SPRs for PowerPC. */ #define PPC_UISA_SPRS \ - /* 66 */ R4(cr), R(lr), R(ctr), R4(xer), R0 + /* 66 */ R4(cr), R(lr), R(ctr), R4(xer), R4(fpscr) /* Segment registers, for PowerPC. */ #define PPC_SEGMENT_REGS \ @@ -2109,7 +2109,8 @@ rs6000_convert_from_func_ptr_addr (CORE_ static const struct reg registers_power[] = { COMMON_UISA_REGS, - /* 66 */ R4(cnd), R(lr), R(cnt), R4(xer), R4(mq) + /* 66 */ R4(cnd), R(lr), R(cnt), R4(xer), R4(mq), + /* 71 */ R4(fpscr) }; /* PowerPC UISA - a PPC processor as viewed by user-level code. A UISA-only @@ -2547,8 +2548,11 @@ rs6000_gdbarch_init (struct gdbarch_info tdep->ppc_xer_regnum = 69; if (v->mach == bfd_mach_ppc_601) tdep->ppc_mq_regnum = 124; - else + else if (power) tdep->ppc_mq_regnum = 70; + else + tdep->ppc_mq_regnum = -1; + tdep->ppc_fpscr_regnum = power ? 71 : 70; if (v->arch == bfd_arch_powerpc) switch (v->mach)