--- ./gdb/rs6000-nat.c_orig	2021-12-10 05:52:11.407240748 -0600
+++ ./gdb/rs6000-nat.c	2021-12-10 05:53:17.698994253 -0600
@@ -35,6 +35,7 @@
 #include "exec.h"
 #include "observable.h"
 #include "xcoffread.h"
+#include "gdbthread.h"
 
 #include <sys/ptrace.h>
 #include <sys/reg.h>
@@ -54,7 +55,19 @@
 #define __LDINFO_PTRACE64__	/* for __ld_info64 */
 #include <sys/ldr.h>
 #include <sys/systemcfg.h>
+#include <sys/context.h>
+#include <sys/pthdebug.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"
+
+
+int have_ptrace_getvrregs = 1;
+
+int have_ptrace_getsetvsxregs = 1;
+
 /* 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.  */
@@ -92,6 +105,8 @@
 
   ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
 
+  const struct target_desc *read_description ()  override;
+
 private:
   enum target_xfer_status
     xfer_shared_libraries (enum target_object object,
@@ -241,7 +256,86 @@
       errno = 0;
     }
 }
+static void
+store_vsx_register_aix (struct regcache *regcache, int regno)
+{
+  int ret;
+  struct gdbarch *gdbarch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
+  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())  {
+    ret = ptrace64 (PTT_READ_VSX, thrd_i, (long long) &vsx, 0, 0);
+    if (ret < 0)
+    {
+       if (errno == ENXIO)
+       {
+         /* have_ptrace_getsetvsxregs = 0; */
+         //warning (_("Unable to fetch VSX registers."));
+         return;
+       }
+    }
+  }
+  regcache->raw_collect (regno, &(vsx.__vsr_dw1[0])+
+                       regno - tdep->ppc_vsr0_upper_regnum);
+
+  ret = ptrace64 (PTT_WRITE_VSX, thrd_i, (long long) &vsx, 0, 0);
+  if (ret < 0)
+    perror_with_name (_("Unable to store VSX register."));
+
+}
+
+static void
+store_altivec_register_aix (struct regcache *regcache, int regno)
+{
+  int offset = 0;
+  int ret;
+  struct gdbarch *gdbarch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
+  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())  {
+    ret = ptrace64 (PTT_READ_VEC, thrd_i, (long long) &vmx, 0, 0);
+    if (ret < 0)
+    {
+       if (errno == ENXIO)
+       {
+         /* have_ptrace_getvrregs = 0; */
+         //warning (_("Unable to fetch AltiVec registers."));
+         return;
+       }
+    }
+  }   
+    /* VSCR is fetched as a 16 bytes quantity, but it is really 4 bytes
+     long on the hardware.  */
+  if (regno == (tdep->ppc_vrsave_regnum - 1))
+    offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum);
+
+  regcache->raw_collect (regno, &(vmx.__vr[0]) + regno
+                                - tdep->ppc_vr0_regnum);
+
+  ret = ptrace64 (PTT_WRITE_VEC, thrd_i, (long long) &vmx, 0, 0);
+  if (ret < 0)
+     perror_with_name (_("Unable to store AltiVec register."));
+
+}
+
 /* Store register REGNO back into the inferior.  */
 
 static void
@@ -294,6 +388,17 @@
 	}
     }
 
+   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;
+   }
+
   if (errno)
     {
       perror (_("ptrace write"));
@@ -301,6 +406,112 @@
     }
 }
 
