*** Changes since GDB 13
+* Removed targets and native configurations
+
+ GDB no longer supports AIX 4.x, AIX 5.x and AIX 6.x. The minimum supported
+ AIX version is now AIX 7.1.
+
* Multi-target feature configuration
GDB now supports the individual configuration of remote targets' feature
req, id, ret, errno);
return ret == -1 ? 0 : 1;
}
- break;
+ break;
+ case PTT_READ_VEC:
+ case PTT_READ_VSX:
+ if (debug_aix_thread)
+ gdb_printf (gdb_stdlog,
+ "ptrace (%d, %d) = %d (errno = %d)\n",
+ req, id, ret, errno);
+ if (ret == -1)
+ return -1;
+ break;
}
error (_("aix-thread: ptrace (%d, %d) returned %d (errno = %d %s)"),
req, id, ret, errno, safe_strerror (errno));
memcpy (&context->msr, &sprs32, sizeof(sprs32));
}
}
+
+ /* vector registers. */
+ __vmx_context_t vmx;
+ if (__power_vmx() && (flags & PTHDB_FLAG_REGS))
+ {
+ if (data->arch64)
+ {
+ if (!ptrace64aix (PTT_READ_VEC, tid, (long long) &vmx, 0, 0))
+ memset (&vmx, 0, sizeof (vmx));
+ memcpy (&context->vmx, &vmx, sizeof(__vmx_context_t));
+ }
+ else
+ {
+ if (!ptrace32 (PTT_READ_VEC, tid, (long long) &vmx, 0, 0))
+ memset (&vmx, 0, sizeof (vmx));
+ memcpy (&context->vmx, &vmx, sizeof(__vmx_context_t));
+ }
+ }
+
+ /* vsx registers. */
+ __vsx_context_t vsx;
+ if (__power_vsx() && (flags & PTHDB_FLAG_REGS))
+ {
+ if (data->arch64)
+ {
+ if (!ptrace64aix (PTT_READ_VSX, tid, (long long) &vsx, 0, 0))
+ memset (&vsx, 0, sizeof (vsx));
+ memcpy (&context->vsx, &vsx, sizeof(__vsx_context_t));
+ }
+ else
+ {
+ if (!ptrace32 (PTT_READ_VSX, tid, (long long) &vsx, 0, 0))
+ memset (&vsx, 0, sizeof (vsx));
+ memcpy (&context->vsx, &vsx, sizeof(__vsx_context_t));
+ }
+ }
return 0;
}
ptrace32 (PTT_WRITE_SPRS, tid, (uintptr_t) &context->msr, 0, NULL);
}
}
+
+ /* vector registers. */
+ if (__power_vmx() && (flags & PTHDB_FLAG_REGS))
+ {
+ if (data->arch64)
+ ptrace64aix (PTT_WRITE_VEC, tid, (unsigned long) &context->vmx, 0, 0);
+ else
+ ptrace32 (PTT_WRITE_VEC, tid, (uintptr_t) &context->vmx, 0, 0);
+ }
+
+ /* vsx registers. */
+ if (__power_vsx() && (flags & PTHDB_FLAG_REGS))
+ {
+ if (data->arch64)
+ ptrace64aix (PTT_WRITE_VSX, tid, (unsigned long) &context->vsx, 0, 0);
+ else
+ ptrace32 (PTT_WRITE_VSX, tid, (uintptr_t) &context->vsx, 0, 0);
+ }
return 0;
}
return pd_update (ptid.pid ());
}
+/* Supply AIX altivec registers, both 64 and 32 bit. */
+
+static void
+supply_altivec_regs (struct regcache *regcache, __vmx_context_t vmx)
+{
+ ppc_gdbarch_tdep *tdep
+ = gdbarch_tdep<ppc_gdbarch_tdep> (regcache->arch ());
+ int regno;
+ for (regno = 0; regno < ppc_num_vrs; regno++)
+ regcache->raw_supply (tdep->ppc_vr0_regnum + regno,
+ &(vmx.__vr[regno]));
+ regcache->raw_supply (tdep->ppc_vrsave_regnum, &(vmx.__vrsave));
+ regcache->raw_supply (tdep->ppc_vrsave_regnum - 1, &(vmx.__vscr));
+}
+
+/* Supply AIX VSX registers, both 64 and 32 bit. */
+
+static void
+supply_vsx_regs (struct regcache *regcache, __vsx_context_t vsx)
+{
+ ppc_gdbarch_tdep *tdep
+ = gdbarch_tdep<ppc_gdbarch_tdep> (regcache->arch ());
+ int regno;
+
+ for (regno = 0; regno < ppc_num_vshrs; regno++)
+ regcache->raw_supply (tdep->ppc_vsr0_upper_regnum + regno,
+ &(vsx.__vsr_dw1[regno]));
+}
+
/* Record that the 64-bit general-purpose registers contain VALS. */
static void
else
supply_sprs32 (regcache, ctx.iar, ctx.msr, ctx.cr, ctx.lr, ctx.ctr,
ctx.xer, ctx.fpscr);
+
+ /* Altivec registers. */
+ supply_altivec_regs (regcache, ctx.vmx);
+
+ /* VSX registers. */
+ supply_vsx_regs (regcache, ctx.vsx);
}
/* Fetch register REGNO if != -1 or all registers otherwise from
}
}
+ /* vector registers. */
+ if (tdep->ppc_vr0_regnum != -1)
+ {
+ int ret = 0;
+ __vmx_context_t vmx;
+ if (data->arch64)
+ ret = ptrace64aix (PTT_READ_VEC, tid, (long long) &vmx, 0, 0);
+ else
+ ret = ptrace32 (PTT_READ_VEC, tid, (uintptr_t) &vmx, 0, 0);
+ if (ret < 0)
+ memset(&vmx, 0, sizeof(__vmx_context_t));
+ for (i = 0; i < ppc_num_vrs; i++)
+ regcache->raw_supply (tdep->ppc_vr0_regnum + i, &(vmx.__vr[i]));
+ regcache->raw_supply (tdep->ppc_vrsave_regnum, &(vmx.__vrsave));
+ regcache->raw_supply (tdep->ppc_vrsave_regnum - 1, &(vmx.__vscr));
+ }
+
+ /* vsx registers. */
+ if (tdep->ppc_vsr0_upper_regnum != -1)
+ {
+ __vsx_context_t vsx;
+ int ret = 0;
+ if (data->arch64)
+ ret = ptrace64aix (PTT_READ_VSX, tid, (long long) &vsx, 0, 0);
+ else
+ ret = ptrace32 (PTT_READ_VSX, tid, (long long) &vsx, 0, 0);
+ if (ret < 0)
+ memset(&vsx, 0, sizeof(__vsx_context_t));
+ for (i = 0; i < ppc_num_vshrs; i++)
+ regcache->raw_supply (tdep->ppc_vsr0_upper_regnum + i, &(vsx.__vsr_dw1[i]));
+ }
+
/* Floating-point registers. */
if (ppc_floating_point_unit_p (gdbarch)
}
}
+/* Fill altivec registers. */
+
+static void
+fill_altivec (const struct regcache *regcache, __vmx_context_t *vmx)
+{
+ struct gdbarch *gdbarch = regcache->arch ();
+ ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
+ int regno;
+
+ for (regno = 0; regno < ppc_num_vrs; regno++)
+ if (REG_VALID == regcache->get_register_status (tdep->ppc_vr0_regnum + regno))
+ regcache->raw_collect (tdep->ppc_vr0_regnum + regno,
+ &(vmx->__vr[regno]));
+
+ if (REG_VALID == regcache->get_register_status (tdep->ppc_vrsave_regnum))
+ regcache->raw_collect (tdep->ppc_vrsave_regnum, &(vmx->__vrsave));
+ if (REG_VALID == regcache->get_register_status (tdep->ppc_vrsave_regnum - 1))
+ regcache->raw_collect (tdep->ppc_vrsave_regnum - 1, &(vmx->__vscr));
+}
+
+/* Fill vsx registers. */
+
+static void
+fill_vsx (const struct regcache *regcache, __vsx_context_t *vsx)
+{
+ struct gdbarch *gdbarch = regcache->arch ();
+ ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
+ int regno;
+
+ for (regno = 0; regno < ppc_num_vshrs; regno++)
+ if (REG_VALID == regcache->get_register_status ( tdep->ppc_vsr0_upper_regnum + regno))
+ regcache->raw_collect (tdep->ppc_vsr0_upper_regnum + regno,
+ &(vsx->__vsr_dw1[0]) + regno);
+}
+
/* Store the gp registers into an array of uint32_t or uint64_t. */
static void
uint64_t int64;
struct aix_thread_variables *data;
data = get_thread_data_helper_for_ptid (inferior_ptid);
+ int ret;
+ __vmx_context_t vmx;
+ __vsx_context_t vsx;
if (debug_aix_thread)
gdb_printf (gdb_stdlog,
error (_("aix-thread: store_registers: pthdb_pthread_context returned %s"),
pd_status2str (status));
+ /* Fill altivec-registers. */
+
+ if (__power_vmx())
+ {
+ memset(&vmx, 0, sizeof(__vmx_context_t));
+ for (i = 0; i < ppc_num_vrs; i++)
+ if (REG_VALID == regcache->get_register_status (tdep->ppc_vr0_regnum + i))
+ {
+ regcache->raw_collect (tdep->ppc_vr0_regnum + i,
+ &(vmx.__vr[i]));
+ ctx.vmx.__vr[i] = vmx.__vr[i];
+ }
+ if (REG_VALID == regcache->get_register_status (tdep->ppc_vrsave_regnum))
+ ctx.vmx.__vrsave = vmx.__vrsave;
+ if (REG_VALID == regcache->get_register_status (tdep->ppc_vrsave_regnum - 1))
+ ctx.vmx.__vscr = vmx.__vscr;
+ }
+
+ /* Fill vsx registers. */
+
+ if (__power_vsx())
+ {
+ memset(&vsx, 0, sizeof(__vsx_context_t));
+ for (i = 0; i < ppc_num_vshrs; i++)
+ if (REG_VALID == regcache->get_register_status (tdep->ppc_vsr0_regnum + i))
+ {
+ regcache->raw_collect (tdep->ppc_vr0_regnum + i,
+ &(vsx.__vsr_dw1[i]));
+ ctx.vsx.__vsr_dw1[i] = vsx.__vsr_dw1[i];
+ }
+ }
+
/* Collect general-purpose register values from the regcache. */
for (i = 0; i < ppc_num_gprs; i++)
struct ptxsprs sprs64;
struct ptsprs sprs32;
struct aix_thread_variables *data;
+ int ret = 0;
data = get_thread_data_helper_for_ptid (regcache->ptid ());
ptrace32 (PTT_WRITE_SPRS, tid, (uintptr_t) &sprs32, 0, NULL);
}
}
+
+ /* Vector registers. */
+ if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1
+ && (regno == -1 || (regno >= tdep->ppc_vr0_regnum
+ && regno <= tdep->ppc_vrsave_regnum)))
+ {
+ __vmx_context_t vmx;
+ if (__power_vmx())
+ {
+ if (data->arch64)
+ ret = ptrace64aix (PTT_READ_VEC, tid, (long long) &vmx, 0, 0);
+ else
+ ret = ptrace32 (PTT_READ_VEC, tid, (long long) &vmx, 0, 0);
+ if (ret > 0)
+ {
+ fill_altivec(regcache, &vmx);
+ if (data->arch64)
+ ret = ptrace64aix (PTT_WRITE_VEC, tid, (long long) &vmx, 0, 0);
+ else
+ ret = ptrace32 (PTT_WRITE_VEC, tid, (long long) &vmx, 0, 0);
+ if (ret < 0)
+ perror_with_name (_("Unable to store AltiVec register after read"));
+ }
+ }
+ }
+
+ /* VSX registers. */
+ if (tdep->ppc_vsr0_upper_regnum != -1 && (regno == -1
+ || (regno >=tdep->ppc_vsr0_upper_regnum
+ && regno < tdep->ppc_vsr0_upper_regnum + ppc_num_vshrs)))
+ {
+ __vsx_context_t vsx;
+ if (__power_vsx())
+ {
+ if (data->arch64)
+ ret = ptrace64aix (PTT_READ_VSX, tid, (long long) &vsx, 0, 0);
+ else
+ ret = ptrace32 (PTT_READ_VSX, tid, (long long) &vsx, 0, 0);
+ if (ret > 0)
+ {
+ fill_vsx (regcache, &vsx);
+ if (data->arch64)
+ ret = ptrace64aix (PTT_WRITE_VSX, tid, (long long) &vsx, 0, 0);
+ else
+ ret = ptrace32 (PTT_WRITE_VSX, tid, (long long) &vsx, 0, 0);
+ if (ret < 0)
+ perror_with_name (_("Unable to store VSX register after read"));
+ }
+ }
+ }
}
/* Store gdb's current view of the register set into the
#include <procinfo.h>
#include <sys/types.h>
+/* Header files for alti-vec reg. */
+#include <sys/context.h>
+
+#include "features/rs6000/powerpc-vsx64.c"
+#include "features/rs6000/powerpc-vsx32.c"
+#include "features/rs6000/powerpc-altivec32.c"
+#include "features/rs6000/powerpc-altivec64.c"
+
/* On AIX4.3+, sys/ldr.h provides different versions of struct ld_info for
debugging 32-bit and 64-bit processes. Define a typedef and macros for
accessing fields in the appropriate structures. */
support. */
void follow_fork (inferior *, ptid_t, target_waitkind, bool, bool) override;
+ const struct target_desc *read_description () override;
+
protected:
void post_startup_inferior (ptid_t ptid) override;
return ret;
}
+/* Store the vsx registers. */
+
+static void
+store_vsx_register_aix (struct regcache *regcache, int regno)
+{
+ int ret;
+ struct gdbarch *gdbarch = regcache->arch ();
+ ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
+ struct thrdentry64 thrdentry;
+ __vsx_context_t vsx;
+ pid_t pid = inferior_ptid.pid ();
+ tid64_t thrd_i = 0;
+
+ if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64),
+ &thrd_i, 1) == 1)
+ thrd_i = thrdentry.ti_tid;
+
+ memset(&vsx, 0, sizeof(__vsx_context_t));
+ if (__power_vsx() && thrd_i > 0)
+ {
+ if (ARCH64 ())
+ ret = rs6000_ptrace64 (PTT_READ_VSX, thrd_i, (long long) &vsx, 0, 0);
+ else
+ ret = rs6000_ptrace32 (PTT_READ_VSX, thrd_i, (int *)&vsx, 0, 0);
+ if (ret < 0)
+ return;
+
+ regcache->raw_collect (regno, &(vsx.__vsr_dw1[0])+
+ regno - tdep->ppc_vsr0_upper_regnum);
+
+ if (ARCH64 ())
+ ret = rs6000_ptrace64 (PTT_WRITE_VSX, thrd_i, (long long) &vsx, 0, 0);
+ else
+ ret = rs6000_ptrace32 (PTT_WRITE_VSX, thrd_i, (int *) &vsx, 0, 0);
+
+ if (ret < 0)
+ perror_with_name (_("Unable to write VSX registers after reading it"));
+ }
+}
+
+/* Store Altivec registers. */
+
+static void
+store_altivec_register_aix (struct regcache *regcache, int regno)
+{
+ int ret;
+ struct gdbarch *gdbarch = regcache->arch ();
+ ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
+ struct thrdentry64 thrdentry;
+ __vmx_context_t vmx;
+ pid_t pid = inferior_ptid.pid ();
+ tid64_t thrd_i = 0;
+
+ if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64),
+ &thrd_i, 1) == 1)
+ thrd_i = thrdentry.ti_tid;
+
+ memset(&vmx, 0, sizeof(__vmx_context_t));
+ if (__power_vmx() && thrd_i > 0)
+ {
+ if (ARCH64 ())
+ ret = rs6000_ptrace64 (PTT_READ_VEC, thrd_i, (long long) &vmx, 0, 0);
+ else
+ ret = rs6000_ptrace32 (PTT_READ_VEC, thrd_i, (int *) &vmx, 0, 0);
+ if (ret < 0)
+ return;
+
+ regcache->raw_collect (regno, &(vmx.__vr[0]) + regno
+ - tdep->ppc_vr0_regnum);
+
+ if (ARCH64 ())
+ ret = rs6000_ptrace64 (PTT_WRITE_VEC, thrd_i, (long long) &vmx, 0, 0);
+ else
+ ret = rs6000_ptrace32 (PTT_WRITE_VEC, thrd_i, (int *) &vmx, 0, 0);
+ if (ret < 0)
+ perror_with_name (_("Unable to store AltiVec register after reading it"));
+ }
+}
+
+/* Supply altivec registers. */
+
+static void
+supply_vrregset_aix (struct regcache *regcache, __vmx_context_t *vmx)
+{
+ int i;
+ struct gdbarch *gdbarch = regcache->arch ();
+ ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
+ int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
+
+ for (i = 0; i < num_of_vrregs; i++)
+ regcache->raw_supply (tdep->ppc_vr0_regnum + i,
+ &(vmx->__vr[i]));
+ regcache->raw_supply (tdep->ppc_vrsave_regnum, &(vmx->__vrsave));
+ regcache->raw_supply (tdep->ppc_vrsave_regnum - 1, &(vmx->__vscr));
+}
+
+/* Fetch altivec register. */
+
+static void
+fetch_altivec_registers_aix (struct regcache *regcache)
+{
+ struct thrdentry64 thrdentry;
+ __vmx_context_t vmx;
+ pid_t pid = current_inferior ()->pid;
+ tid64_t thrd_i = 0;
+
+ if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64),
+ &thrd_i, 1) == 1)
+ thrd_i = thrdentry.ti_tid;
+
+ memset(&vmx, 0, sizeof(__vmx_context_t));
+ if (__power_vmx() && thrd_i > 0)
+ {
+ if (ARCH64 ())
+ rs6000_ptrace64 (PTT_READ_VEC, thrd_i, (long long) &vmx, 0, 0);
+ else
+ rs6000_ptrace32 (PTT_READ_VEC, thrd_i, (int *) &vmx, 0, 0);
+ supply_vrregset_aix (regcache, &vmx);
+ }
+}
+
+/* supply vsx register. */
+
+static void
+supply_vsxregset_aix (struct regcache *regcache, __vsx_context_t *vsx)
+{
+ int i;
+ struct gdbarch *gdbarch = regcache->arch ();
+ ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
+
+ for (i = 0; i < ppc_num_vshrs; i++)
+ regcache->raw_supply (tdep->ppc_vsr0_upper_regnum + i,
+ &(vsx->__vsr_dw1[i]));
+}
+
+/* Fetch vsx registers. */
+static void
+fetch_vsx_registers_aix (struct regcache *regcache)
+{
+ struct thrdentry64 thrdentry;
+ __vsx_context_t vsx;
+ pid_t pid = current_inferior ()->pid;
+ tid64_t thrd_i = 0;
+
+ if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64),
+ &thrd_i, 1) == 1)
+ thrd_i = thrdentry.ti_tid;
+
+ memset(&vsx, 0, sizeof(__vsx_context_t));
+ if (__power_vsx() && thrd_i > 0)
+ {
+ if (ARCH64 ())
+ rs6000_ptrace64 (PTT_READ_VSX, thrd_i, (long long) &vsx, 0, 0);
+ else
+ rs6000_ptrace32 (PTT_READ_VSX, thrd_i, (int *) &vsx, 0, 0);
+ supply_vsxregset_aix (regcache, &vsx);
+ }
+}
+
void rs6000_nat_target::post_startup_inferior (ptid_t ptid)
{
/* Retrieved values may be -1, so infer errors from errno. */
errno = 0;
+ /* Alti-vec register. */
+ if (altivec_register_p (gdbarch, regno))
+ {
+ fetch_altivec_registers_aix (regcache);
+ return;
+ }
+
+ /* VSX register. */
+ if (vsx_register_p (gdbarch, regno))
+ {
+ fetch_vsx_registers_aix (regcache);
+ return;
+ }
+
nr = regmap (gdbarch, regno, &isfloat);
/* Floating-point registers. */
/* -1 can be a successful return value, so infer errors from errno. */
errno = 0;
+ if (altivec_register_p (gdbarch, regno))
+ {
+ store_altivec_register_aix (regcache, regno);
+ return;
+ }
+
+ if (vsx_register_p (gdbarch, regno))
+ {
+ store_vsx_register_aix (regcache, regno);
+ return;
+ }
+
nr = regmap (gdbarch, regno, &isfloat);
/* Floating-point registers. */
for (regno = 0; regno < ppc_num_fprs; regno++)
fetch_register (regcache, tdep->ppc_fp0_regnum + regno);
+ if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
+ fetch_altivec_registers_aix (regcache);
+
+ if (tdep->ppc_vsr0_upper_regnum != -1)
+ fetch_vsx_registers_aix (regcache);
+
/* Read special registers. */
fetch_register (regcache, gdbarch_pc_regnum (gdbarch));
fetch_register (regcache, tdep->ppc_ps_regnum);
}
}
+const struct target_desc *
+rs6000_nat_target::read_description ()
+{
+ if (ARCH64())
+ {
+ if (__power_vsx ())
+ return tdesc_powerpc_vsx64;
+ else if (__power_vmx ())
+ return tdesc_powerpc_altivec64;
+ }
+ else
+ {
+ if (__power_vsx ())
+ return tdesc_powerpc_vsx32;
+ else if (__power_vmx ())
+ return tdesc_powerpc_altivec32;
+ }
+ return NULL;
+}
+
/* Store our register values back into the inferior.
If REGNO is -1, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
/* Minimum possible text address in AIX. */
#define AIX_TEXT_SEGMENT_BASE 0x10000000
+struct rs6000_aix_reg_vrreg_offset
+{
+ int vr0_offset;
+ int vscr_offset;
+ int vrsave_offset;
+};
+
+static struct rs6000_aix_reg_vrreg_offset rs6000_aix_vrreg_offset =
+{
+ /* AltiVec registers. */
+ 32, /* vr0_offset */
+ 544, /* vscr_offset. */
+ 560 /* vrsave_offset */
+};
+
+static int
+rs6000_aix_get_vrreg_offset (ppc_gdbarch_tdep *tdep,
+ const struct rs6000_aix_reg_vrreg_offset *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;
+}
+
+static void
+rs6000_aix_supply_vrregset (const struct regset *regset, struct regcache *regcache,
+ int regnum, const void *vrregs, size_t len)
+{
+ struct gdbarch *gdbarch = regcache->arch ();
+ const struct rs6000_aix_reg_vrreg_offset *offsets;
+ size_t offset;
+ ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
+ if (!(tdep->ppc_vr0_regnum >= 0 && tdep->ppc_vrsave_regnum >= 0))
+ return;
+
+ offsets = (const struct rs6000_aix_reg_vrreg_offset *) regset->regmap;
+ 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, (const gdb_byte *) vrregs, offset, 16);
+
+ ppc_supply_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
+ (const gdb_byte *) vrregs, offsets->vscr_offset, 4);
+
+ ppc_supply_reg (regcache, tdep->ppc_vrsave_regnum,
+ (const gdb_byte *) vrregs, offsets->vrsave_offset, 4);
+
+ return;
+ }
+ offset = rs6000_aix_get_vrreg_offset (tdep, offsets, regnum);
+ if (regnum != tdep->ppc_vrsave_regnum &&
+ regnum != tdep->ppc_vrsave_regnum - 1)
+ ppc_supply_reg (regcache, regnum, (const gdb_byte *) vrregs, offset, 16);
+ else
+ ppc_supply_reg (regcache, regnum,
+ (const gdb_byte *) vrregs, offset, 4);
+
+}
+
+static void
+rs6000_aix_supply_vsxregset (const struct regset *regset, struct regcache *regcache,
+ int regnum, const void *vsxregs, size_t len)
+{
+ struct gdbarch *gdbarch = regcache->arch ();
+ ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
+ if (!(tdep->ppc_vsr0_regnum >= 0))
+ return;
+
+ if (regnum == -1)
+ {
+ int i, offset = 0;
+
+ for (i = tdep->ppc_vsr0_upper_regnum; i < tdep->ppc_vsr0_upper_regnum
+ + 32; i++, offset += 8)
+ ppc_supply_reg (regcache, i, (const gdb_byte *) vsxregs, offset, 8);
+
+ return;
+ }
+ else
+ ppc_supply_reg (regcache, regnum, (const gdb_byte *) vsxregs, 0, 8);
+}
+
+static void
+rs6000_aix_collect_vsxregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *vsxregs, size_t len)
+{
+ struct gdbarch *gdbarch = regcache->arch ();
+ ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
+ if (!(tdep->ppc_vsr0_regnum >= 0))
+ return;
+
+ if (regnum == -1)
+ {
+ int i;
+ int offset = 0;
+ for (i = tdep->ppc_vsr0_upper_regnum; i < tdep->ppc_vsr0_upper_regnum
+ + 32; i++, offset += 8)
+ ppc_collect_reg (regcache, i, (gdb_byte *) vsxregs, offset, 8);
+
+ return;
+ }
+
+ else
+ ppc_collect_reg (regcache, regnum, (gdb_byte *) vsxregs, 0, 8);
+}
+
+static void
+rs6000_aix_collect_vrregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *vrregs, size_t len)
+{
+ struct gdbarch *gdbarch = regcache->arch ();
+ const struct rs6000_aix_reg_vrreg_offset *offsets;
+ size_t offset;
+
+ ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
+ if (!(tdep->ppc_vr0_regnum >= 0 && tdep->ppc_vrsave_regnum >= 0))
+ return;
+
+ offsets = (const struct rs6000_aix_reg_vrreg_offset *) regset->regmap;
+ 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, (gdb_byte *) vrregs, offset, 16);
+
+ ppc_collect_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
+ (gdb_byte *) vrregs, offsets->vscr_offset, 4);
+
+ ppc_collect_reg (regcache, tdep->ppc_vrsave_regnum,
+ (gdb_byte *) vrregs, offsets->vrsave_offset, 4);
+
+ return;
+ }
+
+ offset = rs6000_aix_get_vrreg_offset (tdep, offsets, regnum);
+ if (regnum != tdep->ppc_vrsave_regnum
+ && regnum != tdep->ppc_vrsave_regnum - 1)
+ ppc_collect_reg (regcache, regnum, (gdb_byte *) vrregs, offset, 16);
+ else
+ ppc_collect_reg (regcache, regnum,
+ (gdb_byte *) vrregs, offset, 4);
+}
+
+static const struct regset rs6000_aix_vrregset = {
+ &rs6000_aix_vrreg_offset,
+ rs6000_aix_supply_vrregset,
+ rs6000_aix_collect_vrregset
+};
+
+static const struct regset rs6000_aix_vsxregset = {
+ &rs6000_aix_vrreg_offset,
+ rs6000_aix_supply_vsxregset,
+ rs6000_aix_collect_vsxregset
+};
+
static struct trad_frame_cache *
aix_sighandle_frame_cache (frame_info_ptr this_frame,
void **this_cache)
const struct regcache *regcache)
{
ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
+ int have_altivec = tdep->ppc_vr0_regnum != -1;
+ int have_vsx = tdep->ppc_vsr0_upper_regnum != -1;
+
if (tdep->wordsize == 4)
cb (".reg", 592, 592, &rs6000_aix32_regset, NULL, cb_data);
else
cb (".reg", 576, 576, &rs6000_aix64_regset, NULL, cb_data);
+
+ if (have_altivec)
+ cb (".aix-vmx", 560, 560, &rs6000_aix_vrregset, "AIX altivec", cb_data);
+
+ if (have_vsx)
+ cb (".aix-vsx", 256, 256, &rs6000_aix_vsxregset, "AIX vsx", cb_data);
+
}