X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Frs6000-tdep.c;h=08f926e91f637a0eeccbb08415e7ce37162957aa;hb=5062cc192edb3e057e7f0c8c22d7b806077df307;hp=e095626968a7a7fe3d56117a2764521bebf22a44;hpb=0fd88904d91d1a137779cd5da6dc9d223fa88d14;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index e095626968..08f926e91f 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -1,14 +1,14 @@ /* Target-dependent code for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software - Foundation, Inc. + Copyright (C) 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, + 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,9 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ #include "defs.h" #include "frame.h" @@ -40,6 +38,9 @@ #include "sim-regno.h" #include "gdb/sim-ppc.h" #include "reggroups.h" +#include "dwarf2-frame.h" +#include "target-descriptions.h" +#include "user-regs.h" #include "libbfd.h" /* for bfd_default_set_arch_mach */ #include "coff/internal.h" /* for libcoff.h */ @@ -48,6 +49,7 @@ #include "libxcoff.h" #include "elf-bfd.h" +#include "elf/ppc.h" #include "solib-svr4.h" #include "ppc-tdep.h" @@ -59,18 +61,53 @@ #include "frame-unwind.h" #include "frame-base.h" -#include "reggroups.h" +#include "features/rs6000/powerpc-32.c" +#include "features/rs6000/powerpc-altivec32.c" +#include "features/rs6000/powerpc-403.c" +#include "features/rs6000/powerpc-403gc.c" +#include "features/rs6000/powerpc-505.c" +#include "features/rs6000/powerpc-601.c" +#include "features/rs6000/powerpc-602.c" +#include "features/rs6000/powerpc-603.c" +#include "features/rs6000/powerpc-604.c" +#include "features/rs6000/powerpc-64.c" +#include "features/rs6000/powerpc-altivec64.c" +#include "features/rs6000/powerpc-7400.c" +#include "features/rs6000/powerpc-750.c" +#include "features/rs6000/powerpc-860.c" +#include "features/rs6000/powerpc-e500.c" +#include "features/rs6000/rs6000.c" + +/* Determine if regnum is an SPE pseudo-register. */ +#define IS_SPE_PSEUDOREG(tdep, regnum) ((tdep)->ppc_ev0_regnum >= 0 \ + && (regnum) >= (tdep)->ppc_ev0_regnum \ + && (regnum) < (tdep)->ppc_ev0_regnum + 32) + +/* Determine if regnum is a decimal float pseudo-register. */ +#define IS_DFP_PSEUDOREG(tdep, regnum) ((tdep)->ppc_dl0_regnum >= 0 \ + && (regnum) >= (tdep)->ppc_dl0_regnum \ + && (regnum) < (tdep)->ppc_dl0_regnum + 16) + +/* The list of available "set powerpc ..." and "show powerpc ..." + commands. */ +static struct cmd_list_element *setpowerpccmdlist = NULL; +static struct cmd_list_element *showpowerpccmdlist = NULL; + +static enum auto_boolean powerpc_soft_float_global = AUTO_BOOLEAN_AUTO; + +/* The vector ABI to use. Keep this in sync with powerpc_vector_abi. */ +static const char *powerpc_vector_strings[] = +{ + "auto", + "generic", + "altivec", + "spe", + NULL +}; -/* If the kernel has to deliver a signal, it pushes a sigcontext - structure on the stack and then calls the signal handler, passing - the address of the sigcontext in an argument register. Usually - the signal handler doesn't save this register, so we have to - access the sigcontext structure via an offset from the signal handler - frame. - The following constants were determined by experimentation on AIX 3.2. */ -#define SIG_FRAME_PC_OFFSET 96 -#define SIG_FRAME_LR_OFFSET 108 -#define SIG_FRAME_FP_OFFSET 284 +/* A variable that can be configured by the user. */ +static enum powerpc_vector_abi powerpc_vector_abi_global = POWERPC_VEC_AUTO; +static const char *powerpc_vector_abi_string = "auto"; /* To be used by skip_prologue. */ @@ -95,54 +132,12 @@ struct rs6000_framedata int vrsave_offset; /* offset of saved vrsave register */ }; -/* Description of a single register. */ - -struct reg - { - char *name; /* name of register */ - unsigned char sz32; /* size on 32-bit arch, 0 if nonextant */ - unsigned char sz64; /* size on 64-bit arch, 0 if nonextant */ - unsigned char fpr; /* whether register is floating-point */ - unsigned char pseudo; /* whether register is pseudo */ - int spr_num; /* PowerPC SPR number, or -1 if not an SPR. - This is an ISA SPR number, not a GDB - register number. */ - }; - -/* Breakpoint shadows for the single step instructions will be kept here. */ - -static struct sstep_breaks - { - /* Address, or 0 if this is not in use. */ - CORE_ADDR address; - /* Shadow contents. */ - char data[4]; - } -stepBreaks[2]; - -/* Hook for determining the TOC address when calling functions in the - inferior under AIX. The initialization code in rs6000-nat.c sets - this hook to point to find_toc_address. */ - -CORE_ADDR (*rs6000_find_toc_address_hook) (CORE_ADDR) = NULL; - -/* Hook to set the current architecture when starting a child process. - rs6000-nat.c sets this. */ - -void (*rs6000_set_host_arch_hook) (int) = NULL; - -/* Static function prototypes */ - -static CORE_ADDR branch_dest (int opcode, int instr, CORE_ADDR pc, - CORE_ADDR safety); -static CORE_ADDR skip_prologue (CORE_ADDR, CORE_ADDR, - struct rs6000_framedata *); /* Is REGNO an AltiVec register? Return 1 if so, 0 otherwise. */ int -altivec_register_p (int regno) +altivec_register_p (struct gdbarch *gdbarch, int regno) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (tdep->ppc_vr0_regnum < 0 || tdep->ppc_vrsave_regnum < 0) return 0; else @@ -152,14 +147,12 @@ altivec_register_p (int regno) /* Return true if REGNO is an SPE register, false otherwise. */ int -spe_register_p (int regno) +spe_register_p (struct gdbarch *gdbarch, int regno) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); /* Is it a reference to EV0 -- EV31, and do we have those? */ - if (tdep->ppc_ev0_regnum >= 0 - && tdep->ppc_ev31_regnum >= 0 - && tdep->ppc_ev0_regnum <= regno && regno <= tdep->ppc_ev31_regnum) + if (IS_SPE_PSEUDOREG (tdep, regno)) return 1; /* Is it a reference to one of the raw upper GPR halves? */ @@ -194,6 +187,16 @@ ppc_floating_point_unit_p (struct gdbarch *gdbarch) && tdep->ppc_fpscr_regnum >= 0); } +/* Return non-zero if the architecture described by GDBARCH has + Altivec registers (vr0 --- vr31, vrsave and vscr). */ +int +ppc_altivec_support_p (struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + return (tdep->ppc_vr0_regnum >= 0 + && tdep->ppc_vrsave_regnum >= 0); +} /* Check that TABLE[GDB_REGNO] is not already initialized, and then set it to SIM_REGNO. @@ -219,10 +222,13 @@ static void init_sim_regno_table (struct gdbarch *arch) { struct gdbarch_tdep *tdep = gdbarch_tdep (arch); - int total_regs = gdbarch_num_regs (arch) + gdbarch_num_pseudo_regs (arch); - const struct reg *regs = tdep->regs; + int total_regs = gdbarch_num_regs (arch); int *sim_regno = GDBARCH_OBSTACK_CALLOC (arch, total_regs, int); int i; + static const char *const segment_regs[] = { + "sr0", "sr1", "sr2", "sr3", "sr4", "sr5", "sr6", "sr7", + "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15" + }; /* Presume that all registers not explicitly mentioned below are unavailable from the sim. */ @@ -247,11 +253,14 @@ init_sim_regno_table (struct gdbarch *arch) set_sim_regno (sim_regno, tdep->ppc_cr_regnum, sim_ppc_cr_regnum); /* Segment registers. */ - if (tdep->ppc_sr0_regnum >= 0) - for (i = 0; i < ppc_num_srs; i++) - set_sim_regno (sim_regno, - tdep->ppc_sr0_regnum + i, - sim_ppc_sr0_regnum + i); + for (i = 0; i < ppc_num_srs; i++) + { + int gdb_regno; + + gdb_regno = user_reg_map_name_to_regnum (arch, segment_regs[i], -1); + if (gdb_regno >= 0) + set_sim_regno (sim_regno, gdb_regno, sim_ppc_sr0_regnum + i); + } /* Altivec registers. */ if (tdep->ppc_vr0_regnum >= 0) @@ -270,11 +279,6 @@ init_sim_regno_table (struct gdbarch *arch) /* vsave is a special-purpose register, so the code below handles it. */ /* SPE APU (E500) registers. */ - if (tdep->ppc_ev0_regnum >= 0) - for (i = 0; i < ppc_num_gprs; i++) - set_sim_regno (sim_regno, - tdep->ppc_ev0_regnum + i, - sim_ppc_ev0_regnum + i); if (tdep->ppc_ev0_upper_regnum >= 0) for (i = 0; i < ppc_num_gprs; i++) set_sim_regno (sim_regno, @@ -284,12 +288,22 @@ init_sim_regno_table (struct gdbarch *arch) set_sim_regno (sim_regno, tdep->ppc_acc_regnum, sim_ppc_acc_regnum); /* spefscr is a special-purpose register, so the code below handles it. */ +#ifdef WITH_SIM /* Now handle all special-purpose registers. Verify that they haven't mistakenly been assigned numbers by any of the above - code). */ - for (i = 0; i < total_regs; i++) - if (regs[i].spr_num >= 0) - set_sim_regno (sim_regno, i, regs[i].spr_num + sim_ppc_spr0_regnum); + code. */ + for (i = 0; i < sim_ppc_num_sprs; i++) + { + const char *spr_name = sim_spr_register_name (i); + int gdb_regno = -1; + + if (spr_name != NULL) + gdb_regno = user_reg_map_name_to_regnum (arch, spr_name, -1); + + if (gdb_regno != -1) + set_sim_regno (sim_regno, gdb_regno, sim_ppc_spr0_regnum + i); + } +#endif /* Drop the initialized array into place. */ tdep->sim_regno = sim_regno; @@ -299,12 +313,17 @@ init_sim_regno_table (struct gdbarch *arch) /* Given a GDB register number REG, return the corresponding SIM register number. */ static int -rs6000_register_sim_regno (int reg) +rs6000_register_sim_regno (struct gdbarch *gdbarch, int reg) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); int sim_regno; - gdb_assert (0 <= reg && reg <= NUM_REGS + NUM_PSEUDO_REGS); + if (tdep->sim_regno == NULL) + init_sim_regno_table (gdbarch); + + gdb_assert (0 <= reg + && reg <= gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch)); sim_regno = tdep->sim_regno[reg]; if (sim_regno >= 0) @@ -317,22 +336,127 @@ rs6000_register_sim_regno (int reg) /* Register set support functions. */ -static void +/* REGS + OFFSET contains register REGNUM in a field REGSIZE wide. + Write the register to REGCACHE. */ + +void ppc_supply_reg (struct regcache *regcache, int regnum, - const char *regs, size_t offset) + const gdb_byte *regs, size_t offset, int regsize) { if (regnum != -1 && offset != -1) - regcache_raw_supply (regcache, regnum, regs + offset); + { + if (regsize > 4) + { + struct gdbarch *gdbarch = get_regcache_arch (regcache); + int gdb_regsize = register_size (gdbarch, regnum); + if (gdb_regsize < regsize + && gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + offset += regsize - gdb_regsize; + } + regcache_raw_supply (regcache, regnum, regs + offset); + } } -static void +/* Read register REGNUM from REGCACHE and store to REGS + OFFSET + in a field REGSIZE wide. Zero pad as necessary. */ + +void ppc_collect_reg (const struct regcache *regcache, int regnum, - char *regs, size_t offset) + gdb_byte *regs, size_t offset, int regsize) { if (regnum != -1 && offset != -1) - regcache_raw_collect (regcache, regnum, regs + offset); + { + if (regsize > 4) + { + struct gdbarch *gdbarch = get_regcache_arch (regcache); + int gdb_regsize = register_size (gdbarch, regnum); + if (gdb_regsize < regsize) + { + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + { + memset (regs + offset, 0, regsize - gdb_regsize); + offset += regsize - gdb_regsize; + } + else + memset (regs + offset + regsize - gdb_regsize, 0, + regsize - gdb_regsize); + } + } + regcache_raw_collect (regcache, regnum, regs + offset); + } } +static int +ppc_greg_offset (struct gdbarch *gdbarch, + struct gdbarch_tdep *tdep, + const struct ppc_reg_offsets *offsets, + int regnum, + int *regsize) +{ + *regsize = offsets->gpr_size; + if (regnum >= tdep->ppc_gp0_regnum + && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs) + return (offsets->r0_offset + + (regnum - tdep->ppc_gp0_regnum) * offsets->gpr_size); + + if (regnum == gdbarch_pc_regnum (gdbarch)) + return offsets->pc_offset; + + if (regnum == tdep->ppc_ps_regnum) + return offsets->ps_offset; + + if (regnum == tdep->ppc_lr_regnum) + return offsets->lr_offset; + + if (regnum == tdep->ppc_ctr_regnum) + return offsets->ctr_offset; + + *regsize = offsets->xr_size; + if (regnum == tdep->ppc_cr_regnum) + return offsets->cr_offset; + + if (regnum == tdep->ppc_xer_regnum) + return offsets->xer_offset; + + if (regnum == tdep->ppc_mq_regnum) + return offsets->mq_offset; + + return -1; +} + +static int +ppc_fpreg_offset (struct gdbarch_tdep *tdep, + const struct ppc_reg_offsets *offsets, + int regnum) +{ + if (regnum >= tdep->ppc_fp0_regnum + && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs) + return offsets->f0_offset + (regnum - tdep->ppc_fp0_regnum) * 8; + + if (regnum == tdep->ppc_fpscr_regnum) + return offsets->fpscr_offset; + + return -1; +} + +static int +ppc_vrreg_offset (struct gdbarch_tdep *tdep, + const struct ppc_reg_offsets *offsets, + int regnum) +{ + if (regnum >= tdep->ppc_vr0_regnum + && regnum < tdep->ppc_vr0_regnum + ppc_num_vrs) + return offsets->vr0_offset + (regnum - tdep->ppc_vr0_regnum) * 16; + + if (regnum == tdep->ppc_vrsave_regnum - 1) + return offsets->vscr_offset; + + if (regnum == tdep->ppc_vrsave_regnum) + return offsets->vrsave_offset; + + return -1; +} + /* Supply register REGNUM in the general-purpose register set REGSET from the buffer specified by GREGS and LEN to register cache REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ @@ -345,35 +469,37 @@ ppc_supply_gregset (const struct regset *regset, struct regcache *regcache, struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); const struct ppc_reg_offsets *offsets = regset->descr; size_t offset; - int i; + int regsize; - for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset; - i < tdep->ppc_gp0_regnum + ppc_num_gprs; - i++, offset += 4) + if (regnum == -1) { - if (regnum == -1 || regnum == i) - ppc_supply_reg (regcache, i, gregs, offset); + int i; + int gpr_size = offsets->gpr_size; + + for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset; + i < tdep->ppc_gp0_regnum + ppc_num_gprs; + i++, offset += gpr_size) + ppc_supply_reg (regcache, i, gregs, offset, gpr_size); + + ppc_supply_reg (regcache, gdbarch_pc_regnum (gdbarch), + gregs, offsets->pc_offset, gpr_size); + ppc_supply_reg (regcache, tdep->ppc_ps_regnum, + gregs, offsets->ps_offset, gpr_size); + ppc_supply_reg (regcache, tdep->ppc_lr_regnum, + gregs, offsets->lr_offset, gpr_size); + ppc_supply_reg (regcache, tdep->ppc_ctr_regnum, + gregs, offsets->ctr_offset, gpr_size); + ppc_supply_reg (regcache, tdep->ppc_cr_regnum, + gregs, offsets->cr_offset, offsets->xr_size); + ppc_supply_reg (regcache, tdep->ppc_xer_regnum, + gregs, offsets->xer_offset, offsets->xr_size); + ppc_supply_reg (regcache, tdep->ppc_mq_regnum, + gregs, offsets->mq_offset, offsets->xr_size); + return; } - if (regnum == -1 || regnum == PC_REGNUM) - ppc_supply_reg (regcache, PC_REGNUM, gregs, offsets->pc_offset); - if (regnum == -1 || regnum == tdep->ppc_ps_regnum) - ppc_supply_reg (regcache, tdep->ppc_ps_regnum, - gregs, offsets->ps_offset); - if (regnum == -1 || regnum == tdep->ppc_cr_regnum) - ppc_supply_reg (regcache, tdep->ppc_cr_regnum, - gregs, offsets->cr_offset); - if (regnum == -1 || regnum == tdep->ppc_lr_regnum) - ppc_supply_reg (regcache, tdep->ppc_lr_regnum, - gregs, offsets->lr_offset); - if (regnum == -1 || regnum == tdep->ppc_ctr_regnum) - ppc_supply_reg (regcache, tdep->ppc_ctr_regnum, - gregs, offsets->ctr_offset); - if (regnum == -1 || regnum == tdep->ppc_xer_regnum) - ppc_supply_reg (regcache, tdep->ppc_xer_regnum, - gregs, offsets->cr_offset); - if (regnum == -1 || regnum == tdep->ppc_mq_regnum) - ppc_supply_reg (regcache, tdep->ppc_mq_regnum, gregs, offsets->mq_offset); + offset = ppc_greg_offset (gdbarch, tdep, offsets, regnum, ®size); + ppc_supply_reg (regcache, regnum, gregs, offset, regsize); } /* Supply register REGNUM in the floating-point register set REGSET @@ -385,29 +511,80 @@ ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache, int regnum, const void *fpregs, size_t len) { struct gdbarch *gdbarch = get_regcache_arch (regcache); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - const struct ppc_reg_offsets *offsets = regset->descr; + struct gdbarch_tdep *tdep; + const struct ppc_reg_offsets *offsets; size_t offset; - int i; - gdb_assert (ppc_floating_point_unit_p (gdbarch)); + if (!ppc_floating_point_unit_p (gdbarch)) + return; - offset = offsets->f0_offset; - for (i = tdep->ppc_fp0_regnum; - i < tdep->ppc_fp0_regnum + ppc_num_fprs; - i++, offset += 4) + tdep = gdbarch_tdep (gdbarch); + offsets = regset->descr; + if (regnum == -1) { - if (regnum == -1 || regnum == i) - ppc_supply_reg (regcache, i, fpregs, offset); + int i; + + for (i = tdep->ppc_fp0_regnum, offset = offsets->f0_offset; + i < tdep->ppc_fp0_regnum + ppc_num_fprs; + i++, offset += 8) + ppc_supply_reg (regcache, i, fpregs, offset, 8); + + ppc_supply_reg (regcache, tdep->ppc_fpscr_regnum, + fpregs, offsets->fpscr_offset, offsets->fpscr_size); + return; } - if (regnum == -1 || regnum == tdep->ppc_fpscr_regnum) - ppc_supply_reg (regcache, tdep->ppc_fpscr_regnum, - fpregs, offsets->fpscr_offset); + offset = ppc_fpreg_offset (tdep, offsets, regnum); + ppc_supply_reg (regcache, regnum, fpregs, offset, + regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8); +} + +/* Supply register REGNUM in the Altivec register set REGSET + from the buffer specified by VRREGS and LEN to register cache + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ + +void +ppc_supply_vrregset (const struct regset *regset, struct regcache *regcache, + int regnum, const void *vrregs, size_t len) +{ + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep; + const struct ppc_reg_offsets *offsets; + size_t offset; + + if (!ppc_altivec_support_p (gdbarch)) + return; + + tdep = gdbarch_tdep (gdbarch); + offsets = regset->descr; + if (regnum == -1) + { + int i; + + for (i = tdep->ppc_vr0_regnum, offset = offsets->vr0_offset; + i < tdep->ppc_vr0_regnum + ppc_num_vrs; + i++, offset += 16) + ppc_supply_reg (regcache, i, vrregs, offset, 16); + + ppc_supply_reg (regcache, (tdep->ppc_vrsave_regnum - 1), + vrregs, offsets->vscr_offset, 4); + + ppc_supply_reg (regcache, tdep->ppc_vrsave_regnum, + vrregs, offsets->vrsave_offset, 4); + return; + } + + offset = ppc_vrreg_offset (tdep, offsets, regnum); + if (regnum != tdep->ppc_vrsave_regnum + && regnum != tdep->ppc_vrsave_regnum - 1) + ppc_supply_reg (regcache, regnum, vrregs, offset, 16); + else + ppc_supply_reg (regcache, regnum, + vrregs, offset, 4); } /* Collect register REGNUM in the general-purpose register set - REGSET. from register cache REGCACHE into the buffer specified by + REGSET from register cache REGCACHE into the buffer specified by GREGS and LEN. If REGNUM is -1, do this for all registers in REGSET. */ @@ -420,41 +597,41 @@ ppc_collect_gregset (const struct regset *regset, struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); const struct ppc_reg_offsets *offsets = regset->descr; size_t offset; - int i; + int regsize; - offset = offsets->r0_offset; - for (i = tdep->ppc_gp0_regnum; - i < tdep->ppc_gp0_regnum + ppc_num_gprs; - i++, offset += 4) + if (regnum == -1) { - if (regnum == -1 || regnum == i) - ppc_collect_reg (regcache, i, gregs, offset); + int i; + int gpr_size = offsets->gpr_size; + + for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset; + i < tdep->ppc_gp0_regnum + ppc_num_gprs; + i++, offset += gpr_size) + ppc_collect_reg (regcache, i, gregs, offset, gpr_size); + + ppc_collect_reg (regcache, gdbarch_pc_regnum (gdbarch), + gregs, offsets->pc_offset, gpr_size); + ppc_collect_reg (regcache, tdep->ppc_ps_regnum, + gregs, offsets->ps_offset, gpr_size); + ppc_collect_reg (regcache, tdep->ppc_lr_regnum, + gregs, offsets->lr_offset, gpr_size); + ppc_collect_reg (regcache, tdep->ppc_ctr_regnum, + gregs, offsets->ctr_offset, gpr_size); + ppc_collect_reg (regcache, tdep->ppc_cr_regnum, + gregs, offsets->cr_offset, offsets->xr_size); + ppc_collect_reg (regcache, tdep->ppc_xer_regnum, + gregs, offsets->xer_offset, offsets->xr_size); + ppc_collect_reg (regcache, tdep->ppc_mq_regnum, + gregs, offsets->mq_offset, offsets->xr_size); + return; } - if (regnum == -1 || regnum == PC_REGNUM) - ppc_collect_reg (regcache, PC_REGNUM, gregs, offsets->pc_offset); - if (regnum == -1 || regnum == tdep->ppc_ps_regnum) - ppc_collect_reg (regcache, tdep->ppc_ps_regnum, - gregs, offsets->ps_offset); - if (regnum == -1 || regnum == tdep->ppc_cr_regnum) - ppc_collect_reg (regcache, tdep->ppc_cr_regnum, - gregs, offsets->cr_offset); - if (regnum == -1 || regnum == tdep->ppc_lr_regnum) - ppc_collect_reg (regcache, tdep->ppc_lr_regnum, - gregs, offsets->lr_offset); - if (regnum == -1 || regnum == tdep->ppc_ctr_regnum) - ppc_collect_reg (regcache, tdep->ppc_ctr_regnum, - gregs, offsets->ctr_offset); - if (regnum == -1 || regnum == tdep->ppc_xer_regnum) - ppc_collect_reg (regcache, tdep->ppc_xer_regnum, - gregs, offsets->xer_offset); - if (regnum == -1 || regnum == tdep->ppc_mq_regnum) - ppc_collect_reg (regcache, tdep->ppc_mq_regnum, - gregs, offsets->mq_offset); + offset = ppc_greg_offset (gdbarch, tdep, offsets, regnum, ®size); + ppc_collect_reg (regcache, regnum, gregs, offset, regsize); } /* Collect register REGNUM in the floating-point register set - REGSET. from register cache REGCACHE into the buffer specified by + REGSET from register cache REGCACHE into the buffer specified by FPREGS and LEN. If REGNUM is -1, do this for all registers in REGSET. */ @@ -464,233 +641,399 @@ ppc_collect_fpregset (const struct regset *regset, int regnum, void *fpregs, size_t len) { struct gdbarch *gdbarch = get_regcache_arch (regcache); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - const struct ppc_reg_offsets *offsets = regset->descr; + struct gdbarch_tdep *tdep; + const struct ppc_reg_offsets *offsets; size_t offset; - int i; - gdb_assert (ppc_floating_point_unit_p (gdbarch)); + if (!ppc_floating_point_unit_p (gdbarch)) + return; - offset = offsets->f0_offset; - for (i = tdep->ppc_fp0_regnum; - i <= tdep->ppc_fp0_regnum + ppc_num_fprs; - i++, offset += 4) + tdep = gdbarch_tdep (gdbarch); + offsets = regset->descr; + if (regnum == -1) { - if (regnum == -1 || regnum == i) - ppc_collect_reg (regcache, regnum, fpregs, offset); + int i; + + for (i = tdep->ppc_fp0_regnum, offset = offsets->f0_offset; + i < tdep->ppc_fp0_regnum + ppc_num_fprs; + i++, offset += 8) + ppc_collect_reg (regcache, i, fpregs, offset, 8); + + ppc_collect_reg (regcache, tdep->ppc_fpscr_regnum, + fpregs, offsets->fpscr_offset, offsets->fpscr_size); + return; } - if (regnum == -1 || regnum == tdep->ppc_fpscr_regnum) - ppc_collect_reg (regcache, tdep->ppc_fpscr_regnum, - fpregs, offsets->fpscr_offset); + offset = ppc_fpreg_offset (tdep, offsets, regnum); + ppc_collect_reg (regcache, regnum, fpregs, offset, + regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8); } - -/* Read a LEN-byte address from debugged memory address MEMADDR. */ +/* Collect register REGNUM in the Altivec register set + REGSET from register cache REGCACHE into the buffer specified by + VRREGS and LEN. If REGNUM is -1, do this for all registers in + REGSET. */ -static CORE_ADDR -read_memory_addr (CORE_ADDR memaddr, int len) +void +ppc_collect_vrregset (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *vrregs, size_t len) { - return read_memory_unsigned_integer (memaddr, len); + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep; + const struct ppc_reg_offsets *offsets; + size_t offset; + + if (!ppc_altivec_support_p (gdbarch)) + return; + + tdep = gdbarch_tdep (gdbarch); + offsets = regset->descr; + if (regnum == -1) + { + int i; + + for (i = tdep->ppc_vr0_regnum, offset = offsets->vr0_offset; + i < tdep->ppc_vr0_regnum + ppc_num_vrs; + i++, offset += 16) + ppc_collect_reg (regcache, i, vrregs, offset, 16); + + ppc_collect_reg (regcache, (tdep->ppc_vrsave_regnum - 1), + vrregs, offsets->vscr_offset, 4); + + ppc_collect_reg (regcache, tdep->ppc_vrsave_regnum, + vrregs, offsets->vrsave_offset, 4); + return; + } + + offset = ppc_vrreg_offset (tdep, offsets, regnum); + if (regnum != tdep->ppc_vrsave_regnum + && regnum != tdep->ppc_vrsave_regnum - 1) + ppc_collect_reg (regcache, regnum, vrregs, offset, 16); + else + ppc_collect_reg (regcache, regnum, + vrregs, offset, 4); } + -static CORE_ADDR -rs6000_skip_prologue (CORE_ADDR pc) +static int +insn_changes_sp_or_jumps (unsigned long insn) { - struct rs6000_framedata frame; - pc = skip_prologue (pc, 0, &frame); - return pc; -} + int opcode = (insn >> 26) & 0x03f; + int sd = (insn >> 21) & 0x01f; + int a = (insn >> 16) & 0x01f; + int subcode = (insn >> 1) & 0x3ff; + /* Changes the stack pointer. */ -/* Fill in fi->saved_regs */ + /* NOTE: There are many ways to change the value of a given register. + The ways below are those used when the register is R1, the SP, + in a funtion's epilogue. */ -struct frame_extra_info -{ - /* Functions calling alloca() change the value of the stack - pointer. We need to use initial stack pointer (which is saved in - r31 by gcc) in such cases. If a compiler emits traceback table, - then we should use the alloca register specified in traceback - table. FIXME. */ - CORE_ADDR initial_sp; /* initial stack pointer. */ -}; + if (opcode == 31 && subcode == 444 && a == 1) + return 1; /* mr R1,Rn */ + if (opcode == 14 && sd == 1) + return 1; /* addi R1,Rn,simm */ + if (opcode == 58 && sd == 1) + return 1; /* ld R1,ds(Rn) */ -/* Get the ith function argument for the current function. */ -static CORE_ADDR -rs6000_fetch_pointer_argument (struct frame_info *frame, int argi, - struct type *type) -{ - CORE_ADDR addr; - get_frame_register (frame, 3 + argi, &addr); - return addr; + /* Transfers control. */ + + if (opcode == 18) + return 1; /* b */ + if (opcode == 16) + return 1; /* bc */ + if (opcode == 19 && subcode == 16) + return 1; /* bclr */ + if (opcode == 19 && subcode == 528) + return 1; /* bcctr */ + + return 0; } -/* Calculate the destination of a branch/jump. Return -1 if not a branch. */ +/* Return true if we are in the function's epilogue, i.e. after the + instruction that destroyed the function's stack frame. + + 1) scan forward from the point of execution: + a) If you find an instruction that modifies the stack pointer + or transfers control (except a return), execution is not in + an epilogue, return. + b) Stop scanning if you find a return instruction or reach the + end of the function or reach the hard limit for the size of + an epilogue. + 2) scan backward from the point of execution: + a) If you find an instruction that modifies the stack pointer, + execution *is* in an epilogue, return. + b) Stop scanning if you reach an instruction that transfers + control or the beginning of the function or reach the hard + limit for the size of an epilogue. */ -static CORE_ADDR -branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety) +static int +rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) { - CORE_ADDR dest; - int immediate; - int absolute; - int ext_op; + bfd_byte insn_buf[PPC_INSN_SIZE]; + CORE_ADDR scan_pc, func_start, func_end, epilogue_start, epilogue_end; + unsigned long insn; + struct frame_info *curfrm; - absolute = (int) ((instr >> 1) & 1); + /* Find the search limits based on function boundaries and hard limit. */ - switch (opcode) - { - case 18: - immediate = ((instr & ~3) << 6) >> 6; /* br unconditional */ - if (absolute) - dest = immediate; - else - dest = pc + immediate; - break; + if (!find_pc_partial_function (pc, NULL, &func_start, &func_end)) + return 0; - case 16: - immediate = ((instr & ~3) << 16) >> 16; /* br conditional */ - if (absolute) - dest = immediate; - else - dest = pc + immediate; - break; + epilogue_start = pc - PPC_MAX_EPILOGUE_INSTRUCTIONS * PPC_INSN_SIZE; + if (epilogue_start < func_start) epilogue_start = func_start; - case 19: - ext_op = (instr >> 1) & 0x3ff; + epilogue_end = pc + PPC_MAX_EPILOGUE_INSTRUCTIONS * PPC_INSN_SIZE; + if (epilogue_end > func_end) epilogue_end = func_end; - if (ext_op == 16) /* br conditional register */ - { - dest = read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum) & ~3; + curfrm = get_current_frame (); - /* If we are about to return from a signal handler, dest is - something like 0x3c90. The current frame is a signal handler - caller frame, upon completion of the sigreturn system call - execution will return to the saved PC in the frame. */ - if (dest < TEXT_SEGMENT_BASE) - { - struct frame_info *fi; + /* Scan forward until next 'blr'. */ - fi = get_current_frame (); - if (fi != NULL) - dest = read_memory_addr (get_frame_base (fi) + SIG_FRAME_PC_OFFSET, - gdbarch_tdep (current_gdbarch)->wordsize); - } - } - - else if (ext_op == 528) /* br cond to count reg */ - { - dest = read_register (gdbarch_tdep (current_gdbarch)->ppc_ctr_regnum) & ~3; + for (scan_pc = pc; scan_pc < epilogue_end; scan_pc += PPC_INSN_SIZE) + { + if (!safe_frame_unwind_memory (curfrm, scan_pc, insn_buf, PPC_INSN_SIZE)) + return 0; + insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE); + if (insn == 0x4e800020) + break; + if (insn_changes_sp_or_jumps (insn)) + return 0; + } - /* If we are about to execute a system call, dest is something - like 0x22fc or 0x3b00. Upon completion the system call - will return to the address in the link register. */ - if (dest < TEXT_SEGMENT_BASE) - dest = read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum) & ~3; - } - else - return -1; - break; + /* Scan backward until adjustment to stack pointer (R1). */ - default: - return -1; + for (scan_pc = pc - PPC_INSN_SIZE; + scan_pc >= epilogue_start; + scan_pc -= PPC_INSN_SIZE) + { + if (!safe_frame_unwind_memory (curfrm, scan_pc, insn_buf, PPC_INSN_SIZE)) + return 0; + insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE); + if (insn_changes_sp_or_jumps (insn)) + return 1; } - return (dest < TEXT_SEGMENT_BASE) ? safety : dest; + + return 0; } +/* Get the ith function argument for the current function. */ +static CORE_ADDR +rs6000_fetch_pointer_argument (struct frame_info *frame, int argi, + struct type *type) +{ + return get_frame_register_unsigned (frame, 3 + argi); +} /* Sequence of bytes for breakpoint instruction. */ const static unsigned char * -rs6000_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size) +rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr, + int *bp_size) { static unsigned char big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 }; static unsigned char little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d }; *bp_size = 4; - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) return big_breakpoint; else return little_breakpoint; } +/* Instruction masks for displaced stepping. */ +#define BRANCH_MASK 0xfc000000 +#define BP_MASK 0xFC0007FE +#define B_INSN 0x48000000 +#define BC_INSN 0x40000000 +#define BXL_INSN 0x4c000000 +#define BP_INSN 0x7C000008 -/* AIX does not support PT_STEP. Simulate it. */ - +/* Fix up the state of registers and memory after having single-stepped + a displaced instruction. */ void -rs6000_software_single_step (enum target_signal signal, - int insert_breakpoints_p) -{ - CORE_ADDR dummy; - int breakp_sz; - const char *breakp = rs6000_breakpoint_from_pc (&dummy, &breakp_sz); - int ii, insn; - CORE_ADDR loc; - CORE_ADDR breaks[2]; - int opcode; - - if (insert_breakpoints_p) - { +ppc_displaced_step_fixup (struct gdbarch *gdbarch, + struct displaced_step_closure *closure, + CORE_ADDR from, CORE_ADDR to, + struct regcache *regs) +{ + /* Since we use simple_displaced_step_copy_insn, our closure is a + copy of the instruction. */ + ULONGEST insn = extract_unsigned_integer ((gdb_byte *) closure, + PPC_INSN_SIZE); + ULONGEST opcode = 0; + /* Offset for non PC-relative instructions. */ + LONGEST offset = PPC_INSN_SIZE; - loc = read_pc (); + opcode = insn & BRANCH_MASK; - insn = read_memory_integer (loc, 4); + if (debug_displaced) + fprintf_unfiltered (gdb_stdlog, + "displaced: (ppc) fixup (0x%s, 0x%s)\n", + paddr_nz (from), paddr_nz (to)); - breaks[0] = loc + breakp_sz; - opcode = insn >> 26; - breaks[1] = branch_dest (opcode, insn, loc, breaks[0]); - /* Don't put two breakpoints on the same address. */ - if (breaks[1] == breaks[0]) - breaks[1] = -1; + /* Handle PC-relative branch instructions. */ + if (opcode == B_INSN || opcode == BC_INSN || opcode == BXL_INSN) + { + ULONGEST current_pc; - stepBreaks[1].address = 0; + /* Read the current PC value after the instruction has been executed + in a displaced location. Calculate the offset to be applied to the + original PC value before the displaced stepping. */ + regcache_cooked_read_unsigned (regs, gdbarch_pc_regnum (gdbarch), + ¤t_pc); + offset = current_pc - to; - for (ii = 0; ii < 2; ++ii) + if (opcode != BXL_INSN) { - - /* ignore invalid breakpoint. */ - if (breaks[ii] == -1) - continue; - target_insert_breakpoint (breaks[ii], stepBreaks[ii].data); - stepBreaks[ii].address = breaks[ii]; + /* Check for AA bit indicating whether this is an absolute + addressing or PC-relative (1: absolute, 0: relative). */ + if (!(insn & 0x2)) + { + /* PC-relative addressing is being used in the branch. */ + if (debug_displaced) + fprintf_unfiltered + (gdb_stdlog, + "displaced: (ppc) branch instruction: 0x%s\n" + "displaced: (ppc) adjusted PC from 0x%s to 0x%s\n", + paddr_nz (insn), paddr_nz (current_pc), + paddr_nz (from + offset)); + + regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch), + from + offset); + } + } + else + { + /* If we're here, it means we have a branch to LR or CTR. If the + branch was taken, the offset is probably greater than 4 (the next + instruction), so it's safe to assume that an offset of 4 means we + did not take the branch. */ + if (offset == PPC_INSN_SIZE) + regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch), + from + PPC_INSN_SIZE); } + /* Check for LK bit indicating whether we should set the link + register to point to the next instruction + (1: Set, 0: Don't set). */ + if (insn & 0x1) + { + /* Link register needs to be set to the next instruction's PC. */ + regcache_cooked_write_unsigned (regs, + gdbarch_tdep (gdbarch)->ppc_lr_regnum, + from + PPC_INSN_SIZE); + if (debug_displaced) + fprintf_unfiltered (gdb_stdlog, + "displaced: (ppc) adjusted LR to 0x%s\n", + paddr_nz (from + PPC_INSN_SIZE)); + + } } + /* Check for breakpoints in the inferior. If we've found one, place the PC + right at the breakpoint instruction. */ + else if ((insn & BP_MASK) == BP_INSN) + regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch), from); else + /* Handle any other instructions that do not fit in the categories above. */ + regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch), + from + offset); +} + +/* Instruction masks used during single-stepping of atomic sequences. */ +#define LWARX_MASK 0xfc0007fe +#define LWARX_INSTRUCTION 0x7c000028 +#define LDARX_INSTRUCTION 0x7c0000A8 +#define STWCX_MASK 0xfc0007ff +#define STWCX_INSTRUCTION 0x7c00012d +#define STDCX_INSTRUCTION 0x7c0001ad + +/* Checks for an atomic sequence of instructions beginning with a LWARX/LDARX + instruction and ending with a STWCX/STDCX instruction. If such a sequence + is found, attempt to step through it. A breakpoint is placed at the end of + the sequence. */ + +int +ppc_deal_with_atomic_sequence (struct frame_info *frame) +{ + CORE_ADDR pc = get_frame_pc (frame); + CORE_ADDR breaks[2] = {-1, -1}; + CORE_ADDR loc = pc; + CORE_ADDR closing_insn; /* Instruction that closes the atomic sequence. */ + int insn = read_memory_integer (loc, PPC_INSN_SIZE); + int insn_count; + int index; + int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */ + const int atomic_sequence_length = 16; /* Instruction sequence length. */ + int opcode; /* Branch instruction's OPcode. */ + int bc_insn_count = 0; /* Conditional branch instruction count. */ + + /* Assume all atomic sequences start with a lwarx/ldarx instruction. */ + if ((insn & LWARX_MASK) != LWARX_INSTRUCTION + && (insn & LWARX_MASK) != LDARX_INSTRUCTION) + return 0; + + /* Assume that no atomic sequence is longer than "atomic_sequence_length" + instructions. */ + for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count) { + loc += PPC_INSN_SIZE; + insn = read_memory_integer (loc, PPC_INSN_SIZE); + + /* Assume that there is at most one conditional branch in the atomic + sequence. If a conditional branch is found, put a breakpoint in + its destination address. */ + if ((insn & BRANCH_MASK) == BC_INSN) + { + int immediate = ((insn & ~3) << 16) >> 16; + int absolute = ((insn >> 1) & 1); + + if (bc_insn_count >= 1) + return 0; /* More than one conditional branch found, fallback + to the standard single-step code. */ + + if (absolute) + breaks[1] = immediate; + else + breaks[1] = pc + immediate; + + bc_insn_count++; + last_breakpoint++; + } - /* remove step breakpoints. */ - for (ii = 0; ii < 2; ++ii) - if (stepBreaks[ii].address != 0) - target_remove_breakpoint (stepBreaks[ii].address, - stepBreaks[ii].data); + if ((insn & STWCX_MASK) == STWCX_INSTRUCTION + || (insn & STWCX_MASK) == STDCX_INSTRUCTION) + break; } - errno = 0; /* FIXME, don't ignore errors! */ - /* What errors? {read,write}_memory call error(). */ -} + /* Assume that the atomic sequence ends with a stwcx/stdcx instruction. */ + if ((insn & STWCX_MASK) != STWCX_INSTRUCTION + && (insn & STWCX_MASK) != STDCX_INSTRUCTION) + return 0; -/* return pc value after skipping a function prologue and also return - information about a function frame. + closing_insn = loc; + loc += PPC_INSN_SIZE; + insn = read_memory_integer (loc, PPC_INSN_SIZE); + + /* Insert a breakpoint right after the end of the atomic sequence. */ + breaks[0] = loc; + + /* Check for duplicated breakpoints. Check also for a breakpoint + placed (branch instruction's destination) at the stwcx/stdcx + instruction, this resets the reservation and take us back to the + lwarx/ldarx instruction at the beginning of the atomic sequence. */ + if (last_breakpoint && ((breaks[1] == breaks[0]) + || (breaks[1] == closing_insn))) + last_breakpoint = 0; + + /* Effectively inserts the breakpoints. */ + for (index = 0; index <= last_breakpoint; index++) + insert_single_step_breakpoint (breaks[index]); + + return 1; +} - in struct rs6000_framedata fdata: - - frameless is TRUE, if function does not have a frame. - - nosavedpc is TRUE, if function does not save %pc value in its frame. - - offset is the initial size of this stack frame --- the amount by - which we decrement the sp to allocate the frame. - - saved_gpr is the number of the first saved gpr. - - saved_fpr is the number of the first saved fpr. - - saved_vr is the number of the first saved vr. - - saved_ev is the number of the first saved ev. - - alloca_reg is the number of the register used for alloca() handling. - Otherwise -1. - - gpr_offset is the offset of the first saved gpr from the previous frame. - - fpr_offset is the offset of the first saved fpr from the previous frame. - - vr_offset is the offset of the first saved vr from the previous frame. - - ev_offset is the offset of the first saved ev from the previous frame. - - lr_offset is the offset of the saved lr - - cr_offset is the offset of the saved cr - - vrsave_offset is the offset of the saved vrsave register - */ #define SIGNED_SHORT(x) \ ((sizeof (short) == 2) \ @@ -703,57 +1046,6 @@ rs6000_software_single_step (enum target_signal signal, of the prologue is expensive. */ static int max_skip_non_prologue_insns = 10; -/* Given PC representing the starting address of a function, and - LIM_PC which is the (sloppy) limit to which to scan when looking - for a prologue, attempt to further refine this limit by using - the line data in the symbol table. If successful, a better guess - on where the prologue ends is returned, otherwise the previous - value of lim_pc is returned. */ - -/* FIXME: cagney/2004-02-14: This function and logic have largely been - superseded by skip_prologue_using_sal. */ - -static CORE_ADDR -refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc) -{ - struct symtab_and_line prologue_sal; - - prologue_sal = find_pc_line (pc, 0); - if (prologue_sal.line != 0) - { - int i; - CORE_ADDR addr = prologue_sal.end; - - /* Handle the case in which compiler's optimizer/scheduler - has moved instructions into the prologue. We scan ahead - in the function looking for address ranges whose corresponding - line number is less than or equal to the first one that we - found for the function. (It can be less than when the - scheduler puts a body instruction before the first prologue - instruction.) */ - for (i = 2 * max_skip_non_prologue_insns; - i > 0 && (lim_pc == 0 || addr < lim_pc); - i--) - { - struct symtab_and_line sal; - - sal = find_pc_line (addr, 0); - if (sal.line == 0) - break; - if (sal.line <= prologue_sal.line - && sal.symtab == prologue_sal.symtab) - { - prologue_sal = sal; - } - addr = sal.end; - } - - if (lim_pc == 0 || prologue_sal.end < lim_pc) - lim_pc = prologue_sal.end; - } - return lim_pc; -} - /* Return nonzero if the given instruction OP can be part of the prologue of a function and saves a parameter on the stack. FRAMEP should be set if one of the previous instructions in the function has set the @@ -825,13 +1117,66 @@ store_param_on_stack_p (unsigned long op, int framep, int *r0_contains_arg) return 0; } +/* Assuming that INSN is a "bl" instruction located at PC, return + nonzero if the destination of the branch is a "blrl" instruction. + + This sequence is sometimes found in certain function prologues. + It allows the function to load the LR register with a value that + they can use to access PIC data using PC-relative offsets. */ + +static int +bl_to_blrl_insn_p (CORE_ADDR pc, int insn) +{ + CORE_ADDR dest; + int immediate; + int absolute; + int dest_insn; + + absolute = (int) ((insn >> 1) & 1); + immediate = ((insn & ~3) << 6) >> 6; + if (absolute) + dest = immediate; + else + dest = pc + immediate; + + dest_insn = read_memory_integer (dest, 4); + if ((dest_insn & 0xfc00ffff) == 0x4c000021) /* blrl */ + return 1; + + return 0; +} + +/* return pc value after skipping a function prologue and also return + information about a function frame. + + in struct rs6000_framedata fdata: + - frameless is TRUE, if function does not have a frame. + - nosavedpc is TRUE, if function does not save %pc value in its frame. + - offset is the initial size of this stack frame --- the amount by + which we decrement the sp to allocate the frame. + - saved_gpr is the number of the first saved gpr. + - saved_fpr is the number of the first saved fpr. + - saved_vr is the number of the first saved vr. + - saved_ev is the number of the first saved ev. + - alloca_reg is the number of the register used for alloca() handling. + Otherwise -1. + - gpr_offset is the offset of the first saved gpr from the previous frame. + - fpr_offset is the offset of the first saved fpr from the previous frame. + - vr_offset is the offset of the first saved vr from the previous frame. + - ev_offset is the offset of the first saved ev from the previous frame. + - lr_offset is the offset of the saved lr + - cr_offset is the offset of the saved cr + - vrsave_offset is the offset of the saved vrsave register + */ + static CORE_ADDR -skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) +skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, + struct rs6000_framedata *fdata) { CORE_ADDR orig_pc = pc; CORE_ADDR last_prologue_pc = pc; CORE_ADDR li_found_pc = 0; - char buf[4]; + gdb_byte buf[4]; unsigned long op; long offset = 0; long vr_saved_offset = 0; @@ -847,23 +1192,8 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) int prev_insn_was_prologue_insn = 1; int num_skip_non_prologue_insns = 0; int r0_contains_arg = 0; - const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (current_gdbarch); - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - - /* Attempt to find the end of the prologue when no limit is specified. - Note that refine_prologue_limit() has been written so that it may - be used to "refine" the limits of non-zero PC values too, but this - is only safe if we 1) trust the line information provided by the - compiler and 2) iterate enough to actually find the end of the - prologue. - - It may become a good idea at some point (for both performance and - accuracy) to unconditionally call refine_prologue_limit(). But, - until we can make a clear determination that this is beneficial, - we'll play it safe and only use it to obtain a limit when none - has been specified. */ - if (lim_pc == 0) - lim_pc = refine_prologue_limit (pc, lim_pc); + const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); memset (fdata, 0, sizeof (struct rs6000_framedata)); fdata->saved_gpr = -1; @@ -884,7 +1214,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) last_prologue_pc = pc; /* Stop scanning if we've hit the limit. */ - if (lim_pc != 0 && pc >= lim_pc) + if (pc >= lim_pc) break; prev_insn_was_prologue_insn = 1; @@ -892,7 +1222,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) /* Fetch the instruction and convert it to an integer. */ if (target_read_memory (pc, buf, 4)) break; - op = extract_signed_integer (buf, 4); + op = extract_unsigned_integer (buf, 4); if ((op & 0xfc1fffff) == 0x7c0802a6) { /* mflr Rx */ @@ -913,7 +1243,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) remember just the first one, but skip over additional ones. */ - if (lr_reg < 0) + if (lr_reg == -1) lr_reg = (op & 0x03e00000); if (lr_reg == 0) r0_contains_arg = 0; @@ -1026,6 +1356,13 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) continue; } + else if ((op & 0xfe80ffff) == 0x42800005 && lr_reg != -1) + { + /* bcl 20,xx,.+4 is used to get the current PC, with or without + prediction bits. If the LR has already been saved, we can + skip it. */ + continue; + } else if (op == 0x48000005) { /* bl .+4 used in -mrelocatable */ @@ -1049,6 +1386,12 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) to save fprs??? */ fdata->frameless = 0; + + /* If the return address has already been saved, we can skip + calls to blrl (for PIC). */ + if (lr_reg != -1 && bl_to_blrl_insn_p (pc, op)) + continue; + /* Don't skip over the subroutine call if it is not within the first three instructions of the prologue and either we have no line table information or the line info tells @@ -1105,9 +1448,18 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) offset = fdata->offset; continue; } - /* Load up minimal toc pointer */ + else if ((op & 0xffff0000) == 0x38210000) + { /* addi r1,r1,SIMM */ + fdata->frameless = 0; + fdata->offset += SIGNED_SHORT (op); + offset = fdata->offset; + continue; + } + /* Load up minimal toc pointer. Do not treat an epilogue restore + of r31 as a minimal TOC load. */ else if (((op >> 22) == 0x20f || /* l r31,... or l r30,... */ (op >> 22) == 0x3af) /* ld r31,... or ld r30,... */ + && !framep && !minimal_toc_loaded) { minimal_toc_loaded = 1; @@ -1330,8 +1682,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) Handle optimizer code motions into the prologue by continuing the search if we have no valid frame yet or if the return address is not yet saved in the frame. */ - if (fdata->frameless == 0 - && (lr_reg == -1 || fdata->nosavedpc == 0)) + if (fdata->frameless == 0 && fdata->nosavedpc == 0) break; if (op == 0x4e800020 /* blr */ @@ -1388,324 +1739,42 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) return last_prologue_pc; } - -/************************************************************************* - Support for creating pushing a dummy frame into the stack, and popping - frames, etc. -*************************************************************************/ - - -/* All the ABI's require 16 byte alignment. */ static CORE_ADDR -rs6000_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) +rs6000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { - return (addr & -16); -} - -/* Pass the arguments in either registers, or in the stack. In RS/6000, - the first eight words of the argument list (that might be less than - eight parameters if some parameters occupy more than one word) are - passed in r3..r10 registers. float and double parameters are - passed in fpr's, in addition to that. Rest of the parameters if any - are passed in user stack. There might be cases in which half of the - parameter is copied into registers, the other half is pushed into - stack. - - Stack must be aligned on 64-bit boundaries when synthesizing - function calls. - - If the function is returning a structure, then the return address is passed - in r3, then the first 7 words of the parameters can be passed in registers, - starting from r4. */ - -static CORE_ADDR -rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function, - struct regcache *regcache, CORE_ADDR bp_addr, - int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) -{ - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - int ii; - int len = 0; - int argno; /* current argument number */ - int argbytes; /* current argument byte */ - char tmp_buffer[50]; - int f_argno = 0; /* current floating point argno */ - int wordsize = gdbarch_tdep (current_gdbarch)->wordsize; - CORE_ADDR func_addr = find_function_addr (function, NULL); - - struct value *arg = 0; - struct type *type; - - CORE_ADDR saved_sp; - - /* The calling convention this function implements assumes the - processor has floating-point registers. We shouldn't be using it - on PPC variants that lack them. */ - gdb_assert (ppc_floating_point_unit_p (current_gdbarch)); - - /* The first eight words of ther arguments are passed in registers. - Copy them appropriately. */ - ii = 0; - - /* If the function is returning a `struct', then the first word - (which will be passed in r3) is used for struct return address. - In that case we should advance one word and start from r4 - register to copy parameters. */ - if (struct_return) - { - regcache_raw_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3, - struct_addr); - ii++; - } - -/* - effectively indirect call... gcc does... - - return_val example( float, int); - - eabi: - float in fp0, int in r3 - offset of stack on overflow 8/16 - for varargs, must go by type. - power open: - float in r3&r4, int in r5 - offset of stack on overflow different - both: - return in r3 or f0. If no float, must study how gcc emulates floats; - pay attention to arg promotion. - User may have to cast\args to handle promotion correctly - since gdb won't know if prototype supplied or not. - */ + struct rs6000_framedata frame; + CORE_ADDR limit_pc, func_addr; - for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii) + /* See if we can determine the end of the prologue via the symbol table. + If so, then return either PC, or the PC after the prologue, whichever + is greater. */ + if (find_pc_partial_function (pc, NULL, &func_addr, NULL)) { - int reg_size = register_size (current_gdbarch, ii + 3); - - arg = args[argno]; - type = check_typedef (value_type (arg)); - len = TYPE_LENGTH (type); - - if (TYPE_CODE (type) == TYPE_CODE_FLT) - { - - /* Floating point arguments are passed in fpr's, as well as gpr's. - There are 13 fpr's reserved for passing parameters. At this point - there is no way we would run out of them. */ - - gdb_assert (len <= 8); - - regcache_cooked_write (regcache, - tdep->ppc_fp0_regnum + 1 + f_argno, - value_contents (arg)); - ++f_argno; - } - - if (len > reg_size) - { - - /* Argument takes more than one register. */ - while (argbytes < len) - { - char word[MAX_REGISTER_SIZE]; - memset (word, 0, reg_size); - memcpy (word, - ((char *) value_contents (arg)) + argbytes, - (len - argbytes) > reg_size - ? reg_size : len - argbytes); - regcache_cooked_write (regcache, - tdep->ppc_gp0_regnum + 3 + ii, - word); - ++ii, argbytes += reg_size; - - if (ii >= 8) - goto ran_out_of_registers_for_arguments; - } - argbytes = 0; - --ii; - } - else - { - /* Argument can fit in one register. No problem. */ - int adj = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? reg_size - len : 0; - char word[MAX_REGISTER_SIZE]; - - memset (word, 0, reg_size); - memcpy (word, value_contents (arg), len); - regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3 +ii, word); - } - ++argno; + CORE_ADDR post_prologue_pc = skip_prologue_using_sal (func_addr); + if (post_prologue_pc != 0) + return max (pc, post_prologue_pc); } -ran_out_of_registers_for_arguments: - - saved_sp = read_sp (); - - /* Location for 8 parameters are always reserved. */ - sp -= wordsize * 8; - - /* Another six words for back chain, TOC register, link register, etc. */ - sp -= wordsize * 6; - - /* Stack pointer must be quadword aligned. */ - sp &= -16; - - /* If there are more arguments, allocate space for them in - the stack, then push them starting from the ninth one. */ - - if ((argno < nargs) || argbytes) - { - int space = 0, jj; - - if (argbytes) - { - space += ((len - argbytes + 3) & -4); - jj = argno + 1; - } - else - jj = argno; - - for (; jj < nargs; ++jj) - { - struct value *val = args[jj]; - space += ((TYPE_LENGTH (value_type (val))) + 3) & -4; - } - - /* Add location required for the rest of the parameters. */ - space = (space + 15) & -16; - sp -= space; - - /* This is another instance we need to be concerned about - securing our stack space. If we write anything underneath %sp - (r1), we might conflict with the kernel who thinks he is free - to use this area. So, update %sp first before doing anything - else. */ - - regcache_raw_write_signed (regcache, SP_REGNUM, sp); - - /* If the last argument copied into the registers didn't fit there - completely, push the rest of it into stack. */ + /* Can't determine prologue from the symbol table, need to examine + instructions. */ - if (argbytes) - { - write_memory (sp + 24 + (ii * 4), - ((char *) value_contents (arg)) + argbytes, - len - argbytes); - ++argno; - ii += ((len - argbytes + 3) & -4) / 4; - } - - /* Push the rest of the arguments into stack. */ - for (; argno < nargs; ++argno) - { - - arg = args[argno]; - type = check_typedef (value_type (arg)); - len = TYPE_LENGTH (type); - - - /* Float types should be passed in fpr's, as well as in the - stack. */ - if (TYPE_CODE (type) == TYPE_CODE_FLT && f_argno < 13) - { - - gdb_assert (len <= 8); - - regcache_cooked_write (regcache, - tdep->ppc_fp0_regnum + 1 + f_argno, - value_contents (arg)); - ++f_argno; - } - - write_memory (sp + 24 + (ii * 4), - (char *) value_contents (arg), - len); - ii += ((len + 3) & -4) / 4; - } - } - - /* Set the stack pointer. According to the ABI, the SP is meant to - be set _before_ the corresponding stack space is used. On AIX, - this even applies when the target has been completely stopped! - Not doing this can lead to conflicts with the kernel which thinks - that it still has control over this not-yet-allocated stack - region. */ - regcache_raw_write_signed (regcache, SP_REGNUM, sp); - - /* Set back chain properly. */ - store_unsigned_integer (tmp_buffer, 4, saved_sp); - write_memory (sp, tmp_buffer, 4); - - /* Point the inferior function call's return address at the dummy's - breakpoint. */ - regcache_raw_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr); - - /* Set the TOC register, get the value from the objfile reader - which, in turn, gets it from the VMAP table. */ - if (rs6000_find_toc_address_hook != NULL) - { - CORE_ADDR tocvalue = (*rs6000_find_toc_address_hook) (func_addr); - regcache_raw_write_signed (regcache, tdep->ppc_toc_regnum, tocvalue); - } + /* Find an upper limit on the function prologue using the debug + information. If the debug information could not be used to provide + that bound, then use an arbitrary large number as the upper bound. */ + limit_pc = skip_prologue_using_sal (pc); + if (limit_pc == 0) + limit_pc = pc + 100; /* Magic. */ - target_store_registers (-1); - return sp; + pc = skip_prologue (gdbarch, pc, limit_pc, &frame); + return pc; } -/* PowerOpen always puts structures in memory. Vectors, which were - added later, do get returned in a register though. */ - -static int -rs6000_use_struct_convention (int gcc_p, struct type *value_type) -{ - if ((TYPE_LENGTH (value_type) == 16 || TYPE_LENGTH (value_type) == 8) - && TYPE_VECTOR (value_type)) - return 0; - return 1; -} -static void -rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf) +/* All the ABI's require 16 byte alignment. */ +static CORE_ADDR +rs6000_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) { - int offset = 0; - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - - /* The calling convention this function implements assumes the - processor has floating-point registers. We shouldn't be using it - on PPC variants that lack them. */ - gdb_assert (ppc_floating_point_unit_p (current_gdbarch)); - - if (TYPE_CODE (valtype) == TYPE_CODE_FLT) - { - - /* floats and doubles are returned in fpr1. fpr's have a size of 8 bytes. - We need to truncate the return value into float size (4 byte) if - necessary. */ - - convert_typed_floating (®buf[DEPRECATED_REGISTER_BYTE - (tdep->ppc_fp0_regnum + 1)], - builtin_type_double, - valbuf, - valtype); - } - else if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY - && TYPE_LENGTH (valtype) == 16 - && TYPE_VECTOR (valtype)) - { - memcpy (valbuf, regbuf + DEPRECATED_REGISTER_BYTE (tdep->ppc_vr0_regnum + 2), - TYPE_LENGTH (valtype)); - } - else - { - /* return value is copied starting from r3. */ - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG - && TYPE_LENGTH (valtype) < register_size (current_gdbarch, 3)) - offset = register_size (current_gdbarch, 3) - TYPE_LENGTH (valtype); - - memcpy (valbuf, - regbuf + DEPRECATED_REGISTER_BYTE (3) + offset, - TYPE_LENGTH (valtype)); - } + return (addr & -16); } /* Return whether handle_inferior_event() should proceed through code @@ -1727,8 +1796,8 @@ rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf) branches, meaning that the link register doesn't get set. Therefore, GDB's usual step_over_function () mechanism won't work. - Instead, use the IN_SOLIB_RETURN_TRAMPOLINE and - SKIP_TRAMPOLINE_CODE hooks in handle_inferior_event() to skip past + Instead, use the gdbarch_skip_trampoline_code and + gdbarch_skip_trampoline_code hooks in handle_inferior_event() to skip past @FIX code. */ int @@ -1752,8 +1821,9 @@ rs6000_in_solib_return_trampoline (CORE_ADDR pc, char *name) code that should be skipped. */ CORE_ADDR -rs6000_skip_trampoline_code (CORE_ADDR pc) +rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) { + struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame)); unsigned int ii, op; int rel; CORE_ADDR solib_target_pc; @@ -1774,8 +1844,7 @@ rs6000_skip_trampoline_code (CORE_ADDR pc) /* Check for bigtoc fixup code. */ msymbol = lookup_minimal_symbol_by_pc (pc); if (msymbol - && rs6000_in_solib_return_trampoline (pc, - DEPRECATED_SYMBOL_NAME (msymbol))) + && rs6000_in_solib_return_trampoline (pc, SYMBOL_LINKAGE_NAME (msymbol))) { /* Double-check that the third instruction from PC is relative "b". */ op = read_memory_integer (pc + 8, 4); @@ -1789,7 +1858,7 @@ rs6000_skip_trampoline_code (CORE_ADDR pc) } /* If pc is in a shared library trampoline, return its target. */ - solib_target_pc = find_solib_trampoline_target (pc); + solib_target_pc = find_solib_trampoline_target (frame, pc); if (solib_target_pc) return solib_target_pc; @@ -1799,145 +1868,159 @@ rs6000_skip_trampoline_code (CORE_ADDR pc) if (op != trampoline_code[ii]) return 0; } - ii = read_register (11); /* r11 holds destination addr */ - pc = read_memory_addr (ii, gdbarch_tdep (current_gdbarch)->wordsize); /* (r11) value */ + ii = get_frame_register_unsigned (frame, 11); /* r11 holds destination addr */ + pc = read_memory_unsigned_integer (ii, tdep->wordsize); /* (r11) value */ return pc; } -/* Return the size of register REG when words are WORDSIZE bytes long. If REG - isn't available with that word size, return 0. */ +/* ISA-specific vector types. */ -static int -regsize (const struct reg *reg, int wordsize) +static struct type * +rs6000_builtin_type_vec64 (struct gdbarch *gdbarch) { - return wordsize == 8 ? reg->sz64 : reg->sz32; + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (!tdep->ppc_builtin_type_vec64) + { + /* The type we're building is this: */ +#if 0 + union __gdb_builtin_type_vec64 + { + int64_t uint64; + float v2_float[2]; + int32_t v2_int32[2]; + int16_t v4_int16[4]; + int8_t v8_int8[8]; + }; +#endif + + struct type *t; + + t = init_composite_type ("__ppc_builtin_type_vec64", TYPE_CODE_UNION); + append_composite_type_field (t, "uint64", builtin_type_int64); + append_composite_type_field (t, "v2_float", + init_vector_type (builtin_type_float, 2)); + append_composite_type_field (t, "v2_int32", + init_vector_type (builtin_type_int32, 2)); + append_composite_type_field (t, "v4_int16", + init_vector_type (builtin_type_int16, 4)); + append_composite_type_field (t, "v8_int8", + init_vector_type (builtin_type_int8, 8)); + + TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR; + TYPE_NAME (t) = "ppc_builtin_type_vec64"; + tdep->ppc_builtin_type_vec64 = t; + } + + return tdep->ppc_builtin_type_vec64; } -/* Return the name of register number N, or null if no such register exists - in the current architecture. */ +/* Return the name of register number REGNO, or the empty string if it + is an anonymous register. */ static const char * -rs6000_register_name (int n) +rs6000_register_name (struct gdbarch *gdbarch, int regno) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - const struct reg *reg = tdep->regs + n; + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* The upper half "registers" have names in the XML description, + but we present only the low GPRs and the full 64-bit registers + to the user. */ + if (tdep->ppc_ev0_upper_regnum >= 0 + && tdep->ppc_ev0_upper_regnum <= regno + && regno < tdep->ppc_ev0_upper_regnum + ppc_num_gprs) + return ""; + + /* Check if the SPE pseudo registers are available. */ + if (IS_SPE_PSEUDOREG (tdep, regno)) + { + static const char *const spe_regnames[] = { + "ev0", "ev1", "ev2", "ev3", "ev4", "ev5", "ev6", "ev7", + "ev8", "ev9", "ev10", "ev11", "ev12", "ev13", "ev14", "ev15", + "ev16", "ev17", "ev18", "ev19", "ev20", "ev21", "ev22", "ev23", + "ev24", "ev25", "ev26", "ev27", "ev28", "ev29", "ev30", "ev31", + }; + return spe_regnames[regno - tdep->ppc_ev0_regnum]; + } + + /* Check if the decimal128 pseudo-registers are available. */ + if (IS_DFP_PSEUDOREG (tdep, regno)) + { + static const char *const dfp128_regnames[] = { + "dl0", "dl1", "dl2", "dl3", + "dl4", "dl5", "dl6", "dl7", + "dl8", "dl9", "dl10", "dl11", + "dl12", "dl13", "dl14", "dl15" + }; + return dfp128_regnames[regno - tdep->ppc_dl0_regnum]; + } - if (!regsize (reg, tdep->wordsize)) - return NULL; - return reg->name; + return tdesc_register_name (gdbarch, regno); } -/* Return the GDB type object for the "standard" data type - of data in register N. */ +/* Return the GDB type object for the "standard" data type of data in + register N. */ static struct type * -rs6000_register_type (struct gdbarch *gdbarch, int n) +rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - const struct reg *reg = tdep->regs + n; - if (reg->fpr) - return builtin_type_double; + /* These are the only pseudo-registers we support. */ + gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum) + || IS_DFP_PSEUDOREG (tdep, regnum)); + + /* These are the e500 pseudo-registers. */ + if (IS_SPE_PSEUDOREG (tdep, regnum)) + return rs6000_builtin_type_vec64 (gdbarch); else - { - int size = regsize (reg, tdep->wordsize); - switch (size) - { - case 0: - return builtin_type_int0; - case 4: - return builtin_type_uint32; - case 8: - if (tdep->ppc_ev0_regnum <= n && n <= tdep->ppc_ev31_regnum) - return builtin_type_vec64; - else - return builtin_type_uint64; - break; - case 16: - return builtin_type_vec128; - break; - default: - internal_error (__FILE__, __LINE__, "Register %d size %d unknown", - n, size); - } - } + /* Could only be the ppc decimal128 pseudo-registers. */ + return builtin_type (gdbarch)->builtin_declong; } /* Is REGNUM a member of REGGROUP? */ static int -rs6000_register_reggroup_p (struct gdbarch *gdbarch, int regnum, - struct reggroup *group) +rs6000_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + struct reggroup *group) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int float_p; - int vector_p; - int general_p; - if (REGISTER_NAME (regnum) == NULL - || *REGISTER_NAME (regnum) == '\0') - return 0; - if (group == all_reggroup) - return 1; + /* These are the only pseudo-registers we support. */ + gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum) + || IS_DFP_PSEUDOREG (tdep, regnum)); - float_p = (regnum == tdep->ppc_fpscr_regnum - || (regnum >= tdep->ppc_fp0_regnum - && regnum < tdep->ppc_fp0_regnum + 32)); - if (group == float_reggroup) - return float_p; - - vector_p = ((regnum >= tdep->ppc_vr0_regnum - && regnum < tdep->ppc_vr0_regnum + 32) - || (regnum >= tdep->ppc_ev0_regnum - && regnum < tdep->ppc_ev0_regnum + 32) - || regnum == tdep->ppc_vrsave_regnum - || regnum == tdep->ppc_acc_regnum - || regnum == tdep->ppc_spefscr_regnum); - if (group == vector_reggroup) - return vector_p; - - /* Note that PS aka MSR isn't included - it's a system register (and - besides, due to GCC's CFI foobar you do not want to restore - it). */ - general_p = ((regnum >= tdep->ppc_gp0_regnum - && regnum < tdep->ppc_gp0_regnum + 32) - || regnum == tdep->ppc_toc_regnum - || regnum == tdep->ppc_cr_regnum - || regnum == tdep->ppc_lr_regnum - || regnum == tdep->ppc_ctr_regnum - || regnum == tdep->ppc_xer_regnum - || regnum == PC_REGNUM); - if (group == general_reggroup) - return general_p; - - if (group == save_reggroup || group == restore_reggroup) - return general_p || vector_p || float_p; - - return 0; + /* These are the e500 pseudo-registers. */ + if (IS_SPE_PSEUDOREG (tdep, regnum)) + return group == all_reggroup || group == vector_reggroup; + else + /* Could only be the ppc decimal128 pseudo-registers. */ + return group == all_reggroup || group == float_reggroup; } /* The register format for RS/6000 floating point registers is always double, we need a conversion if the memory format is float. */ static int -rs6000_convert_register_p (int regnum, struct type *type) +rs6000_convert_register_p (struct gdbarch *gdbarch, int regnum, + struct type *type) { - const struct reg *reg = gdbarch_tdep (current_gdbarch)->regs + regnum; - - return (reg->fpr - && TYPE_CODE (type) == TYPE_CODE_FLT - && TYPE_LENGTH (type) != TYPE_LENGTH (builtin_type_double)); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + return (tdep->ppc_fp0_regnum >= 0 + && regnum >= tdep->ppc_fp0_regnum + && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs + && TYPE_CODE (type) == TYPE_CODE_FLT + && TYPE_LENGTH (type) != TYPE_LENGTH (builtin_type_double)); } static void rs6000_register_to_value (struct frame_info *frame, int regnum, struct type *type, - void *to) + gdb_byte *to) { - const struct reg *reg = gdbarch_tdep (current_gdbarch)->regs + regnum; - char from[MAX_REGISTER_SIZE]; + gdb_byte from[MAX_REGISTER_SIZE]; - gdb_assert (reg->fpr); gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); get_frame_register (frame, regnum, from); @@ -1948,12 +2031,10 @@ static void rs6000_value_to_register (struct frame_info *frame, int regnum, struct type *type, - const void *from) + const gdb_byte *from) { - const struct reg *reg = gdbarch_tdep (current_gdbarch)->regs + regnum; - char to[MAX_REGISTER_SIZE]; + gdb_byte to[MAX_REGISTER_SIZE]; - gdb_assert (reg->fpr); gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); convert_typed_floating (from, type, to, builtin_type_double); @@ -1985,21 +2066,20 @@ rs6000_value_to_register (struct frame_info *frame, co-variant type qualifiers, ... */ static void e500_move_ev_register (void (*move) (struct regcache *regcache, - int regnum, void *buf), + int regnum, gdb_byte *buf), struct regcache *regcache, int ev_reg, - void *buffer) + gdb_byte *buffer) { struct gdbarch *arch = get_regcache_arch (regcache); struct gdbarch_tdep *tdep = gdbarch_tdep (arch); int reg_index; - char *byte_buffer = buffer; + gdb_byte *byte_buffer = buffer; - gdb_assert (tdep->ppc_ev0_regnum <= ev_reg - && ev_reg < tdep->ppc_ev0_regnum + ppc_num_gprs); + gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg)); reg_index = ev_reg - tdep->ppc_ev0_regnum; - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG) { move (regcache, tdep->ppc_ev0_upper_regnum + reg_index, byte_buffer); move (regcache, tdep->ppc_gp0_regnum + reg_index, byte_buffer + 4); @@ -2013,71 +2093,119 @@ e500_move_ev_register (void (*move) (struct regcache *regcache, static void e500_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, - int reg_nr, void *buffer) + int reg_nr, gdb_byte *buffer) { - struct gdbarch *regcache_arch = get_regcache_arch (regcache); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + e500_move_ev_register (regcache_raw_read, regcache, reg_nr, buffer); +} - gdb_assert (regcache_arch == gdbarch); - - if (tdep->ppc_ev0_regnum <= reg_nr - && reg_nr < tdep->ppc_ev0_regnum + ppc_num_gprs) - e500_move_ev_register (regcache_raw_read, regcache, reg_nr, buffer); +static void +e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, + int reg_nr, const gdb_byte *buffer) +{ + e500_move_ev_register ((void (*) (struct regcache *, int, gdb_byte *)) + regcache_raw_write, + regcache, reg_nr, (gdb_byte *) buffer); +} + +/* Read method for PPC pseudo-registers. Currently this is handling the + 16 decimal128 registers that map into 16 pairs of FP registers. */ +static void +ppc_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, + int reg_nr, gdb_byte *buffer) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int reg_index = reg_nr - tdep->ppc_dl0_regnum; + + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + { + /* Read two FP registers to form a whole dl register. */ + regcache_raw_read (regcache, tdep->ppc_fp0_regnum + + 2 * reg_index, buffer); + regcache_raw_read (regcache, tdep->ppc_fp0_regnum + + 2 * reg_index + 1, buffer + 8); + } else - internal_error (__FILE__, __LINE__, - "e500_pseudo_register_read: " - "called on unexpected register '%s' (%d)", - gdbarch_register_name (gdbarch, reg_nr), reg_nr); + { + regcache_raw_read (regcache, tdep->ppc_fp0_regnum + + 2 * reg_index + 1, buffer + 8); + regcache_raw_read (regcache, tdep->ppc_fp0_regnum + + 2 * reg_index, buffer); + } } +/* Write method for PPC pseudo-registers. Currently this is handling the + 16 decimal128 registers that map into 16 pairs of FP registers. */ static void -e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, - int reg_nr, const void *buffer) +ppc_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, + int reg_nr, const gdb_byte *buffer) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int reg_index = reg_nr - tdep->ppc_dl0_regnum; + + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + { + /* Write each half of the dl register into a separate + FP register. */ + regcache_raw_write (regcache, tdep->ppc_fp0_regnum + + 2 * reg_index, buffer); + regcache_raw_write (regcache, tdep->ppc_fp0_regnum + + 2 * reg_index + 1, buffer + 8); + } + else + { + regcache_raw_write (regcache, tdep->ppc_fp0_regnum + + 2 * reg_index + 1, buffer + 8); + regcache_raw_write (regcache, tdep->ppc_fp0_regnum + + 2 * reg_index, buffer); + } +} + +static void +rs6000_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, + int reg_nr, gdb_byte *buffer) { struct gdbarch *regcache_arch = get_regcache_arch (regcache); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); gdb_assert (regcache_arch == gdbarch); - - if (tdep->ppc_ev0_regnum <= reg_nr - && reg_nr < tdep->ppc_ev0_regnum + ppc_num_gprs) - e500_move_ev_register ((void (*) (struct regcache *, int, void *)) - regcache_raw_write, - regcache, reg_nr, (void *) buffer); + + if (IS_SPE_PSEUDOREG (tdep, reg_nr)) + e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer); + else if (IS_DFP_PSEUDOREG (tdep, reg_nr)) + ppc_pseudo_register_read (gdbarch, regcache, reg_nr, buffer); else internal_error (__FILE__, __LINE__, - "e500_pseudo_register_read: " - "called on unexpected register '%s' (%d)", - gdbarch_register_name (gdbarch, reg_nr), reg_nr); + _("rs6000_pseudo_register_read: " + "called on unexpected register '%s' (%d)"), + gdbarch_register_name (gdbarch, reg_nr), reg_nr); } -/* The E500 needs a custom reggroup function: it has anonymous raw - registers, and default_register_reggroup_p assumes that anonymous - registers are not members of any reggroup. */ -static int -e500_register_reggroup_p (struct gdbarch *gdbarch, - int regnum, - struct reggroup *group) +static void +rs6000_pseudo_register_write (struct gdbarch *gdbarch, + struct regcache *regcache, + int reg_nr, const gdb_byte *buffer) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + struct gdbarch *regcache_arch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - /* The save and restore register groups need to include the - upper-half registers, even though they're anonymous. */ - if ((group == save_reggroup - || group == restore_reggroup) - && (tdep->ppc_ev0_upper_regnum <= regnum - && regnum < tdep->ppc_ev0_upper_regnum + ppc_num_gprs)) - return 1; + gdb_assert (regcache_arch == gdbarch); - /* In all other regards, the default reggroup definition is fine. */ - return default_register_reggroup_p (gdbarch, regnum, group); + if (IS_SPE_PSEUDOREG (tdep, reg_nr)) + e500_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); + else if (IS_DFP_PSEUDOREG (tdep, reg_nr)) + ppc_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); + else + internal_error (__FILE__, __LINE__, + _("rs6000_pseudo_register_write: " + "called on unexpected register '%s' (%d)"), + gdbarch_register_name (gdbarch, reg_nr), reg_nr); } /* Convert a DBX STABS register number to a GDB register number. */ static int -rs6000_stab_reg_to_regnum (int num) +rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (0 <= num && num <= 31) return tdep->ppc_gp0_regnum + num; @@ -2117,9 +2245,9 @@ rs6000_stab_reg_to_regnum (int num) /* Convert a Dwarf 2 register number to a GDB register number. */ static int -rs6000_dwarf2_reg_to_regnum (int num) +rs6000_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (0 <= num && num <= 31) return tdep->ppc_gp0_regnum + num; @@ -2135,6 +2263,8 @@ rs6000_dwarf2_reg_to_regnum (int num) else switch (num) { + case 64: + return tdep->ppc_cr_regnum; case 67: return tdep->ppc_vrsave_regnum - 1; /* vscr */ case 99: @@ -2156,488 +2286,72 @@ rs6000_dwarf2_reg_to_regnum (int num) } } +/* Translate a .eh_frame register to DWARF register, or adjust a + .debug_frame register. */ -static void -rs6000_store_return_value (struct type *type, - struct regcache *regcache, - const void *valbuf) -{ - struct gdbarch *gdbarch = get_regcache_arch (regcache); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int regnum = -1; - - /* The calling convention this function implements assumes the - processor has floating-point registers. We shouldn't be using it - on PPC variants that lack them. */ - gdb_assert (ppc_floating_point_unit_p (gdbarch)); - - if (TYPE_CODE (type) == TYPE_CODE_FLT) - /* Floating point values are returned starting from FPR1 and up. - Say a double_double_double type could be returned in - FPR1/FPR2/FPR3 triple. */ - regnum = tdep->ppc_fp0_regnum + 1; - else if (TYPE_CODE (type) == TYPE_CODE_ARRAY) +static int +rs6000_adjust_frame_regnum (struct gdbarch *gdbarch, int num, int eh_frame_p) +{ + /* GCC releases before 3.4 use GCC internal register numbering in + .debug_frame (and .debug_info, et cetera). The numbering is + different from the standard SysV numbering for everything except + for GPRs and FPRs. We can not detect this problem in most cases + - to get accurate debug info for variables living in lr, ctr, v0, + et cetera, use a newer version of GCC. But we must detect + one important case - lr is in column 65 in .debug_frame output, + instead of 108. + + GCC 3.4, and the "hammer" branch, have a related problem. They + record lr register saves in .debug_frame as 108, but still record + the return column as 65. We fix that up too. + + We can do this because 65 is assigned to fpsr, and GCC never + generates debug info referring to it. To add support for + handwritten debug info that restores fpsr, we would need to add a + producer version check to this. */ + if (!eh_frame_p) { - if (TYPE_LENGTH (type) == 16 - && TYPE_VECTOR (type)) - regnum = tdep->ppc_vr0_regnum + 2; + if (num == 65) + return 108; else - internal_error (__FILE__, __LINE__, - "rs6000_store_return_value: " - "unexpected array return type"); + return num; } - else - /* Everything else is returned in GPR3 and up. */ - regnum = tdep->ppc_gp0_regnum + 3; - - { - size_t bytes_written = 0; - - while (bytes_written < TYPE_LENGTH (type)) - { - /* How much of this value can we write to this register? */ - size_t bytes_to_write = min (TYPE_LENGTH (type) - bytes_written, - register_size (gdbarch, regnum)); - regcache_cooked_write_part (regcache, regnum, - 0, bytes_to_write, - (char *) valbuf + bytes_written); - regnum++; - bytes_written += bytes_to_write; - } - } -} - - -/* Extract from an array REGBUF containing the (raw) register state - the address in which a function should return its structure value, - as a CORE_ADDR (or an expression that can be used as one). */ - -static CORE_ADDR -rs6000_extract_struct_value_address (struct regcache *regcache) -{ - /* FIXME: cagney/2002-09-26: PR gdb/724: When making an inferior - function call GDB knows the address of the struct return value - and hence, should not need to call this function. Unfortunately, - the current call_function_by_hand() code only saves the most - recent struct address leading to occasional calls. The code - should instead maintain a stack of such addresses (in the dummy - frame object). */ - /* NOTE: cagney/2002-09-26: Return 0 which indicates that we've - really got no idea where the return value is being stored. While - r3, on function entry, contained the address it will have since - been reused (scratch) and hence wouldn't be valid */ - return 0; -} - -/* Hook called when a new child process is started. */ - -void -rs6000_create_inferior (int pid) -{ - if (rs6000_set_host_arch_hook) - rs6000_set_host_arch_hook (pid); -} - -/* Support for CONVERT_FROM_FUNC_PTR_ADDR (ARCH, ADDR, TARG). - - Usually a function pointer's representation is simply the address - of the function. On the RS/6000 however, a function pointer is - represented by a pointer to a TOC entry. This TOC entry contains - three words, the first word is the address of the function, the - second word is the TOC pointer (r2), and the third word is the - static chain value. Throughout GDB it is currently assumed that a - function pointer contains the address of the function, which is not - easy to fix. In addition, the conversion of a function address to - a function pointer would require allocation of a TOC entry in the - inferior's memory space, with all its drawbacks. To be able to - call C++ virtual methods in the inferior (which are called via - function pointers), find_function_addr uses this function to get the - function address from a function pointer. */ - -/* Return real function address if ADDR (a function pointer) is in the data - space and is therefore a special function pointer. */ - -static CORE_ADDR -rs6000_convert_from_func_ptr_addr (struct gdbarch *gdbarch, - CORE_ADDR addr, - struct target_ops *targ) -{ - struct obj_section *s; - - s = find_pc_section (addr); - if (s && s->the_bfd_section->flags & SEC_CODE) - return addr; - - /* ADDR is in the data space, so it's a special function pointer. */ - return read_memory_addr (addr, gdbarch_tdep (current_gdbarch)->wordsize); -} - - -/* Handling the various POWER/PowerPC variants. */ - - -/* The arrays here called registers_MUMBLE hold information about available - registers. - - For each family of PPC variants, I've tried to isolate out the - common registers and put them up front, so that as long as you get - the general family right, GDB will correctly identify the registers - common to that family. The common register sets are: - - For the 60x family: hid0 hid1 iabr dabr pir - - For the 505 and 860 family: eie eid nri - - For the 403 and 403GC: icdbdr esr dear evpr cdbcr tsr tcr pit tbhi - tblo srr2 srr3 dbsr dbcr iac1 iac2 dac1 dac2 dccr iccr pbl1 - pbu1 pbl2 pbu2 - - Most of these register groups aren't anything formal. I arrived at - them by looking at the registers that occurred in more than one - processor. - - Note: kevinb/2002-04-30: Support for the fpscr register was added - during April, 2002. Slot 70 is being used for PowerPC and slot 71 - for Power. For PowerPC, slot 70 was unused and was already in the - PPC_UISA_SPRS which is ideally where fpscr should go. For Power, - slot 70 was being used for "mq", so the next available slot (71) - was chosen. It would have been nice to be able to make the - register numbers the same across processor cores, but this wasn't - possible without either 1) renumbering some registers for some - processors or 2) assigning fpscr to a really high slot that's - larger than any current register number. Doing (1) is bad because - existing stubs would break. Doing (2) is undesirable because it - would introduce a really large gap between fpscr and the rest of - the registers for most processors. */ - -/* Convenience macros for populating register arrays. */ - -/* Within another macro, convert S to a string. */ - -#define STR(s) #s - -/* Return a struct reg defining register NAME that's 32 bits on 32-bit systems - and 64 bits on 64-bit systems. */ -#define R(name) { STR(name), 4, 8, 0, 0, -1 } - -/* Return a struct reg defining register NAME that's 32 bits on all - systems. */ -#define R4(name) { STR(name), 4, 4, 0, 0, -1 } - -/* Return a struct reg defining register NAME that's 64 bits on all - systems. */ -#define R8(name) { STR(name), 8, 8, 0, 0, -1 } - -/* Return a struct reg defining register NAME that's 128 bits on all - systems. */ -#define R16(name) { STR(name), 16, 16, 0, 0, -1 } - -/* Return a struct reg defining floating-point register NAME. */ -#define F(name) { STR(name), 8, 8, 1, 0, -1 } - -/* Return a struct reg defining a pseudo register NAME that is 64 bits - long on all systems. */ -#define P8(name) { STR(name), 8, 8, 0, 1, -1 } - -/* Return a struct reg defining register NAME that's 32 bits on 32-bit - systems and that doesn't exist on 64-bit systems. */ -#define R32(name) { STR(name), 4, 0, 0, 0, -1 } - -/* Return a struct reg defining register NAME that's 64 bits on 64-bit - systems and that doesn't exist on 32-bit systems. */ -#define R64(name) { STR(name), 0, 8, 0, 0, -1 } - -/* Return a struct reg placeholder for a register that doesn't exist. */ -#define R0 { 0, 0, 0, 0, 0, -1 } - -/* Return a struct reg defining an anonymous raw register that's 32 - bits on all systems. */ -#define A4 { 0, 4, 4, 0, 0, -1 } - -/* Return a struct reg defining an SPR named NAME that is 32 bits on - 32-bit systems and 64 bits on 64-bit systems. */ -#define S(name) { STR(name), 4, 8, 0, 0, ppc_spr_ ## name } - -/* Return a struct reg defining an SPR named NAME that is 32 bits on - all systems. */ -#define S4(name) { STR(name), 4, 4, 0, 0, ppc_spr_ ## name } - -/* Return a struct reg defining an SPR named NAME that is 32 bits on - all systems, and whose SPR number is NUMBER. */ -#define SN4(name, number) { STR(name), 4, 4, 0, 0, (number) } - -/* Return a struct reg defining an SPR named NAME that's 64 bits on - 64-bit systems and that doesn't exist on 32-bit systems. */ -#define S64(name) { STR(name), 0, 8, 0, 0, ppc_spr_ ## name } - -/* UISA registers common across all architectures, including POWER. */ - -#define COMMON_UISA_REGS \ - /* 0 */ R(r0), R(r1), R(r2), R(r3), R(r4), R(r5), R(r6), R(r7), \ - /* 8 */ R(r8), R(r9), R(r10),R(r11),R(r12),R(r13),R(r14),R(r15), \ - /* 16 */ R(r16),R(r17),R(r18),R(r19),R(r20),R(r21),R(r22),R(r23), \ - /* 24 */ R(r24),R(r25),R(r26),R(r27),R(r28),R(r29),R(r30),R(r31), \ - /* 32 */ F(f0), F(f1), F(f2), F(f3), F(f4), F(f5), F(f6), F(f7), \ - /* 40 */ F(f8), F(f9), F(f10),F(f11),F(f12),F(f13),F(f14),F(f15), \ - /* 48 */ F(f16),F(f17),F(f18),F(f19),F(f20),F(f21),F(f22),F(f23), \ - /* 56 */ F(f24),F(f25),F(f26),F(f27),F(f28),F(f29),F(f30),F(f31), \ - /* 64 */ R(pc), R(ps) - -/* UISA-level SPRs for PowerPC. */ -#define PPC_UISA_SPRS \ - /* 66 */ R4(cr), S(lr), S(ctr), S4(xer), R4(fpscr) - -/* UISA-level SPRs for PowerPC without floating point support. */ -#define PPC_UISA_NOFP_SPRS \ - /* 66 */ R4(cr), S(lr), S(ctr), S4(xer), R0 - -/* Segment registers, for PowerPC. */ -#define PPC_SEGMENT_REGS \ - /* 71 */ R32(sr0), R32(sr1), R32(sr2), R32(sr3), \ - /* 75 */ R32(sr4), R32(sr5), R32(sr6), R32(sr7), \ - /* 79 */ R32(sr8), R32(sr9), R32(sr10), R32(sr11), \ - /* 83 */ R32(sr12), R32(sr13), R32(sr14), R32(sr15) - -/* OEA SPRs for PowerPC. */ -#define PPC_OEA_SPRS \ - /* 87 */ S4(pvr), \ - /* 88 */ S(ibat0u), S(ibat0l), S(ibat1u), S(ibat1l), \ - /* 92 */ S(ibat2u), S(ibat2l), S(ibat3u), S(ibat3l), \ - /* 96 */ S(dbat0u), S(dbat0l), S(dbat1u), S(dbat1l), \ - /* 100 */ S(dbat2u), S(dbat2l), S(dbat3u), S(dbat3l), \ - /* 104 */ S(sdr1), S64(asr), S(dar), S4(dsisr), \ - /* 108 */ S(sprg0), S(sprg1), S(sprg2), S(sprg3), \ - /* 112 */ S(srr0), S(srr1), S(tbl), S(tbu), \ - /* 116 */ S4(dec), S(dabr), S4(ear) - -/* AltiVec registers. */ -#define PPC_ALTIVEC_REGS \ - /*119*/R16(vr0), R16(vr1), R16(vr2), R16(vr3), R16(vr4), R16(vr5), R16(vr6), R16(vr7), \ - /*127*/R16(vr8), R16(vr9), R16(vr10),R16(vr11),R16(vr12),R16(vr13),R16(vr14),R16(vr15), \ - /*135*/R16(vr16),R16(vr17),R16(vr18),R16(vr19),R16(vr20),R16(vr21),R16(vr22),R16(vr23), \ - /*143*/R16(vr24),R16(vr25),R16(vr26),R16(vr27),R16(vr28),R16(vr29),R16(vr30),R16(vr31), \ - /*151*/R4(vscr), R4(vrsave) - - -/* On machines supporting the SPE APU, the general-purpose registers - are 64 bits long. There are SIMD vector instructions to treat them - as pairs of floats, but the rest of the instruction set treats them - as 32-bit registers, and only operates on their lower halves. - - In the GDB regcache, we treat their high and low halves as separate - registers. The low halves we present as the general-purpose - registers, and then we have pseudo-registers that stitch together - the upper and lower halves and present them as pseudo-registers. */ - -/* SPE GPR lower halves --- raw registers. */ -#define PPC_SPE_GP_REGS \ - /* 0 */ R4(r0), R4(r1), R4(r2), R4(r3), R4(r4), R4(r5), R4(r6), R4(r7), \ - /* 8 */ R4(r8), R4(r9), R4(r10),R4(r11),R4(r12),R4(r13),R4(r14),R4(r15), \ - /* 16 */ R4(r16),R4(r17),R4(r18),R4(r19),R4(r20),R4(r21),R4(r22),R4(r23), \ - /* 24 */ R4(r24),R4(r25),R4(r26),R4(r27),R4(r28),R4(r29),R4(r30),R4(r31) - -/* SPE GPR upper halves --- anonymous raw registers. */ -#define PPC_SPE_UPPER_GP_REGS \ - /* 0 */ A4, A4, A4, A4, A4, A4, A4, A4, \ - /* 8 */ A4, A4, A4, A4, A4, A4, A4, A4, \ - /* 16 */ A4, A4, A4, A4, A4, A4, A4, A4, \ - /* 24 */ A4, A4, A4, A4, A4, A4, A4, A4 - -/* SPE GPR vector registers --- pseudo registers based on underlying - gprs and the anonymous upper half raw registers. */ -#define PPC_EV_PSEUDO_REGS \ -/* 0*/P8(ev0), P8(ev1), P8(ev2), P8(ev3), P8(ev4), P8(ev5), P8(ev6), P8(ev7), \ -/* 8*/P8(ev8), P8(ev9), P8(ev10),P8(ev11),P8(ev12),P8(ev13),P8(ev14),P8(ev15),\ -/*16*/P8(ev16),P8(ev17),P8(ev18),P8(ev19),P8(ev20),P8(ev21),P8(ev22),P8(ev23),\ -/*24*/P8(ev24),P8(ev25),P8(ev26),P8(ev27),P8(ev28),P8(ev29),P8(ev30),P8(ev31) - -/* IBM POWER (pre-PowerPC) architecture, user-level view. We only cover - user-level SPR's. */ -static const struct reg registers_power[] = -{ - COMMON_UISA_REGS, - /* 66 */ R4(cnd), S(lr), S(cnt), S4(xer), S4(mq), - /* 71 */ R4(fpscr) -}; - -/* PowerPC UISA - a PPC processor as viewed by user-level code. A UISA-only - view of the PowerPC. */ -static const struct reg registers_powerpc[] = -{ - COMMON_UISA_REGS, - PPC_UISA_SPRS, - PPC_ALTIVEC_REGS -}; - -/* IBM PowerPC 403. - - Some notes about the "tcr" special-purpose register: - - On the 403 and 403GC, SPR 986 is named "tcr", and it controls the - 403's programmable interval timer, fixed interval timer, and - watchdog timer. - - On the 602, SPR 984 is named "tcr", and it controls the 602's - watchdog timer, and nothing else. - - Some of the fields are similar between the two, but they're not - compatible with each other. Since the two variants have different - registers, with different numbers, but the same name, we can't - splice the register name to get the SPR number. */ -static const struct reg registers_403[] = -{ - COMMON_UISA_REGS, - PPC_UISA_SPRS, - PPC_SEGMENT_REGS, - PPC_OEA_SPRS, - /* 119 */ S(icdbdr), S(esr), S(dear), S(evpr), - /* 123 */ S(cdbcr), S(tsr), SN4(tcr, ppc_spr_403_tcr), S(pit), - /* 127 */ S(tbhi), S(tblo), S(srr2), S(srr3), - /* 131 */ S(dbsr), S(dbcr), S(iac1), S(iac2), - /* 135 */ S(dac1), S(dac2), S(dccr), S(iccr), - /* 139 */ S(pbl1), S(pbu1), S(pbl2), S(pbu2) -}; - -/* IBM PowerPC 403GC. - See the comments about 'tcr' for the 403, above. */ -static const struct reg registers_403GC[] = -{ - COMMON_UISA_REGS, - PPC_UISA_SPRS, - PPC_SEGMENT_REGS, - PPC_OEA_SPRS, - /* 119 */ S(icdbdr), S(esr), S(dear), S(evpr), - /* 123 */ S(cdbcr), S(tsr), SN4(tcr, ppc_spr_403_tcr), S(pit), - /* 127 */ S(tbhi), S(tblo), S(srr2), S(srr3), - /* 131 */ S(dbsr), S(dbcr), S(iac1), S(iac2), - /* 135 */ S(dac1), S(dac2), S(dccr), S(iccr), - /* 139 */ S(pbl1), S(pbu1), S(pbl2), S(pbu2), - /* 143 */ S(zpr), S(pid), S(sgr), S(dcwr), - /* 147 */ S(tbhu), S(tblu) -}; - -/* Motorola PowerPC 505. */ -static const struct reg registers_505[] = -{ - COMMON_UISA_REGS, - PPC_UISA_SPRS, - PPC_SEGMENT_REGS, - PPC_OEA_SPRS, - /* 119 */ S(eie), S(eid), S(nri) -}; - -/* Motorola PowerPC 860 or 850. */ -static const struct reg registers_860[] = -{ - COMMON_UISA_REGS, - PPC_UISA_SPRS, - PPC_SEGMENT_REGS, - PPC_OEA_SPRS, - /* 119 */ S(eie), S(eid), S(nri), S(cmpa), - /* 123 */ S(cmpb), S(cmpc), S(cmpd), S(icr), - /* 127 */ S(der), S(counta), S(countb), S(cmpe), - /* 131 */ S(cmpf), S(cmpg), S(cmph), S(lctrl1), - /* 135 */ S(lctrl2), S(ictrl), S(bar), S(ic_cst), - /* 139 */ S(ic_adr), S(ic_dat), S(dc_cst), S(dc_adr), - /* 143 */ S(dc_dat), S(dpdr), S(dpir), S(immr), - /* 147 */ S(mi_ctr), S(mi_ap), S(mi_epn), S(mi_twc), - /* 151 */ S(mi_rpn), S(md_ctr), S(m_casid), S(md_ap), - /* 155 */ S(md_epn), S(m_twb), S(md_twc), S(md_rpn), - /* 159 */ S(m_tw), S(mi_dbcam), S(mi_dbram0), S(mi_dbram1), - /* 163 */ S(md_dbcam), S(md_dbram0), S(md_dbram1) -}; -/* Motorola PowerPC 601. Note that the 601 has different register numbers - for reading and writing RTCU and RTCL. However, how one reads and writes a - register is the stub's problem. */ -static const struct reg registers_601[] = -{ - COMMON_UISA_REGS, - PPC_UISA_SPRS, - PPC_SEGMENT_REGS, - PPC_OEA_SPRS, - /* 119 */ S(hid0), S(hid1), S(iabr), S(dabr), - /* 123 */ S(pir), S(mq), S(rtcu), S(rtcl) -}; - -/* Motorola PowerPC 602. - See the notes under the 403 about 'tcr'. */ -static const struct reg registers_602[] = -{ - COMMON_UISA_REGS, - PPC_UISA_SPRS, - PPC_SEGMENT_REGS, - PPC_OEA_SPRS, - /* 119 */ S(hid0), S(hid1), S(iabr), R0, - /* 123 */ R0, SN4(tcr, ppc_spr_602_tcr), S(ibr), S(esasrr), - /* 127 */ S(sebr), S(ser), S(sp), S(lt) -}; - -/* Motorola/IBM PowerPC 603 or 603e. */ -static const struct reg registers_603[] = -{ - COMMON_UISA_REGS, - PPC_UISA_SPRS, - PPC_SEGMENT_REGS, - PPC_OEA_SPRS, - /* 119 */ S(hid0), S(hid1), S(iabr), R0, - /* 123 */ R0, S(dmiss), S(dcmp), S(hash1), - /* 127 */ S(hash2), S(imiss), S(icmp), S(rpa) -}; - -/* Motorola PowerPC 604 or 604e. */ -static const struct reg registers_604[] = -{ - COMMON_UISA_REGS, - PPC_UISA_SPRS, - PPC_SEGMENT_REGS, - PPC_OEA_SPRS, - /* 119 */ S(hid0), S(hid1), S(iabr), S(dabr), - /* 123 */ S(pir), S(mmcr0), S(pmc1), S(pmc2), - /* 127 */ S(sia), S(sda) -}; - -/* Motorola/IBM PowerPC 750 or 740. */ -static const struct reg registers_750[] = -{ - COMMON_UISA_REGS, - PPC_UISA_SPRS, - PPC_SEGMENT_REGS, - PPC_OEA_SPRS, - /* 119 */ S(hid0), S(hid1), S(iabr), S(dabr), - /* 123 */ R0, S(ummcr0), S(upmc1), S(upmc2), - /* 127 */ S(usia), S(ummcr1), S(upmc3), S(upmc4), - /* 131 */ S(mmcr0), S(pmc1), S(pmc2), S(sia), - /* 135 */ S(mmcr1), S(pmc3), S(pmc4), S(l2cr), - /* 139 */ S(ictc), S(thrm1), S(thrm2), S(thrm3) -}; - - -/* Motorola PowerPC 7400. */ -static const struct reg registers_7400[] = -{ - /* gpr0-gpr31, fpr0-fpr31 */ - COMMON_UISA_REGS, - /* cr, lr, ctr, xer, fpscr */ - PPC_UISA_SPRS, - /* sr0-sr15 */ - PPC_SEGMENT_REGS, - PPC_OEA_SPRS, - /* vr0-vr31, vrsave, vscr */ - PPC_ALTIVEC_REGS - /* FIXME? Add more registers? */ -}; + /* .eh_frame is GCC specific. For binary compatibility, it uses GCC + internal register numbering; translate that to the standard DWARF2 + register numbering. */ + if (0 <= num && num <= 63) /* r0-r31,fp0-fp31 */ + return num; + else if (68 <= num && num <= 75) /* cr0-cr8 */ + return num - 68 + 86; + else if (77 <= num && num <= 108) /* vr0-vr31 */ + return num - 77 + 1124; + else + switch (num) + { + case 64: /* mq */ + return 100; + case 65: /* lr */ + return 108; + case 66: /* ctr */ + return 109; + case 76: /* xer */ + return 101; + case 109: /* vrsave */ + return 356; + case 110: /* vscr */ + return 67; + case 111: /* spe_acc */ + return 99; + case 112: /* spefscr */ + return 612; + default: + return num; + } +} + -/* Motorola e500. */ -static const struct reg registers_e500[] = -{ - /* 0 .. 31 */ PPC_SPE_GP_REGS, - /* 32 .. 63 */ PPC_SPE_UPPER_GP_REGS, - /* 64 .. 65 */ R(pc), R(ps), - /* 66 .. 70 */ PPC_UISA_NOFP_SPRS, - /* 71 .. 72 */ R8(acc), S4(spefscr), - /* NOTE: Add new registers here the end of the raw register - list and just before the first pseudo register. */ - /* 73 .. 104 */ PPC_EV_PSEUDO_REGS -}; +/* Handling the various POWER/PowerPC variants. */ /* Information about a particular processor variant. */ @@ -2655,151 +2369,64 @@ struct variant /* bfd_arch_info.mach corresponding to variant. */ unsigned long mach; - /* Number of real registers. */ - int nregs; - - /* Number of pseudo registers. */ - int npregs; - - /* Number of total registers (the sum of nregs and npregs). */ - int num_tot_regs; - - /* Table of register names; registers[R] is the name of the register - number R. */ - const struct reg *regs; + /* Target description for this variant. */ + struct target_desc **tdesc; }; -#define tot_num_registers(list) (sizeof (list) / sizeof((list)[0])) - -static int -num_registers (const struct reg *reg_list, int num_tot_regs) -{ - int i; - int nregs = 0; - - for (i = 0; i < num_tot_regs; i++) - if (!reg_list[i].pseudo) - nregs++; - - return nregs; -} - -static int -num_pseudo_registers (const struct reg *reg_list, int num_tot_regs) -{ - int i; - int npregs = 0; - - for (i = 0; i < num_tot_regs; i++) - if (reg_list[i].pseudo) - npregs ++; - - return npregs; -} - -/* Information in this table comes from the following web sites: - IBM: http://www.chips.ibm.com:80/products/embedded/ - Motorola: http://www.mot.com/SPS/PowerPC/ - - I'm sure I've got some of the variant descriptions not quite right. - Please report any inaccuracies you find to GDB's maintainer. - - If you add entries to this table, please be sure to allow the new - value as an argument to the --with-cpu flag, in configure.in. */ - static struct variant variants[] = { - {"powerpc", "PowerPC user-level", bfd_arch_powerpc, - bfd_mach_ppc, -1, -1, tot_num_registers (registers_powerpc), - registers_powerpc}, + bfd_mach_ppc, &tdesc_powerpc_altivec32}, {"power", "POWER user-level", bfd_arch_rs6000, - bfd_mach_rs6k, -1, -1, tot_num_registers (registers_power), - registers_power}, + bfd_mach_rs6k, &tdesc_rs6000}, {"403", "IBM PowerPC 403", bfd_arch_powerpc, - bfd_mach_ppc_403, -1, -1, tot_num_registers (registers_403), - registers_403}, + bfd_mach_ppc_403, &tdesc_powerpc_403}, {"601", "Motorola PowerPC 601", bfd_arch_powerpc, - bfd_mach_ppc_601, -1, -1, tot_num_registers (registers_601), - registers_601}, + bfd_mach_ppc_601, &tdesc_powerpc_601}, {"602", "Motorola PowerPC 602", bfd_arch_powerpc, - bfd_mach_ppc_602, -1, -1, tot_num_registers (registers_602), - registers_602}, + bfd_mach_ppc_602, &tdesc_powerpc_602}, {"603", "Motorola/IBM PowerPC 603 or 603e", bfd_arch_powerpc, - bfd_mach_ppc_603, -1, -1, tot_num_registers (registers_603), - registers_603}, + bfd_mach_ppc_603, &tdesc_powerpc_603}, {"604", "Motorola PowerPC 604 or 604e", bfd_arch_powerpc, - 604, -1, -1, tot_num_registers (registers_604), - registers_604}, + 604, &tdesc_powerpc_604}, {"403GC", "IBM PowerPC 403GC", bfd_arch_powerpc, - bfd_mach_ppc_403gc, -1, -1, tot_num_registers (registers_403GC), - registers_403GC}, + bfd_mach_ppc_403gc, &tdesc_powerpc_403gc}, {"505", "Motorola PowerPC 505", bfd_arch_powerpc, - bfd_mach_ppc_505, -1, -1, tot_num_registers (registers_505), - registers_505}, + bfd_mach_ppc_505, &tdesc_powerpc_505}, {"860", "Motorola PowerPC 860 or 850", bfd_arch_powerpc, - bfd_mach_ppc_860, -1, -1, tot_num_registers (registers_860), - registers_860}, + bfd_mach_ppc_860, &tdesc_powerpc_860}, {"750", "Motorola/IBM PowerPC 750 or 740", bfd_arch_powerpc, - bfd_mach_ppc_750, -1, -1, tot_num_registers (registers_750), - registers_750}, + bfd_mach_ppc_750, &tdesc_powerpc_750}, {"7400", "Motorola/IBM PowerPC 7400 (G4)", bfd_arch_powerpc, - bfd_mach_ppc_7400, -1, -1, tot_num_registers (registers_7400), - registers_7400}, + bfd_mach_ppc_7400, &tdesc_powerpc_7400}, {"e500", "Motorola PowerPC e500", bfd_arch_powerpc, - bfd_mach_ppc_e500, -1, -1, tot_num_registers (registers_e500), - registers_e500}, + bfd_mach_ppc_e500, &tdesc_powerpc_e500}, /* 64-bit */ {"powerpc64", "PowerPC 64-bit user-level", bfd_arch_powerpc, - bfd_mach_ppc64, -1, -1, tot_num_registers (registers_powerpc), - registers_powerpc}, + bfd_mach_ppc64, &tdesc_powerpc_altivec64}, {"620", "Motorola PowerPC 620", bfd_arch_powerpc, - bfd_mach_ppc_620, -1, -1, tot_num_registers (registers_powerpc), - registers_powerpc}, + bfd_mach_ppc_620, &tdesc_powerpc_64}, {"630", "Motorola PowerPC 630", bfd_arch_powerpc, - bfd_mach_ppc_630, -1, -1, tot_num_registers (registers_powerpc), - registers_powerpc}, + bfd_mach_ppc_630, &tdesc_powerpc_64}, {"a35", "PowerPC A35", bfd_arch_powerpc, - bfd_mach_ppc_a35, -1, -1, tot_num_registers (registers_powerpc), - registers_powerpc}, + bfd_mach_ppc_a35, &tdesc_powerpc_64}, {"rs64ii", "PowerPC rs64ii", bfd_arch_powerpc, - bfd_mach_ppc_rs64ii, -1, -1, tot_num_registers (registers_powerpc), - registers_powerpc}, + bfd_mach_ppc_rs64ii, &tdesc_powerpc_64}, {"rs64iii", "PowerPC rs64iii", bfd_arch_powerpc, - bfd_mach_ppc_rs64iii, -1, -1, tot_num_registers (registers_powerpc), - registers_powerpc}, + bfd_mach_ppc_rs64iii, &tdesc_powerpc_64}, /* FIXME: I haven't checked the register sets of the following. */ {"rs1", "IBM POWER RS1", bfd_arch_rs6000, - bfd_mach_rs6k_rs1, -1, -1, tot_num_registers (registers_power), - registers_power}, + bfd_mach_rs6k_rs1, &tdesc_rs6000}, {"rsc", "IBM POWER RSC", bfd_arch_rs6000, - bfd_mach_rs6k_rsc, -1, -1, tot_num_registers (registers_power), - registers_power}, + bfd_mach_rs6k_rsc, &tdesc_rs6000}, {"rs2", "IBM POWER RS2", bfd_arch_rs6000, - bfd_mach_rs6k_rs2, -1, -1, tot_num_registers (registers_power), - registers_power}, + bfd_mach_rs6k_rs2, &tdesc_rs6000}, - {0, 0, 0, 0, 0, 0, 0, 0} + {0, 0, 0, 0, 0} }; -/* Initialize the number of registers and pseudo registers in each variant. */ - -static void -init_variants (void) -{ - struct variant *v; - - for (v = variants; v->name; v++) - { - if (v->nregs == -1) - v->nregs = num_registers (v->regs, v->num_tot_regs); - if (v->npregs == -1) - v->npregs = num_pseudo_registers (v->regs, v->num_tot_regs); - } -} - /* Return the variant corresponding to architecture ARCH and machine number MACH. If no such variant exists, return null. */ @@ -2818,7 +2445,10 @@ find_variant_by_arch (enum bfd_architecture arch, unsigned long mach) static int gdb_print_insn_powerpc (bfd_vma memaddr, disassemble_info *info) { - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + if (!info->disassembler_options) + info->disassembler_options = "any"; + + if (info->endian == BFD_ENDIAN_BIG) return print_insn_big_powerpc (memaddr, info); else return print_insn_little_powerpc (memaddr, info); @@ -2827,15 +2457,16 @@ gdb_print_insn_powerpc (bfd_vma memaddr, disassemble_info *info) static CORE_ADDR rs6000_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { - return frame_unwind_register_unsigned (next_frame, PC_REGNUM); + return frame_unwind_register_unsigned (next_frame, + gdbarch_pc_regnum (gdbarch)); } static struct frame_id -rs6000_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) +rs6000_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) { - return frame_id_build (frame_unwind_register_unsigned (next_frame, - SP_REGNUM), - frame_pc_unwind (next_frame)); + return frame_id_build (get_frame_register_unsigned + (this_frame, gdbarch_sp_regnum (gdbarch)), + get_frame_pc (this_frame)); } struct rs6000_frame_cache @@ -2846,50 +2477,72 @@ struct rs6000_frame_cache }; static struct rs6000_frame_cache * -rs6000_frame_cache (struct frame_info *next_frame, void **this_cache) +rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) { struct rs6000_frame_cache *cache; - struct gdbarch *gdbarch = get_frame_arch (next_frame); + struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct rs6000_framedata fdata; int wordsize = tdep->wordsize; + CORE_ADDR func, pc; if ((*this_cache) != NULL) return (*this_cache); cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache); (*this_cache) = cache; - cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); - - skip_prologue (frame_func_unwind (next_frame), frame_pc_unwind (next_frame), - &fdata); - - /* If there were any saved registers, figure out parent's stack - pointer. */ - /* The following is true only if the frame doesn't have a call to - alloca(), FIXME. */ - - if (fdata.saved_fpr == 0 - && fdata.saved_gpr == 0 - && fdata.saved_vr == 0 - && fdata.saved_ev == 0 - && fdata.lr_offset == 0 - && fdata.cr_offset == 0 - && fdata.vr_offset == 0 - && fdata.ev_offset == 0) - cache->base = frame_unwind_register_unsigned (next_frame, SP_REGNUM); - else + cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); + + func = get_frame_func (this_frame); + pc = get_frame_pc (this_frame); + skip_prologue (gdbarch, func, pc, &fdata); + + /* Figure out the parent's stack pointer. */ + + /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most + address of the current frame. Things might be easier if the + ->frame pointed to the outer-most address of the frame. In + the mean time, the address of the prev frame is used as the + base address of this frame. */ + cache->base = get_frame_register_unsigned + (this_frame, gdbarch_sp_regnum (gdbarch)); + + /* If the function appears to be frameless, check a couple of likely + indicators that we have simply failed to find the frame setup. + Two common cases of this are missing symbols (i.e. + get_frame_func returns the wrong address or 0), and assembly + stubs which have a fast exit path but set up a frame on the slow + path. + + If the LR appears to return to this function, then presume that + we have an ABI compliant frame that we failed to find. */ + if (fdata.frameless && fdata.lr_offset == 0) { - /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most - address of the current frame. Things might be easier if the - ->frame pointed to the outer-most address of the frame. In - the mean time, the address of the prev frame is used as the - base address of this frame. */ - cache->base = frame_unwind_register_unsigned (next_frame, SP_REGNUM); - if (!fdata.frameless) - /* Frameless really means stackless. */ - cache->base = read_memory_addr (cache->base, wordsize); + CORE_ADDR saved_lr; + int make_frame = 0; + + saved_lr = get_frame_register_unsigned (this_frame, tdep->ppc_lr_regnum); + if (func == 0 && saved_lr == pc) + make_frame = 1; + else if (func != 0) + { + CORE_ADDR saved_func = get_pc_function_start (saved_lr); + if (func == saved_func) + make_frame = 1; + } + + if (make_frame) + { + fdata.frameless = 0; + fdata.lr_offset = tdep->lr_frame_offset; + } } - trad_frame_set_value (cache->saved_regs, SP_REGNUM, cache->base); + + if (!fdata.frameless) + /* Frameless really means stackless. */ + cache->base = read_memory_unsigned_integer (cache->base, wordsize); + + trad_frame_set_value (cache->saved_regs, + gdbarch_sp_regnum (gdbarch), cache->base); /* if != -1, fdata.saved_fpr is the smallest number of saved_fpr. All fpr's from saved_fpr to fp31 are saved. */ @@ -2943,7 +2596,7 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache) /* if != -1, fdata.saved_ev is the smallest number of saved_ev. All vr's from saved_ev to ev31 are saved. ????? */ - if (tdep->ppc_ev0_regnum != -1 && tdep->ppc_ev31_regnum != -1) + if (tdep->ppc_ev0_regnum != -1) { if (fdata.saved_ev >= 0) { @@ -2968,7 +2621,8 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache) if (fdata.lr_offset != 0) cache->saved_regs[tdep->ppc_lr_regnum].addr = cache->base + fdata.lr_offset; /* The PC is found in the link register. */ - cache->saved_regs[PC_REGNUM] = cache->saved_regs[tdep->ppc_lr_regnum]; + cache->saved_regs[gdbarch_pc_regnum (gdbarch)] = + cache->saved_regs[tdep->ppc_lr_regnum]; /* If != 0, fdata.vrsave_offset is the offset from the frame that holds the VRSAVE. */ @@ -2978,56 +2632,51 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache) if (fdata.alloca_reg < 0) /* If no alloca register used, then fi->frame is the value of the %sp for this frame, and it is good enough. */ - cache->initial_sp = frame_unwind_register_unsigned (next_frame, SP_REGNUM); + cache->initial_sp + = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); else - cache->initial_sp = frame_unwind_register_unsigned (next_frame, - fdata.alloca_reg); + cache->initial_sp + = get_frame_register_unsigned (this_frame, fdata.alloca_reg); return cache; } static void -rs6000_frame_this_id (struct frame_info *next_frame, void **this_cache, +rs6000_frame_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { - struct rs6000_frame_cache *info = rs6000_frame_cache (next_frame, + struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame, this_cache); - (*this_id) = frame_id_build (info->base, frame_func_unwind (next_frame)); + /* This marks the outermost frame. */ + if (info->base == 0) + return; + + (*this_id) = frame_id_build (info->base, get_frame_func (this_frame)); } -static void -rs6000_frame_prev_register (struct frame_info *next_frame, - void **this_cache, - int regnum, int *optimizedp, - enum lval_type *lvalp, CORE_ADDR *addrp, - int *realnump, void *valuep) +static struct value * +rs6000_frame_prev_register (struct frame_info *this_frame, + void **this_cache, int regnum) { - struct rs6000_frame_cache *info = rs6000_frame_cache (next_frame, + struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame, this_cache); - trad_frame_get_prev_register (next_frame, info->saved_regs, regnum, - optimizedp, lvalp, addrp, realnump, valuep); + return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); } static const struct frame_unwind rs6000_frame_unwind = { NORMAL_FRAME, rs6000_frame_this_id, - rs6000_frame_prev_register + rs6000_frame_prev_register, + NULL, + default_frame_sniffer }; - -static const struct frame_unwind * -rs6000_frame_sniffer (struct frame_info *next_frame) -{ - return &rs6000_frame_unwind; -} - static CORE_ADDR -rs6000_frame_base_address (struct frame_info *next_frame, - void **this_cache) +rs6000_frame_base_address (struct frame_info *this_frame, void **this_cache) { - struct rs6000_frame_cache *info = rs6000_frame_cache (next_frame, + struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame, this_cache); return info->initial_sp; } @@ -3040,11 +2689,73 @@ static const struct frame_base rs6000_frame_base = { }; static const struct frame_base * -rs6000_frame_base_sniffer (struct frame_info *next_frame) +rs6000_frame_base_sniffer (struct frame_info *this_frame) { return &rs6000_frame_base; } +/* DWARF-2 frame support. Used to handle the detection of + clobbered registers during function calls. */ + +static void +ppc_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, + struct dwarf2_frame_state_reg *reg, + struct frame_info *this_frame) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* PPC32 and PPC64 ABI's are the same regarding volatile and + non-volatile registers. We will use the same code for both. */ + + /* Call-saved GP registers. */ + if ((regnum >= tdep->ppc_gp0_regnum + 14 + && regnum <= tdep->ppc_gp0_regnum + 31) + || (regnum == tdep->ppc_gp0_regnum + 1)) + reg->how = DWARF2_FRAME_REG_SAME_VALUE; + + /* Call-clobbered GP registers. */ + if ((regnum >= tdep->ppc_gp0_regnum + 3 + && regnum <= tdep->ppc_gp0_regnum + 12) + || (regnum == tdep->ppc_gp0_regnum)) + reg->how = DWARF2_FRAME_REG_UNDEFINED; + + /* Deal with FP registers, if supported. */ + if (tdep->ppc_fp0_regnum >= 0) + { + /* Call-saved FP registers. */ + if ((regnum >= tdep->ppc_fp0_regnum + 14 + && regnum <= tdep->ppc_fp0_regnum + 31)) + reg->how = DWARF2_FRAME_REG_SAME_VALUE; + + /* Call-clobbered FP registers. */ + if ((regnum >= tdep->ppc_fp0_regnum + && regnum <= tdep->ppc_fp0_regnum + 13)) + reg->how = DWARF2_FRAME_REG_UNDEFINED; + } + + /* Deal with ALTIVEC registers, if supported. */ + if (tdep->ppc_vr0_regnum > 0 && tdep->ppc_vrsave_regnum > 0) + { + /* Call-saved Altivec registers. */ + if ((regnum >= tdep->ppc_vr0_regnum + 20 + && regnum <= tdep->ppc_vr0_regnum + 31) + || regnum == tdep->ppc_vrsave_regnum) + reg->how = DWARF2_FRAME_REG_SAME_VALUE; + + /* Call-clobbered Altivec registers. */ + if ((regnum >= tdep->ppc_vr0_regnum + && regnum <= tdep->ppc_vr0_regnum + 19)) + reg->how = DWARF2_FRAME_REG_UNDEFINED; + } + + /* Handle PC register and Stack Pointer correctly. */ + if (regnum == gdbarch_pc_regnum (gdbarch)) + reg->how = DWARF2_FRAME_REG_RA; + else if (regnum == gdbarch_sp_regnum (gdbarch)) + reg->how = DWARF2_FRAME_REG_CFA; +} + + /* Initialize the current architecture based on INFO. If possible, re-use an architecture from ARCHES, which is a list of architectures already created during this debugging session. @@ -3057,14 +2768,19 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { struct gdbarch *gdbarch; struct gdbarch_tdep *tdep; - int wordsize, from_xcoff_exec, from_elf_exec, i, off; - struct reg *regs; - const struct variant *v; + int wordsize, from_xcoff_exec, from_elf_exec; enum bfd_architecture arch; unsigned long mach; bfd abfd; - int sysv_abi; asection *sect; + enum auto_boolean soft_float_flag = powerpc_soft_float_global; + int soft_float; + enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global; + int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0; + int tdesc_wordsize = -1; + const struct target_desc *tdesc = info.target_desc; + struct tdesc_arch_data *tdesc_data = NULL; + int num_pseudoregs = 0; from_xcoff_exec = info.abfd && info.abfd->format == bfd_object && bfd_get_flavour (info.abfd) == bfd_target_xcoff_flavour; @@ -3072,8 +2788,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) from_elf_exec = info.abfd && info.abfd->format == bfd_object && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour; - sysv_abi = info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour; - /* Check word size. If INFO is from a binary file, infer it from that, else choose a likely default. */ if (from_xcoff_exec) @@ -3090,6 +2804,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) else wordsize = 4; } + else if (tdesc_has_registers (tdesc)) + wordsize = -1; else { if (info.bfd_arch_info != NULL && info.bfd_arch_info->bits_per_word != 0) @@ -3099,6 +2815,302 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) wordsize = 4; } + /* Get the architecture and machine from the BFD. */ + arch = info.bfd_arch_info->arch; + mach = info.bfd_arch_info->mach; + + /* For e500 executables, the apuinfo section is of help here. Such + section contains the identifier and revision number of each + Application-specific Processing Unit that is present on the + chip. The content of the section is determined by the assembler + which looks at each instruction and determines which unit (and + which version of it) can execute it. In our case we just look for + the existance of the section. */ + + if (info.abfd) + { + sect = bfd_get_section_by_name (info.abfd, ".PPC.EMB.apuinfo"); + if (sect) + { + arch = info.bfd_arch_info->arch; + mach = bfd_mach_ppc_e500; + bfd_default_set_arch_mach (&abfd, arch, mach); + info.bfd_arch_info = bfd_get_arch_info (&abfd); + } + } + + /* Find a default target description which describes our register + layout, if we do not already have one. */ + if (! tdesc_has_registers (tdesc)) + { + const struct variant *v; + + /* Choose variant. */ + v = find_variant_by_arch (arch, mach); + if (!v) + return NULL; + + tdesc = *v->tdesc; + } + + gdb_assert (tdesc_has_registers (tdesc)); + + /* Check any target description for validity. */ + if (tdesc_has_registers (tdesc)) + { + static const char *const gprs[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" + }; + static const char *const segment_regs[] = { + "sr0", "sr1", "sr2", "sr3", "sr4", "sr5", "sr6", "sr7", + "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15" + }; + const struct tdesc_feature *feature; + int i, valid_p; + static const char *const msr_names[] = { "msr", "ps" }; + static const char *const cr_names[] = { "cr", "cnd" }; + static const char *const ctr_names[] = { "ctr", "cnt" }; + + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.core"); + if (feature == NULL) + return NULL; + + tdesc_data = tdesc_data_alloc (); + + valid_p = 1; + for (i = 0; i < ppc_num_gprs; i++) + valid_p &= tdesc_numbered_register (feature, tdesc_data, i, gprs[i]); + valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_PC_REGNUM, + "pc"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_LR_REGNUM, + "lr"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_XER_REGNUM, + "xer"); + + /* Allow alternate names for these registers, to accomodate GDB's + historic naming. */ + valid_p &= tdesc_numbered_register_choices (feature, tdesc_data, + PPC_MSR_REGNUM, msr_names); + valid_p &= tdesc_numbered_register_choices (feature, tdesc_data, + PPC_CR_REGNUM, cr_names); + valid_p &= tdesc_numbered_register_choices (feature, tdesc_data, + PPC_CTR_REGNUM, ctr_names); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + + have_mq = tdesc_numbered_register (feature, tdesc_data, PPC_MQ_REGNUM, + "mq"); + + tdesc_wordsize = tdesc_register_size (feature, "pc") / 8; + if (wordsize == -1) + wordsize = tdesc_wordsize; + + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.fpu"); + if (feature != NULL) + { + static const char *const fprs[] = { + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" + }; + valid_p = 1; + for (i = 0; i < ppc_num_fprs; i++) + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_F0_REGNUM + i, fprs[i]); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_FPSCR_REGNUM, "fpscr"); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + have_fpu = 1; + } + else + have_fpu = 0; + + /* The DFP pseudo-registers will be available when there are floating + point registers. */ + have_dfp = have_fpu; + + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.altivec"); + if (feature != NULL) + { + static const char *const vector_regs[] = { + "vr0", "vr1", "vr2", "vr3", "vr4", "vr5", "vr6", "vr7", + "vr8", "vr9", "vr10", "vr11", "vr12", "vr13", "vr14", "vr15", + "vr16", "vr17", "vr18", "vr19", "vr20", "vr21", "vr22", "vr23", + "vr24", "vr25", "vr26", "vr27", "vr28", "vr29", "vr30", "vr31" + }; + + valid_p = 1; + for (i = 0; i < ppc_num_gprs; i++) + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_VR0_REGNUM + i, + vector_regs[i]); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_VSCR_REGNUM, "vscr"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_VRSAVE_REGNUM, "vrsave"); + + if (have_spe || !valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + have_altivec = 1; + } + else + have_altivec = 0; + + /* On machines supporting the SPE APU, the general-purpose registers + are 64 bits long. There are SIMD vector instructions to treat them + as pairs of floats, but the rest of the instruction set treats them + as 32-bit registers, and only operates on their lower halves. + + In the GDB regcache, we treat their high and low halves as separate + registers. The low halves we present as the general-purpose + registers, and then we have pseudo-registers that stitch together + the upper and lower halves and present them as pseudo-registers. + + Thus, the target description is expected to supply the upper + halves separately. */ + + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.spe"); + if (feature != NULL) + { + static const char *const upper_spe[] = { + "ev0h", "ev1h", "ev2h", "ev3h", + "ev4h", "ev5h", "ev6h", "ev7h", + "ev8h", "ev9h", "ev10h", "ev11h", + "ev12h", "ev13h", "ev14h", "ev15h", + "ev16h", "ev17h", "ev18h", "ev19h", + "ev20h", "ev21h", "ev22h", "ev23h", + "ev24h", "ev25h", "ev26h", "ev27h", + "ev28h", "ev29h", "ev30h", "ev31h" + }; + + valid_p = 1; + for (i = 0; i < ppc_num_gprs; i++) + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_SPE_UPPER_GP0_REGNUM + i, + upper_spe[i]); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_SPE_ACC_REGNUM, "acc"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_SPE_FSCR_REGNUM, "spefscr"); + + if (have_mq || have_fpu || !valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + have_spe = 1; + } + else + have_spe = 0; + } + + /* If we have a 64-bit binary on a 32-bit target, complain. Also + complain for a 32-bit binary on a 64-bit target; we do not yet + support that. For instance, the 32-bit ABI routines expect + 32-bit GPRs. + + As long as there isn't an explicit target description, we'll + choose one based on the BFD architecture and get a word size + matching the binary (probably powerpc:common or + powerpc:common64). So there is only trouble if a 64-bit target + supplies a 64-bit description while debugging a 32-bit + binary. */ + if (tdesc_wordsize != -1 && tdesc_wordsize != wordsize) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + +#ifdef HAVE_ELF + if (soft_float_flag == AUTO_BOOLEAN_AUTO && from_elf_exec) + { + switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU, + Tag_GNU_Power_ABI_FP)) + { + case 1: + soft_float_flag = AUTO_BOOLEAN_FALSE; + break; + case 2: + soft_float_flag = AUTO_BOOLEAN_TRUE; + break; + default: + break; + } + } + + if (vector_abi == POWERPC_VEC_AUTO && from_elf_exec) + { + switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU, + Tag_GNU_Power_ABI_Vector)) + { + case 1: + vector_abi = POWERPC_VEC_GENERIC; + break; + case 2: + vector_abi = POWERPC_VEC_ALTIVEC; + break; + case 3: + vector_abi = POWERPC_VEC_SPE; + break; + default: + break; + } + } +#endif + + if (soft_float_flag == AUTO_BOOLEAN_TRUE) + soft_float = 1; + else if (soft_float_flag == AUTO_BOOLEAN_FALSE) + soft_float = 0; + else + soft_float = !have_fpu; + + /* If we have a hard float binary or setting but no floating point + registers, downgrade to soft float anyway. We're still somewhat + useful in this scenario. */ + if (!soft_float && !have_fpu) + soft_float = 1; + + /* Similarly for vector registers. */ + if (vector_abi == POWERPC_VEC_ALTIVEC && !have_altivec) + vector_abi = POWERPC_VEC_GENERIC; + + if (vector_abi == POWERPC_VEC_SPE && !have_spe) + vector_abi = POWERPC_VEC_GENERIC; + + if (vector_abi == POWERPC_VEC_AUTO) + { + if (have_altivec) + vector_abi = POWERPC_VEC_ALTIVEC; + else if (have_spe) + vector_abi = POWERPC_VEC_SPE; + else + vector_abi = POWERPC_VEC_GENERIC; + } + + /* Do not limit the vector ABI based on available hardware, since we + do not yet know what hardware we'll decide we have. Yuck! FIXME! */ + /* Find a candidate among extant architectures. */ for (arches = gdbarch_list_lookup_by_info (arches, &info); arches != NULL; @@ -3108,8 +3120,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) meaningful, because 64-bit CPUs can run in 32-bit mode. So, perform separate word size check. */ tdep = gdbarch_tdep (arches->gdbarch); + if (tdep && tdep->soft_float != soft_float) + continue; + if (tdep && tdep->vector_abi != vector_abi) + continue; if (tdep && tdep->wordsize == wordsize) - return arches->gdbarch; + { + if (tdesc_data != NULL) + tdesc_data_cleanup (tdesc_data); + return arches->gdbarch; + } } /* None found, create a new architecture from INFO, whose bfd_arch_info @@ -3120,145 +3140,59 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) - "set arch" trust blindly - GDB startup useless but harmless */ - if (!from_xcoff_exec) - { - arch = info.bfd_arch_info->arch; - mach = info.bfd_arch_info->mach; - } - else - { - arch = bfd_arch_powerpc; - bfd_default_set_arch_mach (&abfd, arch, 0); - info.bfd_arch_info = bfd_get_arch_info (&abfd); - mach = info.bfd_arch_info->mach; - } - tdep = xmalloc (sizeof (struct gdbarch_tdep)); + tdep = XCALLOC (1, struct gdbarch_tdep); tdep->wordsize = wordsize; - - /* For e500 executables, the apuinfo section is of help here. Such - section contains the identifier and revision number of each - Application-specific Processing Unit that is present on the - chip. The content of the section is determined by the assembler - which looks at each instruction and determines which unit (and - which version of it) can execute it. In our case we just look for - the existance of the section. */ - - if (info.abfd) - { - sect = bfd_get_section_by_name (info.abfd, ".PPC.EMB.apuinfo"); - if (sect) - { - arch = info.bfd_arch_info->arch; - mach = bfd_mach_ppc_e500; - bfd_default_set_arch_mach (&abfd, arch, mach); - info.bfd_arch_info = bfd_get_arch_info (&abfd); - } - } + tdep->soft_float = soft_float; + tdep->vector_abi = vector_abi; gdbarch = gdbarch_alloc (&info, tdep); - /* Initialize the number of real and pseudo registers in each variant. */ - init_variants (); - - /* Choose variant. */ - v = find_variant_by_arch (arch, mach); - if (!v) - return NULL; - - tdep->regs = v->regs; - - tdep->ppc_gp0_regnum = 0; - tdep->ppc_toc_regnum = 2; - tdep->ppc_ps_regnum = 65; - tdep->ppc_cr_regnum = 66; - tdep->ppc_lr_regnum = 67; - tdep->ppc_ctr_regnum = 68; - tdep->ppc_xer_regnum = 69; - if (v->mach == bfd_mach_ppc_601) - tdep->ppc_mq_regnum = 124; - else if (arch == bfd_arch_rs6000) - tdep->ppc_mq_regnum = 70; - else - tdep->ppc_mq_regnum = -1; - tdep->ppc_fp0_regnum = 32; - tdep->ppc_fpscr_regnum = (arch == bfd_arch_rs6000) ? 71 : 70; - tdep->ppc_sr0_regnum = 71; - tdep->ppc_vr0_regnum = -1; - tdep->ppc_vrsave_regnum = -1; - tdep->ppc_ev0_upper_regnum = -1; - tdep->ppc_ev0_regnum = -1; - tdep->ppc_ev31_regnum = -1; - tdep->ppc_acc_regnum = -1; - tdep->ppc_spefscr_regnum = -1; - - set_gdbarch_pc_regnum (gdbarch, 64); - set_gdbarch_sp_regnum (gdbarch, 1); - set_gdbarch_deprecated_fp_regnum (gdbarch, 1); + tdep->ppc_gp0_regnum = PPC_R0_REGNUM; + tdep->ppc_toc_regnum = PPC_R0_REGNUM + 2; + tdep->ppc_ps_regnum = PPC_MSR_REGNUM; + tdep->ppc_cr_regnum = PPC_CR_REGNUM; + tdep->ppc_lr_regnum = PPC_LR_REGNUM; + tdep->ppc_ctr_regnum = PPC_CTR_REGNUM; + tdep->ppc_xer_regnum = PPC_XER_REGNUM; + tdep->ppc_mq_regnum = have_mq ? PPC_MQ_REGNUM : -1; + + tdep->ppc_fp0_regnum = have_fpu ? PPC_F0_REGNUM : -1; + tdep->ppc_fpscr_regnum = have_fpu ? PPC_FPSCR_REGNUM : -1; + tdep->ppc_vr0_regnum = have_altivec ? PPC_VR0_REGNUM : -1; + tdep->ppc_vrsave_regnum = have_altivec ? PPC_VRSAVE_REGNUM : -1; + tdep->ppc_ev0_upper_regnum = have_spe ? PPC_SPE_UPPER_GP0_REGNUM : -1; + tdep->ppc_acc_regnum = have_spe ? PPC_SPE_ACC_REGNUM : -1; + tdep->ppc_spefscr_regnum = have_spe ? PPC_SPE_FSCR_REGNUM : -1; + + set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM); + set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1); + set_gdbarch_deprecated_fp_regnum (gdbarch, PPC_R0_REGNUM + 1); + set_gdbarch_fp0_regnum (gdbarch, tdep->ppc_fp0_regnum); set_gdbarch_register_sim_regno (gdbarch, rs6000_register_sim_regno); - if (sysv_abi && wordsize == 8) + + /* The XML specification for PowerPC sensibly calls the MSR "msr". + GDB traditionally called it "ps", though, so let GDB add an + alias. */ + set_gdbarch_ps_regnum (gdbarch, tdep->ppc_ps_regnum); + + if (wordsize == 8) set_gdbarch_return_value (gdbarch, ppc64_sysv_abi_return_value); - else if (sysv_abi && wordsize == 4) - set_gdbarch_return_value (gdbarch, ppc_sysv_abi_return_value); else - { - set_gdbarch_deprecated_extract_return_value (gdbarch, rs6000_extract_return_value); - set_gdbarch_store_return_value (gdbarch, rs6000_store_return_value); - } + set_gdbarch_return_value (gdbarch, ppc_sysv_abi_return_value); /* Set lr_frame_offset. */ if (wordsize == 8) tdep->lr_frame_offset = 16; - else if (sysv_abi) - tdep->lr_frame_offset = 4; else - tdep->lr_frame_offset = 8; - - if (v->arch == bfd_arch_rs6000) - tdep->ppc_sr0_regnum = -1; - else if (v->arch == bfd_arch_powerpc) - switch (v->mach) - { - case bfd_mach_ppc: - tdep->ppc_sr0_regnum = -1; - tdep->ppc_vr0_regnum = 71; - tdep->ppc_vrsave_regnum = 104; - break; - case bfd_mach_ppc_7400: - tdep->ppc_vr0_regnum = 119; - tdep->ppc_vrsave_regnum = 152; - break; - case bfd_mach_ppc_e500: - tdep->ppc_toc_regnum = -1; - tdep->ppc_ev0_upper_regnum = 32; - tdep->ppc_ev0_regnum = 73; - tdep->ppc_ev31_regnum = 104; - tdep->ppc_acc_regnum = 71; - tdep->ppc_spefscr_regnum = 72; - tdep->ppc_fp0_regnum = -1; - tdep->ppc_fpscr_regnum = -1; - tdep->ppc_sr0_regnum = -1; - set_gdbarch_pseudo_register_read (gdbarch, e500_pseudo_register_read); - set_gdbarch_pseudo_register_write (gdbarch, e500_pseudo_register_write); - set_gdbarch_register_reggroup_p (gdbarch, e500_register_reggroup_p); - break; + tdep->lr_frame_offset = 4; - case bfd_mach_ppc64: - case bfd_mach_ppc_620: - case bfd_mach_ppc_630: - case bfd_mach_ppc_a35: - case bfd_mach_ppc_rs64ii: - case bfd_mach_ppc_rs64iii: - /* These processor's register sets don't have segment registers. */ - tdep->ppc_sr0_regnum = -1; - break; - } - else - internal_error (__FILE__, __LINE__, - "rs6000_gdbarch_init: " - "received unexpected BFD 'arch' value"); + if (have_spe || have_dfp) + { + set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, rs6000_pseudo_register_write); + } - /* Sanity check on registers. */ - gdb_assert (strcmp (tdep->regs[tdep->ppc_gp0_regnum].name, "r0") == 0); + set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); /* Select instruction printer. */ if (arch == bfd_arch_rs6000) @@ -3266,13 +3200,14 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) else set_gdbarch_print_insn (gdbarch, gdb_print_insn_powerpc); - set_gdbarch_write_pc (gdbarch, generic_target_write_pc); + set_gdbarch_num_regs (gdbarch, PPC_NUM_REGS); - set_gdbarch_num_regs (gdbarch, v->nregs); - set_gdbarch_num_pseudo_regs (gdbarch, v->npregs); - set_gdbarch_register_name (gdbarch, rs6000_register_name); - set_gdbarch_register_type (gdbarch, rs6000_register_type); - set_gdbarch_register_reggroup_p (gdbarch, rs6000_register_reggroup_p); + if (have_spe) + num_pseudoregs += 32; + if (have_dfp) + num_pseudoregs += 16; + + set_gdbarch_num_pseudo_regs (gdbarch, num_pseudoregs); set_gdbarch_ptr_bit (gdbarch, wordsize * TARGET_CHAR_BIT); set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT); @@ -3281,22 +3216,13 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT); set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT); set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); - if (sysv_abi) - set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT); - else - set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); + set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT); set_gdbarch_char_signed (gdbarch, 0); set_gdbarch_frame_align (gdbarch, rs6000_frame_align); - if (sysv_abi && wordsize == 8) + if (wordsize == 8) /* PPC64 SYSV. */ set_gdbarch_frame_red_zone_size (gdbarch, 288); - else if (!sysv_abi && wordsize == 4) - /* PowerOpen / AIX 32 bit. The saved area or red zone consists of - 19 4 byte GPRS + 18 8 byte FPRs giving a total of 220 bytes. - Problem is, 220 isn't frame (16 byte) aligned. Round it up to - 224. */ - set_gdbarch_frame_red_zone_size (gdbarch, 224); set_gdbarch_convert_register_p (gdbarch, rs6000_convert_register_p); set_gdbarch_register_to_value (gdbarch, rs6000_register_to_value); @@ -3304,94 +3230,105 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_stab_reg_to_regnum (gdbarch, rs6000_stab_reg_to_regnum); set_gdbarch_dwarf2_reg_to_regnum (gdbarch, rs6000_dwarf2_reg_to_regnum); - /* Note: kevinb/2002-04-12: I'm not convinced that rs6000_push_arguments() - is correct for the SysV ABI when the wordsize is 8, but I'm also - fairly certain that ppc_sysv_abi_push_arguments() will give even - worse results since it only works for 32-bit code. So, for the moment, - we're better off calling rs6000_push_arguments() since it works for - 64-bit code. At some point in the future, this matter needs to be - revisited. */ - if (sysv_abi && wordsize == 4) + + if (wordsize == 4) set_gdbarch_push_dummy_call (gdbarch, ppc_sysv_abi_push_dummy_call); - else if (sysv_abi && wordsize == 8) + else if (wordsize == 8) set_gdbarch_push_dummy_call (gdbarch, ppc64_sysv_abi_push_dummy_call); - else - set_gdbarch_push_dummy_call (gdbarch, rs6000_push_dummy_call); - - set_gdbarch_deprecated_extract_struct_value_address (gdbarch, rs6000_extract_struct_value_address); set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue); + set_gdbarch_in_function_epilogue_p (gdbarch, rs6000_in_function_epilogue_p); + set_gdbarch_inner_than (gdbarch, core_addr_lessthan); set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc); - /* Handle the 64-bit SVR4 minimal-symbol convention of using "FN" - for the descriptor and ".FN" for the entry-point -- a user - specifying "break FN" will unexpectedly end up with a breakpoint - on the descriptor and not the function. This architecture method - transforms any breakpoints on descriptors into breakpoints on the - corresponding entry point. */ - if (sysv_abi && wordsize == 8) - set_gdbarch_adjust_breakpoint_address (gdbarch, ppc64_sysv_abi_adjust_breakpoint_address); + /* The value of symbols of type N_SO and N_FUN maybe null when + it shouldn't be. */ + set_gdbarch_sofun_address_maybe_missing (gdbarch, 1); + /* Handles single stepping of atomic sequences. */ + set_gdbarch_software_single_step (gdbarch, ppc_deal_with_atomic_sequence); + /* Not sure on this. FIXMEmgo */ set_gdbarch_frame_args_skip (gdbarch, 8); - if (!sysv_abi) - set_gdbarch_deprecated_use_struct_convention (gdbarch, rs6000_use_struct_convention); - - if (!sysv_abi) - { - /* Handle RS/6000 function pointers (which are really function - descriptors). */ - set_gdbarch_convert_from_func_ptr_addr (gdbarch, - rs6000_convert_from_func_ptr_addr); - } - /* Helpers for function argument information. */ set_gdbarch_fetch_pointer_argument (gdbarch, rs6000_fetch_pointer_argument); + /* Trampoline. */ + set_gdbarch_in_solib_return_trampoline + (gdbarch, rs6000_in_solib_return_trampoline); + set_gdbarch_skip_trampoline_code (gdbarch, rs6000_skip_trampoline_code); + + /* Hook in the DWARF CFI frame unwinder. */ + dwarf2_append_unwinders (gdbarch); + dwarf2_frame_set_adjust_regnum (gdbarch, rs6000_adjust_frame_regnum); + + /* Frame handling. */ + dwarf2_frame_set_init_reg (gdbarch, ppc_dwarf2_frame_init_reg); + /* Hook in ABI-specific overrides, if they have been registered. */ + info.target_desc = tdesc; + info.tdep_info = (void *) tdesc_data; gdbarch_init_osabi (info, gdbarch); switch (info.osabi) { + case GDB_OSABI_LINUX: case GDB_OSABI_NETBSD_AOUT: case GDB_OSABI_NETBSD_ELF: case GDB_OSABI_UNKNOWN: - case GDB_OSABI_LINUX: set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc); - frame_unwind_append_sniffer (gdbarch, rs6000_frame_sniffer); - set_gdbarch_unwind_dummy_id (gdbarch, rs6000_unwind_dummy_id); + frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind); + set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id); frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer); break; default: set_gdbarch_believe_pcc_promotion (gdbarch, 1); set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc); - frame_unwind_append_sniffer (gdbarch, rs6000_frame_sniffer); - set_gdbarch_unwind_dummy_id (gdbarch, rs6000_unwind_dummy_id); + frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind); + set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id); frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer); } - if (from_xcoff_exec) - { - /* NOTE: jimix/2003-06-09: This test should really check for - GDB_OSABI_AIX when that is defined and becomes - available. (Actually, once things are properly split apart, - the test goes away.) */ - /* RS6000/AIX does not support PT_STEP. Has to be simulated. */ - set_gdbarch_software_single_step (gdbarch, rs6000_software_single_step); - } + set_tdesc_pseudo_register_type (gdbarch, rs6000_pseudo_register_type); + set_tdesc_pseudo_register_reggroup_p (gdbarch, + rs6000_pseudo_register_reggroup_p); + tdesc_use_registers (gdbarch, tdesc, tdesc_data); + + /* Override the normal target description method to make the SPE upper + halves anonymous. */ + set_gdbarch_register_name (gdbarch, rs6000_register_name); - init_sim_regno_table (gdbarch); + /* Recording the numbering of pseudo registers. */ + tdep->ppc_ev0_regnum = have_spe ? gdbarch_num_regs (gdbarch) : -1; + + /* Set the register number for _Decimal128 pseudo-registers. */ + tdep->ppc_dl0_regnum = have_dfp? gdbarch_num_regs (gdbarch) : -1; + + if (have_dfp && have_spe) + /* Put the _Decimal128 pseudo-registers after the SPE registers. */ + tdep->ppc_dl0_regnum += 32; + + /* Setup displaced stepping. */ + set_gdbarch_displaced_step_copy_insn (gdbarch, + simple_displaced_step_copy_insn); + set_gdbarch_displaced_step_fixup (gdbarch, ppc_displaced_step_fixup); + set_gdbarch_displaced_step_free_closure (gdbarch, + simple_displaced_step_free_closure); + set_gdbarch_displaced_step_location (gdbarch, + displaced_step_at_entry_point); + + set_gdbarch_max_insn_length (gdbarch, PPC_INSN_SIZE); return gdbarch; } static void -rs6000_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) +rs6000_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (tdep == NULL) return; @@ -3399,12 +3336,59 @@ rs6000_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) /* FIXME: Dump gdbarch_tdep. */ } -static struct cmd_list_element *info_powerpc_cmdlist = NULL; +/* PowerPC-specific commands. */ + +static void +set_powerpc_command (char *args, int from_tty) +{ + printf_unfiltered (_("\ +\"set powerpc\" must be followed by an appropriate subcommand.\n")); + help_list (setpowerpccmdlist, "set powerpc ", all_commands, gdb_stdout); +} + +static void +show_powerpc_command (char *args, int from_tty) +{ + cmd_show_list (showpowerpccmdlist, from_tty, ""); +} + +static void +powerpc_set_soft_float (char *args, int from_tty, + struct cmd_list_element *c) +{ + struct gdbarch_info info; + + /* Update the architecture. */ + gdbarch_info_init (&info); + if (!gdbarch_update_p (info)) + internal_error (__FILE__, __LINE__, "could not update architecture"); +} static void -rs6000_info_powerpc_command (char *args, int from_tty) +powerpc_set_vector_abi (char *args, int from_tty, + struct cmd_list_element *c) { - help_list (info_powerpc_cmdlist, "info powerpc ", class_info, gdb_stdout); + struct gdbarch_info info; + enum powerpc_vector_abi vector_abi; + + for (vector_abi = POWERPC_VEC_AUTO; + vector_abi != POWERPC_VEC_LAST; + vector_abi++) + if (strcmp (powerpc_vector_abi_string, + powerpc_vector_strings[vector_abi]) == 0) + { + powerpc_vector_abi_global = vector_abi; + break; + } + + if (vector_abi == POWERPC_VEC_LAST) + internal_error (__FILE__, __LINE__, _("Invalid vector ABI accepted: %s."), + powerpc_vector_abi_string); + + /* Update the architecture. */ + gdbarch_info_init (&info); + if (!gdbarch_update_p (info)) + internal_error (__FILE__, __LINE__, "could not update architecture"); } /* Initialization code. */ @@ -3417,8 +3401,47 @@ _initialize_rs6000_tdep (void) gdbarch_register (bfd_arch_rs6000, rs6000_gdbarch_init, rs6000_dump_tdep); gdbarch_register (bfd_arch_powerpc, rs6000_gdbarch_init, rs6000_dump_tdep); - /* Add root prefix command for "info powerpc" commands */ - add_prefix_cmd ("powerpc", class_info, rs6000_info_powerpc_command, - "Various POWERPC info specific commands.", - &info_powerpc_cmdlist, "info powerpc ", 0, &infolist); + /* Initialize the standard target descriptions. */ + initialize_tdesc_powerpc_32 (); + initialize_tdesc_powerpc_altivec32 (); + initialize_tdesc_powerpc_403 (); + initialize_tdesc_powerpc_403gc (); + initialize_tdesc_powerpc_505 (); + initialize_tdesc_powerpc_601 (); + initialize_tdesc_powerpc_602 (); + initialize_tdesc_powerpc_603 (); + initialize_tdesc_powerpc_604 (); + initialize_tdesc_powerpc_64 (); + initialize_tdesc_powerpc_altivec64 (); + initialize_tdesc_powerpc_7400 (); + initialize_tdesc_powerpc_750 (); + initialize_tdesc_powerpc_860 (); + initialize_tdesc_powerpc_e500 (); + initialize_tdesc_rs6000 (); + + /* Add root prefix command for all "set powerpc"/"show powerpc" + commands. */ + add_prefix_cmd ("powerpc", no_class, set_powerpc_command, + _("Various PowerPC-specific commands."), + &setpowerpccmdlist, "set powerpc ", 0, &setlist); + + add_prefix_cmd ("powerpc", no_class, show_powerpc_command, + _("Various PowerPC-specific commands."), + &showpowerpccmdlist, "show powerpc ", 0, &showlist); + + /* Add a command to allow the user to force the ABI. */ + add_setshow_auto_boolean_cmd ("soft-float", class_support, + &powerpc_soft_float_global, + _("Set whether to use a soft-float ABI."), + _("Show whether to use a soft-float ABI."), + NULL, + powerpc_set_soft_float, NULL, + &setpowerpccmdlist, &showpowerpccmdlist); + + add_setshow_enum_cmd ("vector-abi", class_support, powerpc_vector_strings, + &powerpc_vector_abi_string, + _("Set the vector ABI."), + _("Show the vector ABI."), + NULL, powerpc_set_vector_abi, NULL, + &setpowerpccmdlist, &showpowerpccmdlist); }