+static void
+supply_vsxregset_aix (struct regcache *regcache, __vsx_context_t *vsx)
+{
+
+  int i;
+  struct gdbarch *gdbarch = regcache->arch ();
+  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 (tdep->ppc_vsr0_upper_regnum + i,
+                             &(vsx->__vsr_dw1[i]));
+    }
+}
+
+static void
+fetch_vsx_registers_aix (struct regcache *regcache)
+{
+  int ret;
+  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())  {
+    ret = ptrace64 (PTT_READ_VSX, thrd_i, (long long) &vsx, 0, 0);
+    if (ret < 0)
+    {
+       /* Just fill with 0 zero instead of error return */
+       #if 0
+         if (errno == ENXIO)
+         {
+           have_ptrace_getsetvsxregs = 0;
+          return;
+           perror_with_name (_("Unable to fetch VSX registers"));
+         }
+       #endif
+    }
+  }
+  supply_vsxregset_aix (regcache, &vsx);
+}
+
+
+static void
+supply_vrregset_aix (struct regcache *regcache, __vmx_context_t *vmx)
+{
+  int i;
+ struct gdbarch *gdbarch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
+  int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
+  int offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum);
+
+  for (i = 0; i < num_of_vrregs; i++)
+    {
+      /* The last 2 registers of this set are only 32 bit long, not
+         128.  However an offset is necessary only for VSCR because it
+         occupies a whole vector, while VRSAVE occupies a full 4 bytes
+         slot.  */
+      if (i == (num_of_vrregs - 2))
+       regcache->raw_supply (tdep->ppc_vr0_regnum + i,
+                             &(vmx->__vr[i]));
+      else
+        regcache->raw_supply (tdep->ppc_vr0_regnum + i,
+                             &(vmx->__vr[i]));
+    }
+}
+
+static void
+fetch_altivec_registers_aix (struct regcache *regcache)
+{
+  int ret;
+  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())  {
+    ret = ptrace64 (PTT_READ_VEC, thrd_i, (long long) &vmx, 0, 0);
+   if (ret < 0)
+    {
+       /* Just fill with 0 zero instead of error return */
+       #if 0
+        if (errno == ENXIO)
+         {
+           have_ptrace_getvrregs = 0;
+           return;
+           perror_with_name (_("Unable to fetch AltiVec registers"));
+         }
+       #endif
+    }
+  }   
+  supply_vrregset_aix (regcache, &vmx);
+}   
+
 /* Read from the inferior all registers if REGNO == -1 and just register
    REGNO otherwise.  */
 
@@ -308,10 +519,6 @@
 rs6000_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = regcache->arch ();
-  if (regno != -1)
-    fetch_register (regcache, regno);
-
-  else
     {
       struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
@@ -339,6 +546,18 @@
         fetch_register (regcache, tdep->ppc_fpscr_regnum);
       if (tdep->ppc_mq_regnum >= 0)
 	fetch_register (regcache, tdep->ppc_mq_regnum);
+
+      if (have_ptrace_getvrregs)
+        if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1) 
+        {
+           fetch_altivec_registers_aix (regcache);
+        }
+
+     if (have_ptrace_getsetvsxregs)
+         if (tdep->ppc_vsr0_upper_regnum != -1)
+          {
+            fetch_vsx_registers_aix (regcache);
+          }
     }
 }
 
@@ -550,6 +769,17 @@
 
 /* Set the current architecture from the host running GDB.  Called when
    starting a child process.  */
+
+static const struct target_desc *
+rs6000_nat_target::read_description ()
+{
+   if (ARCH64())
+      return tdesc_powerpc_vsx64;
+   else
+      return tdesc_powerpc_vsx32;
+}
+
+void _initialize_rs6000_nat (void);
 
 void
 rs6000_nat_target::create_inferior (const char *exec_file,
--- ./gdb/rs6000-tdep.c_orig	2021-12-09 00:27:32.879741431 -0600
+++ ./gdb/rs6000-tdep.c	2021-12-10 05:57:59.698759793 -0600
@@ -1850,8 +1850,10 @@
 	 stack.  */
       /* 001110 00000 00000 iiii iiii iiii iiii  */
       /* 001110 01110 00000 iiii iiii iiii iiii  */
+	  /* TODO-AIX: Need some more  improvment */
       else if ((op & 0xffff0000) == 0x38000000         /* li r0, SIMM */
-               || (op & 0xffff0000) == 0x39c00000)     /* li r14, SIMM */
+               || (op & 0xffff0000) == 0x39c00000      /* li r14, SIMM */
+               || (op & 0xff0f0000) == 0x38000000)     /* li, r4, SIMM */
 	{
           if ((op & 0xffff0000) == 0x38000000)
             r0_contains_arg = 0;
@@ -1865,23 +1867,22 @@
 	}
       /* Store vector register S at (r31+r0) aligned to 16 bytes.  */      
       /* 011111 sssss 11111 00000 00111001110 */
