Re: [PATCH-ppc 1/5] Add basic support for new VSX register set

Luis Machado
2008-08-08T15:22:37Z

The changelog is a bit bogus in here, i forgot to include the new
"ppc_num_vshrs" constant i defined. I have that fixed already though.
Will send it again after some comments.

On Fri, 2008-08-08 at 12:10 -0300, Luis Machado wrote:
> Patch updated.
>
> > > /* Constants for register set sizes. */
> > > enum
> > > {
> > > - ppc_num_gprs = 32, /* 32 general-purpose registers */
> > > - ppc_num_fprs = 32, /* 32 floating-point registers */
> > > - ppc_num_srs = 16, /* 16 segment registers */
> > > - ppc_num_vrs = 32 /* 32 Altivec vector registers */
> > > + ppc_num_gprs = 32, /* 32 general-purpose registers. */
> > > + ppc_num_fprs = 32, /* 32 floating-point registers. */
> > > + ppc_num_srs = 16, /* 16 segment registers. */
> > > + ppc_num_vrs = 32, /* 32 Altivec vector registers. */
> > > + ppc_num_vsrs = 64, /* 64 VSX vector registers. */
> > > + ppc_num_efprs = 32 /* 32 Extended FP registers. */
> > > };
> >
> > Why change the column of all the comments here?
>
> Identation is broken (mixed tab/blank space). They're fixed now. If you
> want, i can leave it broken and fix only the ones i care for this patch.
>
> > > /* Linux target descriptions. */
> > > extern struct target_desc *tdesc_powerpc_32l;
> > > extern struct target_desc *tdesc_powerpc_altivec32l;
> > > +extern struct target_desc *tdesc_powerpc_vsx32l;
> > > extern struct target_desc *tdesc_powerpc_e500l;
> > > extern struct target_desc *tdesc_powerpc_64l;
> > > extern struct target_desc *tdesc_powerpc_altivec64l;
> > > -
> > > +extern struct target_desc *tdesc_powerpc_vsx64l;
> > > #endif /* PPC_LINUX_TDEP_H */
> >
> > I know this is very picky, but I'd preserve the blank line before
> > #endif.
>
> The blank line is back.
>
>
> ---
> 2008-08-08 Luis Machado <luisgpm@br.ibm.com>
>
> * rs6000-tdep: Include "features/rs6000/powerpc-vsx32.c".
> Include "features/rs6000/powerpc-vsx64.c".
> (ppc_supply_vsxregset): New function.
> (ppc_collect_vsxregset): New function.
> (IS_VSX_PSEUDOREG): New macro.
> (IS_EFP_PSEUDOREG): New macro.
> (vsx_register_p): New function.
> (ppc_vsx_support_p): New function.
> (rs6000_builtin_type_vec128): New function.
> (rs6000_register_name): Hide upper halves of vs0~vs31. Return
> correct names for VSX registers and EFPR registers.
> (rs6000_pseudo_register_type): Return correct types for VSX
> and EFPR registers.
> (rs6000_pseudo_register_reggroup_p): Return correct group for
> VSX and EFPR registers.
> (ppc_pseudo_register_read): Rename to dfp_pseudo_register_read.
> (ppc_pseudo_register_write): Rename to dfp_pseudo_register_write.
> (vsx_pseudo_register_read): New function.
> (vsx_pseudo_register_write): New function.
> (efpr_pseudo_register_read): New function.
> (efpr_pseudo_register_write): New function.
> (rs6000_pseudo_register_read): Call new VSX and EFPR read functions.
> (rs6000_pseudo_register_write): Call new VSX and EFPR write functions.
> (rs6000_gdbarch_init): Declare have_vsx.
> Initialize new upper half VSX registers.
> Initialize VSX-related and EFPR-related pseudo-registers variables.
> Adjust the number of pseudo registers accordingly.
>
> * ppc-linux-nat.c: Define PTRACE_GETVSXREGS, PTRACE_SETVSXREGS
> and SIZEOF_VSRREGS.
> (gdb_vsxregset_t): New type.
> (have_ptrace_getsetvsxregs): New variable.
> (fetch_vsx_register): New function.
> (fetch_register): Handle VSX registers.
> (fetch_vsx_registers): New function.
> (fetch_ppc_registers): Handle VSX registers.
> (store_ppc_registers): Handle VSX registers.
> (store_vsx_register): New function.
> (store_register): Handle VSX registers.
> (store_vsx_registers): New function.
> (ppc_linux_read_description): Handle VSX-enabled inferiors.
> (gdb_vsxregset_t): New type.
> (supply_vsxregset): New function.
> (fill_vsxregset): New function.
>
> * ppc-tdep.h (vsx_register_p): New prototype.
> (vsx_support_p): New prototype.
> (ppc_vsr0_regnum): New variable.
> (ppc_vsr0_upper_regnum): Likewise.
> (ppc_efpr0_regnum): Likewise.
> (ppc_builtin_type_vec128): New type.
> (ppc_num_vsrs): New constant.
> (ppc_num_efprs): Likewise.
> Define POWERPC_VEC_VSX PPC_VSR0_UPPER_REGNUM and PPC_VSR31_UPPER_REGNUM.
> (ppc_supply_vsxregset): New prototype.
> (ppc_collect_vsxregset): New prototype.
>
> * ppc-linux-tdep.c: Include "features/rs6000/powerpc-vsx32l.c"
> Include "features/rs6000/powerpc-vsx64l.c".
> (_initialize_ppc_linux_tdep): Initialize VSX-enabled targets.
>
> * ppc-linux-tdep.h: Declare *tdesc_powerpc_vsx32l
> Declare tdesc_powerpc_vsx64l
>
> Index: gdb/rs6000-tdep.c
> ===================================================================
> --- gdb.orig/rs6000-tdep.c 2008-08-08 07:17:03.000000000 -0700
> +++ gdb/rs6000-tdep.c 2008-08-08 07:17:47.000000000 -0700
> @@ -63,6 +63,7 @@
>
> #include "features/rs6000/powerpc-32.c"
> #include "features/rs6000/powerpc-altivec32.c"
> +#include "features/rs6000/powerpc-vsx32.c"
> #include "features/rs6000/powerpc-403.c"
> #include "features/rs6000/powerpc-403gc.c"
> #include "features/rs6000/powerpc-505.c"
> @@ -72,6 +73,7 @@
> #include "features/rs6000/powerpc-604.c"
> #include "features/rs6000/powerpc-64.c"
> #include "features/rs6000/powerpc-altivec64.c"
> +#include "features/rs6000/powerpc-vsx64.c"
> #include "features/rs6000/powerpc-7400.c"
> #include "features/rs6000/powerpc-750.c"
> #include "features/rs6000/powerpc-860.c"
> @@ -88,6 +90,16 @@
> && (regnum) >= (tdep)->ppc_dl0_regnum \
> && (regnum) < (tdep)->ppc_dl0_regnum + 16)
>
> +/* Determine if regnum is a POWER7 VSX register. */
> +#define IS_VSX_PSEUDOREG(tdep, regnum) ((tdep)->ppc_vsr0_regnum >= 0 \
> + && (regnum) >= (tdep)->ppc_vsr0_regnum \
> + && (regnum) < (tdep)->ppc_vsr0_regnum + ppc_num_vsrs)
> +
> +/* Determine if regnum is a POWER7 Extended FP register. */
> +#define IS_EFP_PSEUDOREG(tdep, regnum) ((tdep)->ppc_efpr0_regnum >= 0 \
> + && (regnum) >= (tdep)->ppc_efpr0_regnum \
> + && (regnum) < (tdep)->ppc_efpr0_regnum + ppc_num_fprs)
> +
> /* The list of available "set powerpc ..." and "show powerpc ..."
> commands. */
> static struct cmd_list_element *setpowerpccmdlist = NULL;
> @@ -133,6 +145,18 @@
> };
>
>
> +/* Is REGNO a VSX register? Return 1 if so, 0 otherwise. */
> +int
> +vsx_register_p (struct gdbarch *gdbarch, int regno)
> +{
> + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> + if (tdep->ppc_vsr0_regnum < 0)
> + return 0;
> + else
> + return (regno >= tdep->ppc_vsr0_upper_regnum && regno
> + <= tdep->ppc_vsr0_upper_regnum + 31);
> +}
> +
> /* Is REGNO an AltiVec register? Return 1 if so, 0 otherwise. */
> int
> altivec_register_p (struct gdbarch *gdbarch, int regno)
> @@ -188,6 +212,16 @@
> }
>
> /* Return non-zero if the architecture described by GDBARCH has
> + VSX registers (vsr0 --- vsr63). */
> +int
> +ppc_vsx_support_p (struct gdbarch *gdbarch)
> +{
> + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> +
> + return tdep->ppc_vsr0_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)
> @@ -539,6 +573,37 @@
> regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
> }
>
> +/* Supply register REGNUM in the VSX register set REGSET
> + from the buffer specified by VSRREGS and LEN to register cache
> + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
> +
> +void
> +ppc_supply_vsxregset (const struct regset *regset, struct regcache *regcache,
> + int regnum, const void *vsxregs, size_t len)
> +{
> + struct gdbarch *gdbarch = get_regcache_arch (regcache);
> + struct gdbarch_tdep *tdep;
> +
> + if (!ppc_vsx_support_p (gdbarch))
> + return;
> +
> + tdep = gdbarch_tdep (gdbarch);
> +
> + if (regnum == -1)
> + {
> + int i;
> +
> + for (i = tdep->ppc_vsr0_upper_regnum;
> + i < tdep->ppc_vsr0_upper_regnum + 32;
> + i++)
> + ppc_supply_reg (regcache, i, vsxregs, 0, 8);
> +
> + return;
> + }
> + else
> + ppc_supply_reg (regcache, regnum, vsxregs, 0, 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. */
> @@ -669,6 +734,40 @@
> regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
> }
>
> +/* Collect register REGNUM in the VSX register set
> + REGSET from register cache REGCACHE into the buffer specified by
> + VSRREGS and LEN. If REGNUM is -1, do this for all registers in
> + REGSET. */
> +
> +void
> +ppc_collect_vsxregset (const struct regset *regset,
> + const struct regcache *regcache,
> + int regnum, void *vsxregs, size_t len)
> +{
> + struct gdbarch *gdbarch = get_regcache_arch (regcache);
> + struct gdbarch_tdep *tdep;
> +
> + if (!ppc_vsx_support_p (gdbarch))
> + return;
> +
> + tdep = gdbarch_tdep (gdbarch);
> +
> + if (regnum == -1)
> + {
> + int i;
> +
> + for (i = tdep->ppc_vsr0_upper_regnum;
> + i < tdep->ppc_vsr0_upper_regnum + 32;
> + i++)
> + ppc_collect_reg (regcache, i, vsxregs, 0, 8);
> +
> + return;
> + }
> + else
> + ppc_collect_reg (regcache, regnum, vsxregs, 0, 8);
> +}
> +
> +
> /* 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
> @@ -1915,6 +2014,47 @@
> return tdep->ppc_builtin_type_vec64;
> }
>
> +/* Vector 128 type. */
> +
> +static struct type *
> +rs6000_builtin_type_vec128 (struct gdbarch *gdbarch)
> +{
> + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> +
> + if (!tdep->ppc_builtin_type_vec128)
> + {
> + /* The type we're building is this
> +
> + type = union __ppc_builtin_type_vec128 {
> + uint128_t uint128;
> + float v4_float[4];
> + int32_t v4_int32[4];
> + int16_t v8_int16[8];
> + int8_t v16_int8[16];
> + }
> + */
> +
> + struct type *t;
> +
> + t = init_composite_type ("__ppc_builtin_type_vec128", TYPE_CODE_UNION);
> + append_composite_type_field (t, "uint128", builtin_type_uint128);
> + append_composite_type_field (t, "v4_float",
> + init_vector_type (builtin_type_float, 4));
> + append_composite_type_field (t, "v4_int32",
> + init_vector_type (builtin_type_int32, 4));
> + append_composite_type_field (t, "v8_int16",
> + init_vector_type (builtin_type_int16, 8));
> + append_composite_type_field (t, "v16_int8",
> + init_vector_type (builtin_type_int8, 16));
> +
> + TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR;
> + TYPE_NAME (t) = "ppc_builtin_type_vec128";
> + tdep->ppc_builtin_type_vec128 = t;
> + }
> +
> + return tdep->ppc_builtin_type_vec128;
> +}
> +
> /* Return the name of register number REGNO, or the empty string if it
> is an anonymous register. */
>
> @@ -1931,6 +2071,12 @@
> && regno < tdep->ppc_ev0_upper_regnum + ppc_num_gprs)
> return "";
>
> + /* Hide the upper halves of the vs0~vs31 registers. */
> + if (tdep->ppc_vsr0_regnum >= 0
> + && tdep->ppc_vsr0_upper_regnum <= regno
> + && regno < tdep->ppc_vsr0_upper_regnum + ppc_num_gprs)
> + return "";
> +
> /* Check if the SPE pseudo registers are available. */
> if (IS_SPE_PSEUDOREG (tdep, regno))
> {
> @@ -1955,6 +2101,36 @@
> return dfp128_regnames[regno - tdep->ppc_dl0_regnum];
> }
>
> + /* Check if this is a VSX pseudo-register. */
> + if (IS_VSX_PSEUDOREG (tdep, regno))
> + {
> + static const char *const vsx_regnames[] = {
> + "vs0", "vs1", "vs2", "vs3", "vs4", "vs5", "vs6", "vs7",
> + "vs8", "vs9", "vs10", "vs11", "vs12", "vs13", "vs14",
> + "vs15", "vs16", "vs17", "vs18", "vs19", "vs20", "vs21",
> + "vs22", "vs23", "vs24", "vs25", "vs26", "vs27", "vs28",
> + "vs29", "vs30", "vs31", "vs32", "vs33", "vs34", "vs35",
> + "vs36", "vs37", "vs38", "vs39", "vs40", "vs41", "vs42",
> + "vs43", "vs44", "vs45", "vs46", "vs47", "vs48", "vs49",
> + "vs50", "vs51", "vs52", "vs53", "vs54", "vs55", "vs56",
> + "vs57", "vs58", "vs59", "vs60", "vs61", "vs62", "vs63"
> + };
> + return vsx_regnames[regno - tdep->ppc_vsr0_regnum];
> + }
> +
> + /* Check if the this is a Extended FP pseudo-register. */
> + if (IS_EFP_PSEUDOREG (tdep, regno))
> + {
> + static const char *const efpr_regnames[] = {
> + "f32", "f33", "f34", "f35", "f36", "f37", "f38",
> + "f39", "f40", "f41", "f42", "f43", "f44", "f45",
> + "f46", "f47", "f48", "f49", "f50", "f51",
> + "f52", "f53", "f54", "f55", "f56", "f57",
> + "f58", "f59", "f60", "f61", "f62", "f63"
> + };
> + return efpr_regnames[regno - tdep->ppc_efpr0_regnum];
> + }
> +
> return tdesc_register_name (gdbarch, regno);
> }
>
> @@ -1968,14 +2144,22 @@
>
> /* These are the only pseudo-registers we support. */
> gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum)
> - || IS_DFP_PSEUDOREG (tdep, regnum));
> + || IS_DFP_PSEUDOREG (tdep, regnum)
> + || IS_VSX_PSEUDOREG (tdep, regnum)
> + || IS_EFP_PSEUDOREG (tdep, regnum));
>
> /* These are the e500 pseudo-registers. */
> if (IS_SPE_PSEUDOREG (tdep, regnum))
> return rs6000_builtin_type_vec64 (gdbarch);
> - else
> - /* Could only be the ppc decimal128 pseudo-registers. */
> + else if (IS_DFP_PSEUDOREG (tdep, regnum))
> + /* PPC decimal128 pseudo-registers. */
> return builtin_type (gdbarch)->builtin_declong;
> + else if (IS_VSX_PSEUDOREG (tdep, regnum))
> + /* POWER7 VSX pseudo-registers. */
> + return rs6000_builtin_type_vec128 (gdbarch);
> + else
> + /* POWER7 Extended FP pseudo-registers. */
> + return builtin_type_ieee_double;
> }
>
> /* Is REGNUM a member of REGGROUP? */
> @@ -1987,13 +2171,15 @@
>
> /* These are the only pseudo-registers we support. */
> gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum)
> - || IS_DFP_PSEUDOREG (tdep, regnum));
> + || IS_DFP_PSEUDOREG (tdep, regnum)
> + || IS_VSX_PSEUDOREG (tdep, regnum)
> + || IS_EFP_PSEUDOREG (tdep, regnum));
>
> - /* These are the e500 pseudo-registers. */
> - if (IS_SPE_PSEUDOREG (tdep, regnum))
> + /* These are the e500 pseudo-registers or the POWER7 VSX registers. */
> + if (IS_SPE_PSEUDOREG (tdep, regnum) || IS_VSX_PSEUDOREG (tdep, regnum))
> return group == all_reggroup || group == vector_reggroup;
> else
> - /* Could only be the ppc decimal128 pseudo-registers. */
> + /* PPC decimal128 or Extended FP pseudo-registers. */
> return group == all_reggroup || group == float_reggroup;
> }
>
> @@ -2107,10 +2293,9 @@
> 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. */
> +/* Read method for DFP pseudo-registers. */
> static void
> -ppc_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
> +dfp_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
> int reg_nr, gdb_byte *buffer)
> {
> struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> @@ -2133,10 +2318,9 @@
> }
> }
>
> -/* Write method for PPC pseudo-registers. Currently this is handling the
> - 16 decimal128 registers that map into 16 pairs of FP registers. */
> +/* Write method for DFP pseudo-registers. */
> static void
> -ppc_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
> +dfp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
> int reg_nr, const gdb_byte *buffer)
> {
> struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> @@ -2160,6 +2344,92 @@
> }
> }
>
> +/* Read method for POWER7 VSX pseudo-registers. */
> +static void
> +vsx_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_vsr0_regnum;
> +
> + /* Read the portion that overlaps the VMX registers. */
> + if (reg_index > 31)
> + regcache_raw_read (regcache, tdep->ppc_vr0_regnum +
> + reg_index - 32, buffer);
> + else
> + /* Read the portion that overlaps the FPR registers. */
> + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
> + {
> + regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
> + reg_index, buffer);
> + regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
> + reg_index, buffer + 8);
> + }
> + else
> + {
> + regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
> + reg_index, buffer + 8);
> + regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
> + reg_index, buffer);
> + }
> +}
> +
> +/* Write method for POWER7 VSX pseudo-registers. */
> +static void
> +vsx_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_vsr0_regnum;
> +
> + /* Write the portion that overlaps the VMX registers. */
> + if (reg_index > 31)
> + regcache_raw_write (regcache, tdep->ppc_vr0_regnum +
> + reg_index - 32, buffer);
> + else
> + /* Write the portion that overlaps the FPR registers. */
> + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
> + {
> + regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
> + reg_index, buffer);
> + regcache_raw_write (regcache, tdep->ppc_vsr0_upper_regnum +
> + reg_index, buffer + 8);
> + }
> + else
> + {
> + regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
> + reg_index, buffer + 8);
> + regcache_raw_write (regcache, tdep->ppc_vsr0_upper_regnum +
> + reg_index, buffer);
> + }
> +}
> +
> +/* Read method for POWER7 Extended FP pseudo-registers. */
> +static void
> +efpr_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_efpr0_regnum;
> +
> + /* Read the portion that overlaps the VMX registers. */
> + regcache_raw_read (regcache, tdep->ppc_vr0_regnum +
> + reg_index, buffer);
> +}
> +
> +/* Write method for POWER7 Extended FP pseudo-registers. */
> +static void
> +efpr_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_efpr0_regnum;
> +
> + /* Write the portion that overlaps the VMX registers. */
> + regcache_raw_write (regcache, tdep->ppc_vr0_regnum +
> + reg_index, buffer);
> +}
> +
> static void
> rs6000_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
> int reg_nr, gdb_byte *buffer)
> @@ -2172,7 +2442,11 @@
> 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);
> + dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
> + else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
> + vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
> + else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
> + efpr_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
> else
> internal_error (__FILE__, __LINE__,
> _("rs6000_pseudo_register_read: "
> @@ -2193,7 +2467,11 @@
> 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);
> + dfp_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
> + else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
> + vsx_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
> + else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
> + efpr_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
> else
> internal_error (__FILE__, __LINE__,
> _("rs6000_pseudo_register_write: "
> @@ -2776,7 +3054,8 @@
> 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 have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0,
> + have_vsx = 0;
> int tdesc_wordsize = -1;
> const struct target_desc *tdesc = info.target_desc;
> struct tdesc_arch_data *tdesc_data = NULL;
> @@ -2975,6 +3254,38 @@
> else
> have_altivec = 0;
>
> + /* Check for POWER7 VSX registers support. */
> + feature = tdesc_find_feature (tdesc,
> + "org.gnu.gdb.power.vsx");
> +
> + if (feature != NULL)
> + {
> + static const char *const vsx_regs[] = {
> + "vs0h", "vs1h", "vs2h", "vs3h", "vs4h", "vs5h",
> + "vs6h", "vs7h", "vs8h", "vs9h", "vs10h", "vs11h",
> + "vs12h", "vs13h", "vs14h", "vs15h", "vs16h", "vs17h",
> + "vs18h", "vs19h", "vs20h", "vs21h", "vs22h", "vs23h",
> + "vs24h", "vs25h", "vs26h", "vs27h", "vs28h", "vs29h",
> + "vs30h", "vs31h"
> + };
> +
> + valid_p = 1;
> +
> + for (i = 0; i < ppc_num_vshrs; i++)
> + valid_p &= tdesc_numbered_register (feature, tdesc_data,
> + PPC_VSR0_UPPER_REGNUM + i,
> + vsx_regs[i]);
> + if (!valid_p)
> + {
> + tdesc_data_cleanup (tdesc_data);
> + return NULL;
> + }
> +
> + have_vsx = 1;
> + }
> + else
> + have_vsx = 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
> @@ -3158,6 +3469,7 @@
>
> tdep->ppc_fp0_regnum = have_fpu ? PPC_F0_REGNUM : -1;
> tdep->ppc_fpscr_regnum = have_fpu ? PPC_FPSCR_REGNUM : -1;
> + tdep->ppc_vsr0_upper_regnum = have_vsx ? PPC_VSR0_UPPER_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;
> @@ -3186,7 +3498,7 @@
> else
> tdep->lr_frame_offset = 4;
>
> - if (have_spe || have_dfp)
> + if (have_spe || have_dfp || have_vsx)
> {
> set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read);
> set_gdbarch_pseudo_register_write (gdbarch, rs6000_pseudo_register_write);
> @@ -3206,6 +3518,9 @@
> num_pseudoregs += 32;
> if (have_dfp)
> num_pseudoregs += 16;
> + if (have_vsx)
> + /* Include both VSX and Extended FP registers. */
> + num_pseudoregs += 96;
>
> set_gdbarch_num_pseudo_regs (gdbarch, num_pseudoregs);
>
> @@ -3307,9 +3622,26 @@
> /* Set the register number for _Decimal128 pseudo-registers. */
> tdep->ppc_dl0_regnum = have_dfp? gdbarch_num_regs (gdbarch) : -1;
>
> + /* Set the register number for VSX pseudo-registers. */
> + tdep->ppc_vsr0_regnum = have_vsx? gdbarch_num_regs (gdbarch) : -1;
> + tdep->ppc_efpr0_regnum = have_vsx? gdbarch_num_regs (gdbarch) : -1;
> +
> if (have_dfp && have_spe)
> - /* Put the _Decimal128 pseudo-registers after the SPE registers. */
> - tdep->ppc_dl0_regnum += 32;
> + {
> + /* Put the _Decimal128 pseudo-registers after the SPE registers. */
> + tdep->ppc_dl0_regnum += 32;
> +
> + if (have_vsx)
> + {
> + tdep->ppc_vsr0_regnum += 48;
> + tdep->ppc_efpr0_regnum += 112;
> + }
> + }
> + else if (have_dfp && have_vsx)
> + {
> + tdep->ppc_vsr0_regnum += 16;
> + tdep->ppc_efpr0_regnum += 80;
> + }
>
> /* Setup displaced stepping. */
> set_gdbarch_displaced_step_copy_insn (gdbarch,
> @@ -3404,6 +3736,7 @@
> /* Initialize the standard target descriptions. */
> initialize_tdesc_powerpc_32 ();
> initialize_tdesc_powerpc_altivec32 ();
> + initialize_tdesc_powerpc_vsx32 ();
> initialize_tdesc_powerpc_403 ();
> initialize_tdesc_powerpc_403gc ();
> initialize_tdesc_powerpc_505 ();
> @@ -3413,6 +3746,7 @@
> initialize_tdesc_powerpc_604 ();
> initialize_tdesc_powerpc_64 ();
> initialize_tdesc_powerpc_altivec64 ();
> + initialize_tdesc_powerpc_vsx64 ();
> initialize_tdesc_powerpc_7400 ();
> initialize_tdesc_powerpc_750 ();
> initialize_tdesc_powerpc_860 ();
> Index: gdb/ppc-linux-nat.c
> ===================================================================
> --- gdb.orig/ppc-linux-nat.c 2008-08-08 07:17:03.000000000 -0700
> +++ gdb/ppc-linux-nat.c 2008-08-08 07:17:47.000000000 -0700
> @@ -68,6 +68,11 @@
> #define PTRACE_SETVRREGS 19
> #endif
>
> +/* PTRACE requests for POWER7 VSX registers. */
> +#ifndef PTRACE_GETVSXREGS
> +#define PTRACE_GETVSXREGS 27
> +#define PTRACE_SETVSXREGS 28
> +#endif
>
> /* Similarly for the ptrace requests for getting / setting the SPE
> registers (ev0 -- ev31, acc, and spefscr). See the description of
> @@ -119,6 +124,41 @@
>
> typedef char gdb_vrregset_t[SIZEOF_VRREGS];
>
> +/* This is the layout of the POWER7 VSX registers and the way they overlap
> + with the existing FPR and VMX registers.
> +
> + VSR doubleword 0 VSR doubleword 1
> + ----------------------------------------------------------------
> + VSR[0] | FPR[0] | |
> + ----------------------------------------------------------------
> + VSR[1] | FPR[1] | |
> + ----------------------------------------------------------------
> + | ... | |
> + | ... | |
> + ----------------------------------------------------------------
> + VSR[30] | FPR[30] | |
> + ----------------------------------------------------------------
> + VSR[31] | FPR[31] | |
> + ----------------------------------------------------------------
> + VSR[32] | VR[0] |
> + ----------------------------------------------------------------
> + VSR[33] | VR[1] |
> + ----------------------------------------------------------------
> + | ... |
> + | ... |
> + ----------------------------------------------------------------
> + VSR[62] | VR[30] |
> + ----------------------------------------------------------------
> + VSR[63] | VR[31] |
> + ----------------------------------------------------------------
> +
> + VSX has 64 128bit registers. The first 32 registers overlap with
> + the FP registers (doubleword 0) and hence extend them with additional
> + 64 bits (doubleword 1). The other 32 regs overlap with the VMX
> + registers. */
> +#define SIZEOF_VSXREGS 32*8
> +
> +typedef char gdb_vsxregset_t[SIZEOF_VSXREGS];
>
> /* On PPC processors that support the the Signal Processing Extension
> (SPE) APU, the general-purpose registers are 64 bits long.
> @@ -144,6 +184,12 @@
> unsigned long spefscr;
> };
>
> +/* Non-zero if our kernel may support the PTRACE_GETVSXREGS and
> + PTRACE_SETVSXREGS requests, for reading and writing the VSX
> + POWER7 registers 0 through 31. Zero if we've tried one of them and
> + gotten an error. Note that VSX registers 32 through 63 overlap
> + with VR registers 0 through 31. */
> +int have_ptrace_getsetvsxregs = 1;
>
> /* Non-zero if our kernel may support the PTRACE_GETVRREGS and
> PTRACE_SETVRREGS requests, for reading and writing the Altivec
> @@ -231,6 +277,34 @@
> return u_addr;
> }
>
> +/* The Linux kernel ptrace interface for POWER7 VSX registers uses the
> + registers set mechanism, as opposed to the interface for all the
> + other registers, that stores/fetches each register individually. */
> +static void
> +fetch_vsx_register (struct regcache *regcache, int tid, int regno)
> +{
> + int ret;
> + gdb_vsxregset_t regs;
> + struct gdbarch *gdbarch = get_regcache_arch (regcache);
> + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> + int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
> +
> + ret = ptrace (PTRACE_GETVSXREGS, tid, 0, &regs);
> + if (ret < 0)
> + {
> + if (errno == EIO)
> + {
> + have_ptrace_getsetvsxregs = 0;
> + return;
> + }
> + perror_with_name (_("Unable to fetch VSX register"));
> + }
> +
> + regcache_raw_supply (regcache, regno,
> + regs + (regno - tdep->ppc_vsr0_upper_regnum)
> + * vsxregsize);
> +}
> +
> /* The Linux kernel ptrace interface for AltiVec registers uses the
> registers set mechanism, as opposed to the interface for all the
> other registers, that stores/fetches each register individually. */
> @@ -365,6 +439,14 @@
> AltiVec registers, fall through and return zeroes, because
> regaddr will be -1 in this case. */
> }
> + if (vsx_register_p (gdbarch, regno))
> + {
> + if (have_ptrace_getsetvsxregs)
> + {
> + fetch_vsx_register (regcache, tid, regno);
> + return;
> + }
> + }
> else if (spe_register_p (gdbarch, regno))
> {
> fetch_spe_register (regcache, tid, regno);
> @@ -421,6 +503,21 @@
> }
>
> static void
> +supply_vsxregset (struct regcache *regcache, gdb_vsxregset_t *vsxregsetp)
> +{
> + int i;
> + struct gdbarch *gdbarch = get_regcache_arch (regcache);
> + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> + int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
> +
> + for (i = 0; i < ppc_num_vshrs; i++)
> + {
> + regcache_raw_supply (regcache, tdep->ppc_vsr0_upper_regnum + i,
> + *vsxregsetp + i * vsxregsize);
> + }
> +}
> +
> +static void
> supply_vrregset (struct regcache *regcache, gdb_vrregset_t *vrregsetp)
> {
> int i;
> @@ -446,6 +543,25 @@
> }
>
> static void
> +fetch_vsx_registers (struct regcache *regcache, int tid)
> +{
> + int ret;
> + gdb_vsxregset_t regs;
> +
> + ret = ptrace (PTRACE_GETVSXREGS, tid, 0, &regs);
> + if (ret < 0)
> + {
> + if (errno == EIO)
> + {
> + have_ptrace_getsetvsxregs = 0;
> + return;
> + }
> + perror_with_name (_("Unable to fetch VSX registers"));
> + }
> + supply_vsxregset (regcache, &regs);
> +}
> +
> +static void
> fetch_altivec_registers (struct regcache *regcache, int tid)
> {
> int ret;
> @@ -499,6 +615,9 @@
> if (have_ptrace_getvrregs)
> if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
> fetch_altivec_registers (regcache, tid);
> + if (have_ptrace_getsetvsxregs)
> + if (tdep->ppc_vsr0_upper_regnum != -1)
> + fetch_vsx_registers (regcache, tid);
> if (tdep->ppc_ev0_upper_regnum >= 0)
> fetch_spe_register (regcache, tid, -1);
> }
> @@ -522,6 +641,35 @@
> fetch_register (regcache, tid, regno);
> }
>
> +/* Store one VSX register. */
> +static void
> +store_vsx_register (const struct regcache *regcache, int tid, int regno)
> +{
> + int ret;
> + gdb_vsxregset_t regs;
> + struct gdbarch *gdbarch = get_regcache_arch (regcache);
> + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> + int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
> +
> + ret = ptrace (PTRACE_SETVSXREGS, tid, 0, &regs);
> + if (ret < 0)
> + {
> + if (errno == EIO)
> + {
> + have_ptrace_getsetvsxregs = 0;
> + return;
> + }
> + perror_with_name (_("Unable to fetch VSX register"));
> + }
> +
> + regcache_raw_collect (regcache, regno, regs +
> + (regno - tdep->ppc_vsr0_upper_regnum) * vsxregsize);
> +
> + ret = ptrace (PTRACE_SETVSXREGS, tid, 0, &regs);
> + if (ret < 0)
> + perror_with_name (_("Unable to store VSX register"));
> +}
> +
> /* Store one register. */
> static void
> store_altivec_register (const struct regcache *regcache, int tid, int regno)
> @@ -660,6 +808,11 @@
> store_altivec_register (regcache, tid, regno);
> return;
> }
> + if (vsx_register_p (gdbarch, regno))
> + {
> + store_vsx_register (regcache, tid, regno);
> + return;
> + }
> else if (spe_register_p (gdbarch, regno))
> {
> store_spe_register (regcache, tid, regno);
> @@ -714,6 +867,19 @@
> }
>
> static void
> +fill_vsxregset (const struct regcache *regcache, gdb_vsxregset_t *vsxregsetp)
> +{
> + int i;
> + struct gdbarch *gdbarch = get_regcache_arch (regcache);
> + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> + int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
> +
> + for (i = 0; i < ppc_num_vshrs; i++)
> + regcache_raw_collect (regcache, tdep->ppc_vsr0_upper_regnum + i,
> + *vsxregsetp + i * vsxregsize);
> +}
> +
> +static void
> fill_vrregset (const struct regcache *regcache, gdb_vrregset_t *vrregsetp)
> {
> int i;
> @@ -737,6 +903,29 @@
> }
>
> static void
> +store_vsx_registers (const struct regcache *regcache, int tid)
> +{
> + int ret;
> + gdb_vsxregset_t regs;
> +
> + ret = ptrace (PTRACE_GETVSXREGS, tid, 0, &regs);
> + if (ret < 0)
> + {
> + if (errno == EIO)
> + {
> + have_ptrace_getsetvsxregs = 0;
> + return;
> + }
> + perror_with_name (_("Couldn't get VSX registers"));
> + }
> +
> + fill_vsxregset (regcache, &regs);
> +
> + if (ptrace (PTRACE_SETVSXREGS, tid, 0, &regs) < 0)
> + perror_with_name (_("Couldn't write VSX registers"));
> +}
> +
> +static void
> store_altivec_registers (const struct regcache *regcache, int tid)
> {
> int ret;
> @@ -794,6 +983,9 @@
> if (have_ptrace_getvrregs)
> if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
> store_altivec_registers (regcache, tid);
> + if (have_ptrace_getsetvsxregs)
> + if (tdep->ppc_vsr0_upper_regnum != -1)
> + store_vsx_registers (regcache, tid);
> if (tdep->ppc_ev0_upper_regnum >= 0)
> store_spe_register (regcache, tid, -1);
> }
> @@ -989,6 +1181,7 @@
> ppc_linux_read_description (struct target_ops *ops)
> {
> int altivec = 0;
> + int vsx = 0;
>
> int tid = TIDGET (inferior_ptid);
> if (tid == 0)
> @@ -1007,6 +1200,19 @@
> perror_with_name (_("Unable to fetch SPE registers"));
> }
>
> + if (have_ptrace_getsetvsxregs)
> + {
> + gdb_vsxregset_t vsxregset;
> +
> + if (ptrace (PTRACE_GETVSXREGS, tid, 0, &vsxregset) >= 0)
> + vsx = 1;
> +
> + /* EIO means that the PTRACE_GETVSXREGS request isn't supported.
> + Anything else needs to be reported. */
> + else if (errno != EIO)
> + perror_with_name (_("Unable to fetch VSX registers"));
> + }
> +
> if (have_ptrace_getvrregs)
> {
> gdb_vrregset_t vrregset;
> @@ -1028,11 +1234,23 @@
> errno = 0;
> msr = (long) ptrace (PTRACE_PEEKUSER, tid, PT_MSR * 8, 0);
> if (errno == 0 && msr < 0)
> - return altivec? tdesc_powerpc_altivec64l : tdesc_powerpc_64l;
> + {
> + if (vsx)
> + return tdesc_powerpc_vsx64l;
> + else if (altivec)
> + return tdesc_powerpc_altivec64l;
> +
> + return tdesc_powerpc_64l;
> + }
> }
> #endif
>
> - return altivec? tdesc_powerpc_altivec32l : tdesc_powerpc_32l;
> + if (vsx)
> + return tdesc_powerpc_vsx32l;
> + else if (altivec)
> + return tdesc_powerpc_altivec32l;
> +
> + return tdesc_powerpc_32l;
> }
>
> void _initialize_ppc_linux_nat (void);
> Index: gdb/ppc-tdep.h
> ===================================================================
> --- gdb.orig/ppc-tdep.h 2008-08-08 07:17:03.000000000 -0700
> +++ gdb/ppc-tdep.h 2008-08-08 07:17:47.000000000 -0700
> @@ -63,6 +63,7 @@
>
> /* From rs6000-tdep.c... */
> int altivec_register_p (struct gdbarch *gdbarch, int regno);
> +int vsx_register_p (struct gdbarch *gdbarch, int regno);
> int spe_register_p (struct gdbarch *gdbarch, int regno);
>
> /* Return non-zero if the architecture described by GDBARCH has
> @@ -73,6 +74,9 @@
> Altivec registers (vr0 --- vr31, vrsave and vscr). */
> int ppc_altivec_support_p (struct gdbarch *gdbarch);
>
> +/* Return non-zero if the architecture described by GDBARCH has
> + VSX registers (vsr0 --- vsr63). */
> +int vsx_support_p (struct gdbarch *gdbarch);
> int ppc_deal_with_atomic_sequence (struct frame_info *frame);
>
>
> @@ -133,6 +137,14 @@
> struct regcache *regcache,
> int regnum, const void *vrregs, size_t len);
>
> +/* Supply register REGNUM in the VSX register set REGSET
> + from the buffer specified by VSXREGS and LEN to register cache
> + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
> +
> +extern void ppc_supply_vsxregset (const struct regset *regset,
> + struct regcache *regcache,
> + int regnum, const void *vsxregs, size_t len);
> +
> /* Collect register REGNUM in the general-purpose register set
> REGSET. from register cache REGCACHE into the buffer specified by
> GREGS and LEN. If REGNUM is -1, do this for all registers in
> @@ -160,6 +172,15 @@
> const struct regcache *regcache,
> int regnum, void *vrregs, size_t len);
>
> +/* Collect register REGNUM in the VSX register set
> + REGSET from register cache REGCACHE into the buffer specified by
> + VSXREGS and LEN. If REGNUM is -1, do this for all registers in
> + REGSET. */
> +
> +extern void ppc_collect_vsxregset (const struct regset *regset,
> + const struct regcache *regcache,
> + int regnum, void *vsxregs, size_t len);
> +
> /* Private data that this module attaches to struct gdbarch. */
>
> /* Vector ABI used by the inferior. */
> @@ -199,6 +220,11 @@
> /* Multiplier-Quotient Register (older POWER architectures only). */
> int ppc_mq_regnum;
>
> + /* POWER7 VSX registers. */
> + int ppc_vsr0_regnum; /* First VSX register. */
> + int ppc_vsr0_upper_regnum; /* First right most dword vsx register. */
> + int ppc_efpr0_regnum; /* First Extended FP register. */
> +
> /* Altivec registers. */
> int ppc_vr0_regnum; /* First AltiVec register */
> int ppc_vrsave_regnum; /* Last AltiVec register */
> @@ -222,16 +248,20 @@
>
> /* ISA-specific types. */
> struct type *ppc_builtin_type_vec64;
> + struct type *ppc_builtin_type_vec128;
> };
>
>
> /* Constants for register set sizes. */
> enum
> {
> - ppc_num_gprs = 32, /* 32 general-purpose registers */
> - ppc_num_fprs = 32, /* 32 floating-point registers */
> - ppc_num_srs = 16, /* 16 segment registers */
> - ppc_num_vrs = 32 /* 32 Altivec vector registers */
> + ppc_num_gprs = 32, /* 32 general-purpose registers. */
> + ppc_num_fprs = 32, /* 32 floating-point registers. */
> + ppc_num_srs = 16, /* 16 segment registers. */
> + ppc_num_vrs = 32, /* 32 Altivec vector registers. */
> + ppc_num_vshrs = 32, /* 32 doublewords (dword 1 of vs0~vs31). */
> + ppc_num_vsrs = 64, /* 64 VSX vector registers. */
> + ppc_num_efprs = 32 /* 32 Extended FP registers. */
> };
>
>
> @@ -257,6 +287,8 @@
> PPC_VR0_REGNUM = 106,
> PPC_VSCR_REGNUM = 138,
> PPC_VRSAVE_REGNUM = 139,
> + PPC_VSR0_UPPER_REGNUM = 140,
> + PPC_VSR31_UPPER_REGNUM = 171,
> PPC_NUM_REGS
> };
>
> Index: gdb/ppc-linux-tdep.c
> ===================================================================
> --- gdb.orig/ppc-linux-tdep.c 2008-08-08 07:17:03.000000000 -0700
> +++ gdb/ppc-linux-tdep.c 2008-08-08 07:17:47.000000000 -0700
> @@ -41,8 +41,10 @@
>
> #include "features/rs6000/powerpc-32l.c"
> #include "features/rs6000/powerpc-altivec32l.c"
> +#include "features/rs6000/powerpc-vsx32l.c"
> #include "features/rs6000/powerpc-64l.c"
> #include "features/rs6000/powerpc-altivec64l.c"
> +#include "features/rs6000/powerpc-vsx64l.c"
> #include "features/rs6000/powerpc-e500l.c"
>
>
> @@ -1095,7 +1097,9 @@
> /* Initialize the Linux target descriptions. */
> initialize_tdesc_powerpc_32l ();
> initialize_tdesc_powerpc_altivec32l ();
> + initialize_tdesc_powerpc_vsx32l ();
> initialize_tdesc_powerpc_64l ();
> initialize_tdesc_powerpc_altivec64l ();
> + initialize_tdesc_powerpc_vsx64l ();
> initialize_tdesc_powerpc_e500l ();
> }
> Index: gdb/ppc-linux-tdep.h
> ===================================================================
> --- gdb.orig/ppc-linux-tdep.h 2008-08-08 07:17:03.000000000 -0700
> +++ gdb/ppc-linux-tdep.h 2008-08-08 07:17:47.000000000 -0700
> @@ -41,8 +41,10 @@
> /* Linux target descriptions. */
> extern struct target_desc *tdesc_powerpc_32l;
> extern struct target_desc *tdesc_powerpc_altivec32l;
> +extern struct target_desc *tdesc_powerpc_vsx32l;
> extern struct target_desc *tdesc_powerpc_e500l;
> extern struct target_desc *tdesc_powerpc_64l;
> extern struct target_desc *tdesc_powerpc_altivec64l;
> +extern struct target_desc *tdesc_powerpc_vsx64l;
>
> #endif /* PPC_LINUX_TDEP_H */
>
>