-      else if ((op & 0xfc1fffff) == 0x7c1f01ce)   /* stvx Vs, R31, R0 */
+      /* TODO-AIX: Need some more  improvment */
+      else if ((op & 0xfc1fffff) == 0x7c1f01ce    /* stvx Vs, R31, R0 */
+               || (op & 0xfc1fffff) == 0x7c012f99 /* stxvd2x Vs,r1, r5 */
+               || (op & 0xfc1fffff) == 0x7c012f98 /* stxvd2x vs0, r1, r5 */
+               || (op & 0xfc1ff000) == 0x7c012000)
         {
-	  if (pc == (li_found_pc + 4))
-	    {
+	  
 	      vr_reg = GET_SRC_REG (op);
 	      /* If this is the first vector reg to be saved, or if
 		 it has a lower number than others previously seen,
 		 reupdate the frame info.  */
-	      if (fdata->saved_vr == -1 || fdata->saved_vr > vr_reg)
-		{
-		  fdata->saved_vr = vr_reg;
-		  fdata->vr_offset = vr_saved_offset + offset;
-		}
+	      fdata->saved_vr = vr_reg;
+	      fdata->vr_offset = vr_saved_offset;
 	      vr_saved_offset = -1;
 	      vr_reg = -1;
 	      li_found_pc = 0;
-	    }
 	}
       /* End AltiVec related instructions.  */
 
@@ -3338,7 +3339,7 @@
   {"powerpc", "PowerPC user-level", bfd_arch_powerpc,
    bfd_mach_ppc, &tdesc_powerpc_altivec32},
   {"power", "POWER user-level", bfd_arch_rs6000,
-   bfd_mach_rs6k, &tdesc_rs6000},
+   bfd_mach_rs6k, &tdesc_powerpc_vsx32},
   {"403", "IBM PowerPC 403", bfd_arch_powerpc,
    bfd_mach_ppc_403, &tdesc_powerpc_403},
   {"405", "IBM PowerPC 405", bfd_arch_powerpc,
@@ -3368,7 +3369,7 @@
   {"powerpc64", "PowerPC 64-bit user-level", bfd_arch_powerpc,
    bfd_mach_ppc64, &tdesc_powerpc_altivec64},
   {"620", "Motorola PowerPC 620", bfd_arch_powerpc,
-   bfd_mach_ppc_620, &tdesc_powerpc_64},
+   bfd_mach_ppc_620, &tdesc_powerpc_vsx64},
   {"630", "Motorola PowerPC 630", bfd_arch_powerpc,
    bfd_mach_ppc_630, &tdesc_powerpc_64},
   {"a35", "PowerPC A35", bfd_arch_powerpc,
@@ -3544,18 +3545,16 @@
 
   /* if != -1, fdata.saved_vr is the smallest number of saved_vr.
      All vr's from saved_vr to vr31 are saved.  */
+	 /* TODO-AIX: Need some more  improvment */
   if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
     {
-      if (fdata.saved_vr >= 0)
-	{
-	  int i;
-	  CORE_ADDR vr_addr = cache->base + fdata.vr_offset;
-	  for (i = fdata.saved_vr; i < 32; i++)
-	    {
-	      cache->saved_regs[tdep->ppc_vr0_regnum + i].addr = vr_addr;
-	      vr_addr += register_size (gdbarch, tdep->ppc_vr0_regnum);
-	    }
-	}
+      int i;
+          CORE_ADDR vr_addr = cache->base + fdata.vr_offset;
+          for (i = 0; i < 66; i++)
+          {
+            cache->saved_regs[tdep->ppc_vsr0_upper_regnum + i].addr = vr_addr;
+            vr_addr += register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
+          }
     }
 
   /* if != -1, fdata.saved_ev is the smallest number of saved_ev.
--- ./gdb/aix-thread.c_orig	2021-12-09 00:27:46.959186979 -0600
+++ ./gdb/aix-thread.c	2021-12-09 00:33:17.908278996 -0600
@@ -55,6 +55,7 @@
 #include <sys/reg.h>
 #include <sched.h>
 #include <sys/pthdebug.h>
+#include <sys/context.h>
 
 #if !HAVE_DECL_GETTHRDS
 extern int getthrds (pid_t, struct thrdsinfo64 *, int, tid_t *, int);
@@ -1348,6 +1349,55 @@
 	    regcache->raw_supply (tdep->ppc_mq_regnum, (char *) &sprs32.pt_mq);
 	}
     }
+	/* vector registers */
+    if (tdep->ppc_vr0_regnum != -1 && regno >= tdep->ppc_vr0_regnum)
+    {
+       int ret = 0;
+       int i = 0;
+       int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
+       __vmx_context_t vmx;
+       memset(&vmx, 0, sizeof(__vmx_context_t)); 
+       if (__power_vmx())  {
+          ret = ptrace64 (PTT_READ_VEC, tid, (long long) &vmx, 0, 0);
+          if (ret < 0)
+          {
+            /* Just fill with 0 zero instead of error return */
+             #if 0
+              if (errno == ENXIO)
+                 return;
+               perror_with_name (_("Unable to fetch AltiVec registers"));
+             #endif
+          }   
+         for (i = 0; i < num_of_vrregs; i++)
+         {
+             regcache->raw_supply (tdep->ppc_vr0_regnum + i, 
+                                  &(vmx.__vr[i]));
+         }   
+       }
+    }
+    /* vsx registers */
+    if (tdep->ppc_vsr0_upper_regnum != -1 && regno >= tdep->ppc_vsr0_upper_regnum) {
+       __vsx_context_t vsx;
+       memset(&vsx, 0, sizeof(__vsx_context_t)); 
+       if (__power_vsx())  {
+           int i = 0, ret = 0;
+           ret = ptrace64 (PTT_READ_VSX, tid, (long long) &vsx, 0, 0);
+           if (ret < 0)
+           {
+             /* Just fill with zeros instead of error return */
+             #if 0
+               if (errno == ENXIO)
+                 return;
+               perror_with_name (_("Unable to fetch VSX registers"));
+             #endif
+           }
+           for (i = 0; i < ppc_num_vshrs; i++)
+               regcache->raw_supply (tdep->ppc_vsr0_upper_regnum + i,
+                                    &(vsx.__vsr_dw1[i]));
+       } 
+ 
+    }
+
 }
 
 /* Fetch register REGNO if != -1 or all registers otherwise from the
@@ -1577,6 +1627,34 @@
            pd_status2str (status));
 }
 
+
+static void
+fill_altivec (const struct regcache *regcache, __vmx_context_t *vmx)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
+  int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
+  int regno;
+
+  for (regno = 0; regno < num_of_vrregs; regno++)
+    if (REG_VALID == regcache->get_register_status (tdep->ppc_vr0_regnum + regno))
+      regcache->raw_collect (tdep->ppc_vr0_regnum + regno,
+                            &(vmx->__vr[0]) + regno);
+}
+
+static void
+fill_vsx (const struct regcache *regcache, __vsx_context_t  *vsx)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
+  int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
+  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 register REGNO if != -1 or all registers otherwise into
    kernel thread TID.
 
@@ -1685,6 +1763,50 @@
 
 	  ptrace32 (PTT_WRITE_SPRS, tid, (uintptr_t) &sprs32, 0, NULL);
 	}
+    }
+	    /* vector register */
+    if (tdep->ppc_vr0_regnum != -1 && regno >= tdep->ppc_vr0_regnum)
+    {
+       int ret = 0;
+       int i = 0;
+       int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
+       __vmx_context_t vmx;
+       memset(&vmx, 0, sizeof(__vmx_context_t)); 
+      if (__power_vmx())  {
+          ret = ptrace64 (PTT_READ_VEC, tid, (long long) &vmx, 0, 0);
+          if (ret < 0)
+          {
+             if (errno == ENXIO) {
+               //warning (_("Unable to fetch AltiVec registers."));
+               return;
+             }
+          }  
+          fill_altivec(regcache, &vmx);
+          ret = ptrace64 (PTT_WRITE_VEC, tid, (long long) &vmx, 0, 0);
+          if (ret < 0)
+             perror_with_name (_("Unable to store AltiVec register."));
+       }
+   }
+    /* vmx registers */
+   if (tdep->ppc_vsr0_upper_regnum != -1 && regno >= tdep->ppc_vsr0_upper_regnum) {
+       __vsx_context_t vsx;
+      memset(&vsx, 0, sizeof(__vsx_context_t)); 
+       if (__power_vsx())  {
+           int i = 0, ret = 0;
+           ret = ptrace64 (PTT_READ_VSX, tid, (long long) &vsx, 0, 0);
+           if (ret < 0)
+           {
+             if (errno == ENXIO) {
+               //warning (_("Unable to fetch VSX registers."));
+               return;
+             }
+           }
+           fill_vsx (regcache, &vsx);
+           ret = ptrace64 (PTT_WRITE_VSX, tid, (long long) &vsx, 0, 0);
+           if (ret < 0)
+              perror_with_name (_("Unable to store VSX register."));
+
+       }
     }
 }
 
--- ./gdb/rs6000-aix-tdep.c_orig	2021-12-09 00:28:11.513071668 -0600
+++ ./gdb/rs6000-aix-tdep.c	2021-12-10 06:07:46.844304910 -0600
@@ -206,7 +206,22 @@
   4  /* fpscr_size */
 };
 
+struct rs6000_aix_reg_vrreg_offset
+{
+     /* AltiVec registers.  */
+  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 */
+};
+
 /* 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.  */
@@ -234,6 +249,183 @@
   ppc_collect_fpregset (regset, regcache, regnum, gregs, len);
 }
 
+/* Return non-zero if the architecture described by GDBARCH has
+   VSX registers (vsr0 --- vsr63).  */
+static int
+rs6000_aix_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
+rs6000_aix_altivec_support_p (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  return (tdep->ppc_vr0_regnum >= 0
+          && tdep->ppc_vrsave_regnum >= 0);
+}
+
+
+static int
+rs6000_aix_get_vrreg_offset (struct 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;
+}
+
+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 ();
+  struct gdbarch_tdep *tdep;
+  const struct rs6000_aix_reg_vrreg_offset  *offsets;
+  size_t offset;
+
+  if (!rs6000_aix_altivec_support_p (gdbarch))
+    return;
+
+  tdep = gdbarch_tdep (gdbarch);
+  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);
+}
+
+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 ();
+  struct gdbarch_tdep *tdep;
+
+  if (!rs6000_aix_vsx_support_p (gdbarch))
+    return;
+
+  tdep = gdbarch_tdep (gdbarch);
+
+  if (regnum == -1)
+    {
+      int i, offset = 0;;
+
+      for (i = tdep->ppc_vsr0_upper_regnum;
+           i < tdep->ppc_vsr0_upper_regnum + 32;
+           i++, offset++)
+        ppc_supply_reg (regcache, i, (const gdb_byte *) vsxregs, offset * 8, 8);
+
+      return;
+    }
+  else
+    ppc_supply_reg (regcache, regnum, (const gdb_byte *) vsxregs, 0, 8);
+}
+
+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 ();
+  struct gdbarch_tdep *tdep;
+
+  if (!rs6000_aix_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, (gdb_byte *) vsxregs, 0, 8);
+
+      return;
+    }
+  else
+    ppc_collect_reg (regcache, regnum, (gdb_byte *) vsxregs, 0, 8);
+}
+
+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 ();
+  struct gdbarch_tdep *tdep;
+  const struct rs6000_aix_reg_vrreg_offset *offsets;
+  size_t offset;
+
+  if (!rs6000_aix_altivec_support_p (gdbarch))
+    return;
+
+  tdep = gdbarch_tdep (gdbarch);
+  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);
+}
+
+
 /* AIX register set.  */
 
 static const struct regset rs6000_aix32_regset =
@@ -250,6 +442,19 @@
   rs6000_aix_collect_regset,
 };
 
+static const struct regset rs6000_aix32_vrregset = {
+  &rs6000_aix_vrreg_offset,
+  rs6000_aix_supply_vrregset,
+  rs6000_aix_collect_vrregset
+};
+
+static const struct regset rs6000_aix32_vsxregset = {
+  &rs6000_aix_vrreg_offset,
+  rs6000_aix_supply_vsxregset,
+  rs6000_aix_collect_vsxregset
+};
+
+
 /* Iterate over core file register note sections.  */
 
 static void
@@ -258,10 +463,20 @@
 					 void *cb_data,
 					 const struct regcache *regcache)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int have_altivec = tdep->ppc_vr0_regnum != -1;
+  int have_vsx = tdep->ppc_vsr0_upper_regnum != -1;
+
   if (gdbarch_tdep (gdbarch)->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_aix32_vrregset, "AIX altivec", cb_data);
+
+  if (have_vsx)
+    cb (".aix-vsx", 256, 256, &rs6000_aix32_vsxregset, "AIX vsx", cb_data);
 }
 
 
--- ./bfd/aix5ppc-core.c_orig	2021-12-09 00:28:40.294164907 -0600
+++ ./bfd/aix5ppc-core.c	2021-12-09 00:33:45.115559884 -0600
@@ -142,6 +142,29 @@
   sec->filepos = 0;
   sec->contents = (bfd_byte *)&new_core_hdr->c_flt.r64;
 
+  if (core.c_extctx) 
+  {
+      /* .vmx section. */
+      flags = SEC_HAS_CONTENTS;
+      sec = bfd_make_section_anyway_with_flags (abfd, ".aix-vmx", flags);
+      if (NULL == sec)
+        return NULL;
+
+      sec->size = 560;
+      sec->vma = 0;
+      sec->filepos = core.c_extctx;
+
+      /* .vsx section. */
+      flags = SEC_HAS_CONTENTS;
+      sec = bfd_make_section_anyway_with_flags (abfd, ".aix-vsx", flags);
+      if (NULL == sec)
+        return NULL;
+
+      sec->size = 256;
+      sec->vma = 0;
+      sec->filepos = core.c_extctx + 584;
+  }
+
   /* .ldinfo section.
      To actually find out how long this section is in this particular
      core dump would require going down the whole list of struct
--- ./bfd/rs6000-core.c_orig	2021-12-09 00:28:52.292377490 -0600
+++ ./bfd/rs6000-core.c	2021-12-09 00:33:53.507032619 -0600
@@ -343,7 +343,7 @@
   /* Values from new and old core structures.  */
   int c_flag;
   file_ptr c_stack, c_regoff, c_loader;
-  bfd_size_type c_size, c_regsize, c_lsize;
+  bfd_size_type c_size, c_regsize, c_lsize, c_extoff;
   bfd_vma c_stackend;
   void *c_regptr;
   int proc64;
@@ -371,6 +371,7 @@
       c_stackend = CNEW_STACKORG (core.new_dump) + c_size;
       c_lsize = CNEW_LSIZE (core.new_dump);
       c_loader = CNEW_LOADER (core.new_dump);
+	  c_extoff = core.new_dump.c_extctx;
 #ifndef BFD64
       proc64 = CNEW_PROC64 (core.new_dump);
     }
@@ -517,6 +518,19 @@
 			  SEC_HAS_CONTENTS,
 			  c_regsize, (bfd_vma) 0, c_regoff))
     goto fail;
+	
+  if (c_extoff)
+  {
+      if (!make_bfd_asection (abfd, ".aix-vmx",
+                              SEC_HAS_CONTENTS,
+                              560, (bfd_vma) 0, c_extoff))
+        goto fail;
+
+      if (!make_bfd_asection (abfd, ".aix-vsx",
+                            SEC_HAS_CONTENTS,
+                              256, (bfd_vma) 0, c_extoff + 584))
+        goto fail;
+  }
 
   /* .ldinfo section.
      To actually find out how long this section is in this particular
