]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Reverse debugging for PowerPC.
authorWei-cheng Wang <cole945@gmail.com>
Sat, 17 Jan 2015 06:30:33 +0000 (14:30 +0800)
committerCole Wang <cole945@gmail.com>
Sat, 17 Jan 2015 11:48:22 +0000 (19:48 +0800)
gdb/ChangeLog
gdb/configure.tgt
gdb/ppc-linux-tdep.c
gdb/ppc-tdep.h
gdb/rs6000-tdep.c
gdb/testsuite/ChangeLog
gdb/testsuite/lib/gdb.exp

index 982e9aed9b404613d71417a5abff934180b0891b..6866edb954dd04584a96150406497d397b40d6ca 100644 (file)
@@ -1,3 +1,21 @@
+2015-01-17  Wei-cheng Wang  <cole945@gmail.com>
+           Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * configure.tgt (powerpc*-*-linux): Add linux-record.o to
+       gdb_target_obs.
+       (ppc_linux_record_tdep, ppc64_linux_record_tdep): New for linux syscall
+       record.
+       (ppc_canonicalize_syscall, ppc_linux_syscall_record,
+       ppc_linux_record_signal, ppc_init_linux_record_tdep): New functions.
+       (ppc_linux_init_abi): Set process_record, process_record_signal.
+       * ppc-tdep.h (struct gdbarch_tdep): Add ppc_syscall_record and
+       ppc_linux_record_tdep to gdbarch_tdep.
+       (ppc_process_record): New declaration.
+       * rs6000-tdep.c (ppc_record_vsr, ppc_process_record_op4,
+       ppc_process_record_op19, ppc_process_record_op31,
+       ppc_process_record_op59, ppc_process_record_op60,
+       ppc_process_record_op63, ppc_process_record): New functions.
+
 2015-01-17  Wei-cheng Wang  <cole945@gmail.com>
 
        * rs6000-tdep.c (rs6000_in_function_epilogue_p): Rename to
index b2c752f4c8eedf09a81b3a5c378c8d2efa6d6e22..7fdd34e4285fbf90602676ed8712b4c7b869a260 100644 (file)
@@ -439,7 +439,8 @@ powerpc*-*-linux*)
                        ppc64-tdep.o solib-svr4.o solib-spu.o \
                        spu-multiarch.o \
                        glibc-tdep.o symfile-mem.o linux-tdep.o \
-                       ravenscar-thread.o ppc-ravenscar-thread.o"
+                       ravenscar-thread.o ppc-ravenscar-thread.o \
+                       linux-record.o "
        gdb_sim=../sim/ppc/libsim.a
        build_gdbserver=yes
        ;;
index 8bb9a222df5cf1324d1b2f3ba2ab6340d6eb148a..dcfd3bb9f9746377499bf8edf03601ddbcca46f1 100644 (file)
@@ -49,6 +49,8 @@
 #include "spu-tdep.h"
 #include "xml-syscall.h"
 #include "linux-tdep.h"
+#include "linux-record.h"
+#include "record-full.h"
 
 #include "stap-probe.h"
 #include "ax.h"
@@ -764,6 +766,167 @@ ppc_linux_get_syscall_number (struct gdbarch *gdbarch,
   return ret;
 }
 
+/* PPC process record-replay */
+
+static struct linux_record_tdep ppc_linux_record_tdep;
+static struct linux_record_tdep ppc64_linux_record_tdep;
+
+static enum gdb_syscall
+ppc_canonicalize_syscall (int syscall)
+{
+  /* See arch/powerpc/include/uapi/asm/unistd.h */
+
+  if (syscall <= 165)
+    return syscall;
+  else if (syscall >= 167 && syscall <= 190)   /* Skip query_module 166 */
+    return syscall + 1;
+  else if (syscall >= 192 && syscall <= 197)   /* mmap2 */
+    return syscall;
+  else if (syscall == 208)                     /* tkill */
+    return gdb_sys_tkill;
+  else if (syscall >= 207 && syscall <= 220)   /* gettid */
+    return syscall + 224 - 207;
+  else if (syscall >= 234 && syscall <= 239)   /* exit_group */
+    return syscall + 252 - 234;
+  else if (syscall >= 240 && syscall <=248)    /* timer_create */
+    return syscall += 259 - 240;
+  else if (syscall >= 250 && syscall <=251)    /* tgkill */
+    return syscall + 270 - 250;
+  else if (syscall == 336)
+    return gdb_sys_recv;
+  else if (syscall == 337)
+    return gdb_sys_recvfrom;
+  else if (syscall == 342)
+    return gdb_sys_recvmsg;
+  return -1;
+}
+
+static int
+ppc_linux_syscall_record (struct regcache *regcache)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ULONGEST scnum;
+  enum gdb_syscall syscall_gdb;
+  int ret;
+  int i;
+
+  regcache_raw_read_unsigned (regcache, tdep->ppc_gp0_regnum, &scnum);
+  syscall_gdb = ppc_canonicalize_syscall (scnum);
+
+  if (syscall_gdb < 0)
+    {
+      printf_unfiltered (_("Process record and replay target doesn't "
+                          "support syscall number %d\n"), (int) scnum);
+      return 0;
+    }
+
+  if (syscall_gdb == gdb_sys_sigreturn
+      || syscall_gdb == gdb_sys_rt_sigreturn)
+   {
+     int i, j;
+     int regsets[] = { tdep->ppc_gp0_regnum,
+                      tdep->ppc_fp0_regnum,
+                      tdep->ppc_vr0_regnum,
+                      tdep->ppc_vsr0_upper_regnum };
+
+     for (j = 0; j < 4; j++)
+       {
+        if (regsets[j] == -1)
+          continue;
+        for (i = 0; i < 32; i++)
+          {
+            if (record_full_arch_list_add_reg (regcache, regsets[j] + i))
+              return -1;
+          }
+       }
+
+     if (record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum))
+       return -1;
+     if (record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum))
+       return -1;
+     if (record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum))
+       return -1;
+     if (record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum))
+       return -1;
+
+     return 0;
+   }
+
+  if (tdep->wordsize == 8)
+    ret = record_linux_system_call (syscall_gdb, regcache,
+                                   &ppc64_linux_record_tdep);
+  else
+    ret = record_linux_system_call (syscall_gdb, regcache,
+                                   &ppc_linux_record_tdep);
+
+  if (ret != 0)
+    return ret;
+
+  /* Record registers clobbered during syscall.  */
+  for (i = 3; i <= 12; i++)
+    {
+      if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + i))
+       return -1;
+    }
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 0))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum))
+    return -1;
+
+  return 0;
+}
+
+static int
+ppc_linux_record_signal (struct gdbarch *gdbarch, struct regcache *regcache,
+                        enum gdb_signal signal)
+{
+  /* See handle_rt_signal64 in arch/powerpc/kernel/signal_64.c
+        handle_rt_signal32 in arch/powerpc/kernel/signal_32.c
+        arch/powerpc/include/asm/ptrace.h
+     for details.  */
+  const int SIGNAL_FRAMESIZE = 128;
+  const int sizeof_rt_sigframe = 1440 * 2 + 8 * 2 + 4 * 6 + 8 + 8 + 128 + 512;
+  ULONGEST sp;
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int i;
+
+  for (i = 3; i <= 12; i++)
+    {
+      if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + i))
+       return -1;
+    }
+
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, gdbarch_pc_regnum (gdbarch)))
+    return -1;
+  if (record_full_arch_list_add_reg (regcache, gdbarch_sp_regnum (gdbarch)))
+    return -1;
+
+  /* Record the change in the stack.
+     frame-size = sizeof (struct rt_sigframe) + SIGNAL_FRAMESIZE  */
+  regcache_raw_read_unsigned (regcache, gdbarch_sp_regnum (gdbarch), &sp);
+  sp -= SIGNAL_FRAMESIZE;
+  sp -= sizeof_rt_sigframe;
+
+  if (record_full_arch_list_add_mem (sp, SIGNAL_FRAMESIZE + sizeof_rt_sigframe))
+    return -1;
+
+  if (record_full_arch_list_add_end ())
+    return -1;
+
+  return 0;
+}
+
 static void
 ppc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
@@ -1234,6 +1397,234 @@ static const struct frame_unwind ppu2spu_unwind = {
   ppu2spu_prev_arch,
 };
 
+/* Initialize linux_record_tdep if not initialized yet.  */
+
+static void
+ppc_init_linux_record_tdep (struct linux_record_tdep *record_tdep,
+                           int wordsize)
+{
+  /* Simply return if it had been initialized.  */
+  if (record_tdep->size_pointer != 0)
+    return;
+
+  /* These values are the size of the type that will be used in a system
+     call.  They are obtained from Linux Kernel source.  */
+
+  if (wordsize == 8)
+    {
+      record_tdep->size_pointer = 8;
+      record_tdep->size__old_kernel_stat = 32;
+      record_tdep->size_tms = 32;
+      record_tdep->size_loff_t = 8;
+      record_tdep->size_flock = 32;
+      record_tdep->size_oldold_utsname = 45;
+      record_tdep->size_ustat = 32;
+      record_tdep->size_old_sigaction = 152;
+      record_tdep->size_old_sigset_t = 128;
+      record_tdep->size_rlimit = 16;
+      record_tdep->size_rusage = 144;
+      record_tdep->size_timeval = 16;
+      record_tdep->size_timezone = 8;
+      record_tdep->size_old_gid_t = 4;
+      record_tdep->size_old_uid_t = 4;
+      record_tdep->size_fd_set = 128;
+      record_tdep->size_dirent = 280;
+      record_tdep->size_dirent64 = 280;
+      record_tdep->size_statfs = 120;
+      record_tdep->size_statfs64 = 120;
+      record_tdep->size_sockaddr = 16;
+      record_tdep->size_int = 4;
+      record_tdep->size_long = 8;
+      record_tdep->size_ulong = 8;
+      record_tdep->size_msghdr = 56;
+      record_tdep->size_itimerval = 32;
+      record_tdep->size_stat = 144;
+      record_tdep->size_old_utsname = 325;
+      record_tdep->size_sysinfo = 112;
+      record_tdep->size_msqid_ds = 120;
+      record_tdep->size_shmid_ds = 112;
+      record_tdep->size_new_utsname = 390;
+      record_tdep->size_timex = 208;
+      record_tdep->size_mem_dqinfo = 24;
+      record_tdep->size_if_dqblk = 72;
+      record_tdep->size_fs_quota_stat = 80;
+      record_tdep->size_timespec = 16;
+      record_tdep->size_pollfd = 8;
+      record_tdep->size_NFS_FHSIZE = 32;
+      record_tdep->size_knfsd_fh = 132;
+      record_tdep->size_TASK_COMM_LEN = 32;
+      record_tdep->size_sigaction = 152;
+      record_tdep->size_sigset_t = 128;
+      record_tdep->size_siginfo_t = 128;
+      record_tdep->size_cap_user_data_t = 8;
+      record_tdep->size_stack_t = 24;
+      record_tdep->size_off_t = 8;
+      record_tdep->size_stat64 = 104;
+      record_tdep->size_gid_t = 4;
+      record_tdep->size_uid_t = 4;
+      record_tdep->size_PAGE_SIZE = 0x10000;   /* 64KB */
+      record_tdep->size_flock64 = 32;
+      record_tdep->size_io_event = 32;
+      record_tdep->size_iocb = 64;
+      record_tdep->size_epoll_event = 16;
+      record_tdep->size_itimerspec = 32;
+      record_tdep->size_mq_attr = 64;
+      record_tdep->size_siginfo = 128;
+      record_tdep->size_termios = 44;
+      record_tdep->size_pid_t = 4;
+      record_tdep->size_winsize = 8;
+      record_tdep->size_serial_struct = 72;
+      record_tdep->size_serial_icounter_struct = 80;
+      record_tdep->size_size_t = 8;
+      record_tdep->size_iovec = 16;
+    }
+  else if (wordsize == 4)
+    {
+      record_tdep->size_pointer = 4;
+      record_tdep->size__old_kernel_stat = 32;
+      record_tdep->size_tms = 16;
+      record_tdep->size_loff_t = 8;
+      record_tdep->size_flock = 16;
+      record_tdep->size_oldold_utsname = 45;
+      record_tdep->size_ustat = 20;
+      record_tdep->size_old_sigaction = 152;
+      record_tdep->size_old_sigset_t = 128;
+      record_tdep->size_rlimit = 8;
+      record_tdep->size_rusage = 72;
+      record_tdep->size_timeval = 8;
+      record_tdep->size_timezone = 8;
+      record_tdep->size_old_gid_t = 4;
+      record_tdep->size_old_uid_t = 4;
+      record_tdep->size_fd_set = 128;
+      record_tdep->size_dirent = 268;
+      record_tdep->size_dirent64 = 280;
+      record_tdep->size_statfs = 64;
+      record_tdep->size_statfs64 = 88;
+      record_tdep->size_sockaddr = 16;
+      record_tdep->size_int = 4;
+      record_tdep->size_long = 4;
+      record_tdep->size_ulong = 4;
+      record_tdep->size_msghdr = 28;
+      record_tdep->size_itimerval = 16;
+      record_tdep->size_stat = 88;
+      record_tdep->size_old_utsname = 325;
+      record_tdep->size_sysinfo = 64;
+      record_tdep->size_msqid_ds = 68;
+      record_tdep->size_shmid_ds = 60;
+      record_tdep->size_new_utsname = 390;
+      record_tdep->size_timex = 128;
+      record_tdep->size_mem_dqinfo = 24;
+      record_tdep->size_if_dqblk = 72;
+      record_tdep->size_fs_quota_stat = 80;
+      record_tdep->size_timespec = 8;
+      record_tdep->size_pollfd = 8;
+      record_tdep->size_NFS_FHSIZE = 32;
+      record_tdep->size_knfsd_fh = 132;
+      record_tdep->size_TASK_COMM_LEN = 32;
+      record_tdep->size_sigaction = 140;
+      record_tdep->size_sigset_t = 128;
+      record_tdep->size_siginfo_t = 128;
+      record_tdep->size_cap_user_data_t = 4;
+      record_tdep->size_stack_t = 12;
+      record_tdep->size_off_t = 4;
+      record_tdep->size_stat64 = 104;
+      record_tdep->size_gid_t = 4;
+      record_tdep->size_uid_t = 4;
+      record_tdep->size_PAGE_SIZE = 0x10000;   /* 64KB */
+      record_tdep->size_flock64 = 32;
+      record_tdep->size_io_event = 32;
+      record_tdep->size_iocb = 64;
+      record_tdep->size_epoll_event = 16;
+      record_tdep->size_itimerspec = 16;
+      record_tdep->size_mq_attr = 32;
+      record_tdep->size_siginfo = 128;
+      record_tdep->size_termios = 44;
+      record_tdep->size_pid_t = 4;
+      record_tdep->size_winsize = 8;
+      record_tdep->size_serial_struct = 60;
+      record_tdep->size_serial_icounter_struct = 80;
+      record_tdep->size_size_t = 4;
+      record_tdep->size_iovec = 8;
+    }
+  else
+    internal_error (__FILE__, __LINE__, _("unexpected wordsize"));
+
+  /* These values are the second argument of system call "sys_fcntl"
+     and "sys_fcntl64".  They are obtained from Linux Kernel source.  */
+  record_tdep->fcntl_F_GETLK = 5;
+  record_tdep->fcntl_F_GETLK64 = 12;
+  record_tdep->fcntl_F_SETLK64 = 13;
+  record_tdep->fcntl_F_SETLKW64 = 14;
+
+  record_tdep->arg1 = PPC_R0_REGNUM + 3;
+  record_tdep->arg2 = PPC_R0_REGNUM + 4;
+  record_tdep->arg3 = PPC_R0_REGNUM + 5;
+  record_tdep->arg4 = PPC_R0_REGNUM + 6;
+  record_tdep->arg5 = PPC_R0_REGNUM + 7;
+  record_tdep->arg6 = PPC_R0_REGNUM + 8;
+
+  /* These values are the second argument of system call "sys_ioctl".
+     They are obtained from Linux Kernel source.
+     See arch/powerpc/include/uapi/asm/ioctls.h.  */
+  record_tdep->ioctl_TCGETS = 0x403c7413;
+  record_tdep->ioctl_TCSETS = 0x803c7414;
+  record_tdep->ioctl_TCSETSW = 0x803c7415;
+  record_tdep->ioctl_TCSETSF = 0x803c7416;
+  record_tdep->ioctl_TCGETA = 0x40147417;
+  record_tdep->ioctl_TCSETA = 0x80147418;
+  record_tdep->ioctl_TCSETAW = 0x80147419;
+  record_tdep->ioctl_TCSETAF = 0x8014741c;
+  record_tdep->ioctl_TCSBRK = 0x2000741d;
+  record_tdep->ioctl_TCXONC = 0x2000741e;
+  record_tdep->ioctl_TCFLSH = 0x2000741f;
+  record_tdep->ioctl_TIOCEXCL = 0x540c;
+  record_tdep->ioctl_TIOCNXCL = 0x540d;
+  record_tdep->ioctl_TIOCSCTTY = 0x540e;
+  record_tdep->ioctl_TIOCGPGRP = 0x40047477;
+  record_tdep->ioctl_TIOCSPGRP = 0x80047476;
+  record_tdep->ioctl_TIOCOUTQ = 0x40047473;
+  record_tdep->ioctl_TIOCSTI = 0x5412;
+  record_tdep->ioctl_TIOCGWINSZ = 0x40087468;
+  record_tdep->ioctl_TIOCSWINSZ = 0x80087467;
+  record_tdep->ioctl_TIOCMGET = 0x5415;
+  record_tdep->ioctl_TIOCMBIS = 0x5416;
+  record_tdep->ioctl_TIOCMBIC = 0x5417;
+  record_tdep->ioctl_TIOCMSET = 0x5418;
+  record_tdep->ioctl_TIOCGSOFTCAR = 0x5419;
+  record_tdep->ioctl_TIOCSSOFTCAR = 0x541a;
+  record_tdep->ioctl_FIONREAD = 0x4004667f;
+  record_tdep->ioctl_TIOCINQ = 0x4004667f;
+  record_tdep->ioctl_TIOCLINUX = 0x541c;
+  record_tdep->ioctl_TIOCCONS = 0x541d;
+  record_tdep->ioctl_TIOCGSERIAL = 0x541e;
+  record_tdep->ioctl_TIOCSSERIAL = 0x541f;
+  record_tdep->ioctl_TIOCPKT = 0x5420;
+  record_tdep->ioctl_FIONBIO = 0x8004667e;
+  record_tdep->ioctl_TIOCNOTTY = 0x5422;
+  record_tdep->ioctl_TIOCSETD = 0x5423;
+  record_tdep->ioctl_TIOCGETD = 0x5424;
+  record_tdep->ioctl_TCSBRKP = 0x5425;
+  record_tdep->ioctl_TIOCSBRK = 0x5427;
+  record_tdep->ioctl_TIOCCBRK = 0x5428;
+  record_tdep->ioctl_TIOCGSID = 0x5429;
+  record_tdep->ioctl_TIOCGPTN = 0x40045430;
+  record_tdep->ioctl_TIOCSPTLCK = 0x80045431;
+  record_tdep->ioctl_FIONCLEX = 0x20006602;
+  record_tdep->ioctl_FIOCLEX = 0x20006601;
+  record_tdep->ioctl_FIOASYNC = 0x8004667d;
+  record_tdep->ioctl_TIOCSERCONFIG = 0x5453;
+  record_tdep->ioctl_TIOCSERGWILD = 0x5454;
+  record_tdep->ioctl_TIOCSERSWILD = 0x5455;
+  record_tdep->ioctl_TIOCGLCKTRMIOS = 0x5456;
+  record_tdep->ioctl_TIOCSLCKTRMIOS = 0x5457;
+  record_tdep->ioctl_TIOCSERGSTRUCT = 0x5458;
+  record_tdep->ioctl_TIOCSERGETLSR = 0x5459;
+  record_tdep->ioctl_TIOCSERGETMULTI = 0x545a;
+  record_tdep->ioctl_TIOCSERSETMULTI = 0x545b;
+  record_tdep->ioctl_TIOCMIWAIT = 0x545c;
+  record_tdep->ioctl_TIOCGICOUNT = 0x545d;
+  record_tdep->ioctl_FIOQSIZE = 0x40086680;
+}
 
 static void
 ppc_linux_init_abi (struct gdbarch_info info,
@@ -1414,6 +1805,14 @@ ppc_linux_init_abi (struct gdbarch_info info,
     }
 
   set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
+
+  /* Support reverse debugging.  */
+  set_gdbarch_process_record (gdbarch, ppc_process_record);
+  set_gdbarch_process_record_signal (gdbarch, ppc_linux_record_signal);
+  tdep->ppc_syscall_record = ppc_linux_syscall_record;
+
+  ppc_init_linux_record_tdep (&ppc_linux_record_tdep, 4);
+  ppc_init_linux_record_tdep (&ppc64_linux_record_tdep, 8);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
index 11d505c0e508009ba2bc7c57a6566c9b77760ddb..68f3a74eecb377e50f18688ef132157f5dd98ab3 100644 (file)
@@ -259,6 +259,8 @@ struct gdbarch_tdep
     /* ISA-specific types.  */
     struct type *ppc_builtin_type_vec64;
     struct type *ppc_builtin_type_vec128;
+
+    int (*ppc_syscall_record) (struct regcache *regcache);
 };
 
 
@@ -318,6 +320,9 @@ extern CORE_ADDR ppc_insn_d_field (unsigned int insn);
 
 extern CORE_ADDR ppc_insn_ds_field (unsigned int insn);
 
+extern int ppc_process_record (struct gdbarch *gdbarch,
+                              struct regcache *regcache, CORE_ADDR addr);
+
 /* Instruction size.  */
 #define PPC_INSN_SIZE 4
 
index e6e2e60a81dc83909fb82157f789ecb81fdf8d4a..75811d105c03ddbf175058f1645093649185a92b 100644 (file)
@@ -40,6 +40,8 @@
 #include "dwarf2-frame.h"
 #include "target-descriptions.h"
 #include "user-regs.h"
+#include "record-full.h"
+#include "auxv.h"
 
 #include "libbfd.h"            /* for bfd_default_set_arch_mach */
 #include "coff/internal.h"     /* for libcoff.h */
@@ -3633,6 +3635,1681 @@ bfd_uses_spe_extensions (bfd *abfd)
   return success;
 }
 
+/* These are macros for parsing instruction fields (I.1.6.28)  */
+
+#define PPC_FIELD(value, from, len) \
+       (((value) >> (32 - (from) - (len))) & ((1 << (len)) - 1))
+#define PPC_SEXT(v, bs) \
+       ((((CORE_ADDR) (v) & (((CORE_ADDR) 1 << (bs)) - 1)) \
+         ^ ((CORE_ADDR) 1 << ((bs) - 1))) \
+        - ((CORE_ADDR) 1 << ((bs) - 1)))
+#define PPC_OP6(insn)  PPC_FIELD (insn, 0, 6)
+#define PPC_EXTOP(insn)        PPC_FIELD (insn, 21, 10)
+#define PPC_RT(insn)   PPC_FIELD (insn, 6, 5)
+#define PPC_RS(insn)   PPC_FIELD (insn, 6, 5)
+#define PPC_RA(insn)   PPC_FIELD (insn, 11, 5)
+#define PPC_RB(insn)   PPC_FIELD (insn, 16, 5)
+#define PPC_NB(insn)   PPC_FIELD (insn, 16, 5)
+#define PPC_VRT(insn)  PPC_FIELD (insn, 6, 5)
+#define PPC_FRT(insn)  PPC_FIELD (insn, 6, 5)
+#define PPC_SPR(insn)  (PPC_FIELD (insn, 11, 5) \
+                       | (PPC_FIELD (insn, 16, 5) << 5))
+#define PPC_BO(insn)   PPC_FIELD (insn, 6, 5)
+#define PPC_T(insn)    PPC_FIELD (insn, 6, 5)
+#define PPC_D(insn)    PPC_SEXT (PPC_FIELD (insn, 16, 16), 16)
+#define PPC_DS(insn)   PPC_SEXT (PPC_FIELD (insn, 16, 14), 14)
+#define PPC_BIT(insn,n)        ((insn & (1 << (31 - (n)))) ? 1 : 0)
+#define PPC_OE(insn)   PPC_BIT (insn, 21)
+#define PPC_RC(insn)   PPC_BIT (insn, 31)
+#define PPC_Rc(insn)   PPC_BIT (insn, 21)
+#define PPC_LK(insn)   PPC_BIT (insn, 31)
+#define PPC_TX(insn)   PPC_BIT (insn, 31)
+#define PPC_LEV(insn)  PPC_FIELD (insn, 20, 7)
+
+#define PPC_XT(insn)   ((PPC_TX (insn) << 5) | PPC_T (insn))
+#define PPC_XER_NB(xer)        (xer & 0x7f)
+
+/* Record Vector-Scalar Registers.  */
+
+static int
+ppc_record_vsr (struct regcache *regcache, struct gdbarch_tdep *tdep, int vsr)
+{
+  if (vsr < 0 || vsr >= 64)
+    return -1;
+
+  if (vsr >= 32)
+    {
+      if (tdep->ppc_vr0_regnum >= 0)
+       record_full_arch_list_add_reg (regcache, tdep->ppc_vr0_regnum + vsr - 32);
+    }
+  else
+    {
+      if (tdep->ppc_fp0_regnum >= 0)
+       record_full_arch_list_add_reg (regcache, tdep->ppc_fp0_regnum + vsr);
+      if (tdep->ppc_vsr0_upper_regnum >= 0)
+       record_full_arch_list_add_reg (regcache,
+                                      tdep->ppc_vsr0_upper_regnum + vsr);
+    }
+
+  return 0;
+}
+
+/* Parse instructions of primary opcode-4.  */
+
+static int
+ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
+                          CORE_ADDR addr, uint32_t insn)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int ext = PPC_FIELD (insn, 21, 11);
+
+  switch (ext & 0x3f)
+    {
+    case 32:           /* Vector Multiply-High-Add Signed Halfword Saturate */
+    case 33:           /* Vector Multiply-High-Round-Add Signed Halfword Saturate */
+    case 39:           /* Vector Multiply-Sum Unsigned Halfword Saturate */
+    case 41:           /* Vector Multiply-Sum Signed Halfword Saturate */
+      record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
+      /* FALL-THROUGH */
+    case 42:           /* Vector Select */
+    case 43:           /* Vector Permute */
+    case 44:           /* Vector Shift Left Double by Octet Immediate */
+    case 45:           /* Vector Permute and Exclusive-OR */
+    case 60:           /* Vector Add Extended Unsigned Quadword Modulo */
+    case 61:           /* Vector Add Extended & write Carry Unsigned Quadword */
+    case 62:           /* Vector Subtract Extended Unsigned Quadword Modulo */
+    case 63:           /* Vector Subtract Extended & write Carry Unsigned Quadword */
+    case 34:           /* Vector Multiply-Low-Add Unsigned Halfword Modulo */
+    case 36:           /* Vector Multiply-Sum Unsigned Byte Modulo */
+    case 37:           /* Vector Multiply-Sum Mixed Byte Modulo */
+    case 38:           /* Vector Multiply-Sum Unsigned Halfword Modulo */
+    case 40:           /* Vector Multiply-Sum Signed Halfword Modulo */
+    case 46:           /* Vector Multiply-Add Single-Precision */
+    case 47:           /* Vector Negative Multiply-Subtract Single-Precision */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_vr0_regnum + PPC_VRT (insn));
+      return 0;
+    }
+
+  switch ((ext & 0x1ff))
+    {
+                       /* 5.16 Decimal Integer Arithmetic Instructions */
+    case 1:            /* Decimal Add Modulo */
+    case 65:           /* Decimal Subtract Modulo */
+
+      /* Bit-21 should be set.  */
+      if (!PPC_BIT (insn, 21))
+       break;
+
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_vr0_regnum + PPC_VRT (insn));
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+    }
+
+  /* Bit-21 is used for RC */
+  switch (ext & 0x3ff)
+    {
+    case 6:            /* Vector Compare Equal To Unsigned Byte */
+    case 70:           /* Vector Compare Equal To Unsigned Halfword */
+    case 134:          /* Vector Compare Equal To Unsigned Word */
+    case 199:          /* Vector Compare Equal To Unsigned Doubleword */
+    case 774:          /* Vector Compare Greater Than Signed Byte */
+    case 838:          /* Vector Compare Greater Than Signed Halfword */
+    case 902:          /* Vector Compare Greater Than Signed Word */
+    case 967:          /* Vector Compare Greater Than Signed Doubleword */
+    case 518:          /* Vector Compare Greater Than Unsigned Byte */
+    case 646:          /* Vector Compare Greater Than Unsigned Word */
+    case 582:          /* Vector Compare Greater Than Unsigned Halfword */
+    case 711:          /* Vector Compare Greater Than Unsigned Doubleword */
+    case 966:          /* Vector Compare Bounds Single-Precision */
+    case 198:          /* Vector Compare Equal To Single-Precision */
+    case 454:          /* Vector Compare Greater Than or Equal To Single-Precision */
+    case 710:          /* Vector Compare Greater Than Single-Precision */
+      if (PPC_Rc (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_vr0_regnum + PPC_VRT (insn));
+      return 0;
+    }
+
+  switch (ext)
+    {
+    case 142:          /* Vector Pack Unsigned Halfword Unsigned Saturate */
+    case 206:          /* Vector Pack Unsigned Word Unsigned Saturate */
+    case 270:          /* Vector Pack Signed Halfword Unsigned Saturate */
+    case 334:          /* Vector Pack Signed Word Unsigned Saturate */
+    case 398:          /* Vector Pack Signed Halfword Signed Saturate */
+    case 462:          /* Vector Pack Signed Word Signed Saturate */
+    case 1230:         /* Vector Pack Unsigned Doubleword Unsigned Saturate */
+    case 1358:         /* Vector Pack Signed Doubleword Unsigned Saturate */
+    case 1486:         /* Vector Pack Signed Doubleword Signed Saturate */
+    case 512:          /* Vector Add Unsigned Byte Saturate */
+    case 576:          /* Vector Add Unsigned Halfword Saturate */
+    case 640:          /* Vector Add Unsigned Word Saturate */
+    case 768:          /* Vector Add Signed Byte Saturate */
+    case 832:          /* Vector Add Signed Halfword Saturate */
+    case 896:          /* Vector Add Signed Word Saturate */
+    case 1536:         /* Vector Subtract Unsigned Byte Saturate */
+    case 1600:         /* Vector Subtract Unsigned Halfword Saturate */
+    case 1664:         /* Vector Subtract Unsigned Word Saturate */
+    case 1792:         /* Vector Subtract Signed Byte Saturate */
+    case 1856:         /* Vector Subtract Signed Halfword Saturate */
+    case 1920:         /* Vector Subtract Signed Word Saturate */
+
+    case 1544:         /* Vector Sum across Quarter Unsigned Byte Saturate */
+    case 1800:         /* Vector Sum across Quarter Signed Byte Saturate */
+    case 1608:         /* Vector Sum across Quarter Signed Halfword Saturate */
+    case 1672:         /* Vector Sum across Half Signed Word Saturate */
+    case 1928:         /* Vector Sum across Signed Word Saturate */
+    case 970:          /* Vector Convert To Signed Fixed-Point Word Saturate */
+    case 906:          /* Vector Convert To Unsigned Fixed-Point Word Saturate */
+      record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
+      /* FALL-THROUGH */
+    case 12:           /* Vector Merge High Byte */
+    case 14:           /* Vector Pack Unsigned Halfword Unsigned Modulo */
+    case 76:           /* Vector Merge High Halfword */
+    case 78:           /* Vector Pack Unsigned Word Unsigned Modulo */
+    case 140:          /* Vector Merge High Word */
+    case 268:          /* Vector Merge Low Byte */
+    case 332:          /* Vector Merge Low Halfword */
+    case 396:          /* Vector Merge Low Word */
+    case 526:          /* Vector Unpack High Signed Byte */
+    case 590:          /* Vector Unpack High Signed Halfword */
+    case 654:          /* Vector Unpack Low Signed Byte */
+    case 718:          /* Vector Unpack Low Signed Halfword */
+    case 782:          /* Vector Pack Pixel */
+    case 846:          /* Vector Unpack High Pixel */
+    case 974:          /* Vector Unpack Low Pixel */
+    case 1102:         /* Vector Pack Unsigned Doubleword Unsigned Modulo */
+    case 1614:         /* Vector Unpack High Signed Word */
+    case 1676:         /* Vector Merge Odd Word */
+    case 1742:         /* Vector Unpack Low Signed Word */
+    case 1932:         /* Vector Merge Even Word */
+    case 524:          /* Vector Splat Byte */
+    case 588:          /* Vector Splat Halfword */
+    case 652:          /* Vector Splat Word */
+    case 780:          /* Vector Splat Immediate Signed Byte */
+    case 844:          /* Vector Splat Immediate Signed Halfword */
+    case 908:          /* Vector Splat Immediate Signed Word */
+    case 452:          /* Vector Shift Left */
+    case 708:          /* Vector Shift Right */
+    case 1036:         /* Vector Shift Left by Octet */
+    case 1100:         /* Vector Shift Right by Octet */
+    case 0:            /* Vector Add Unsigned Byte Modulo */
+    case 64:           /* Vector Add Unsigned Halfword Modulo */
+    case 128:          /* Vector Add Unsigned Word Modulo */
+    case 192:          /* Vector Add Unsigned Doubleword Modulo */
+    case 256:          /* Vector Add Unsigned Quadword Modulo */
+    case 320:          /* Vector Add & write Carry Unsigned Quadword */
+    case 384:          /* Vector Add and Write Carry-Out Unsigned Word */
+    case 8:            /* Vector Multiply Odd Unsigned Byte */
+    case 72:           /* Vector Multiply Odd Unsigned Halfword */
+    case 136:          /* Vector Multiply Odd Unsigned Word */
+    case 264:          /* Vector Multiply Odd Signed Byte */
+    case 328:          /* Vector Multiply Odd Signed Halfword */
+    case 392:          /* Vector Multiply Odd Signed Word */
+    case 520:          /* Vector Multiply Even Unsigned Byte */
+    case 584:          /* Vector Multiply Even Unsigned Halfword */
+    case 648:          /* Vector Multiply Even Unsigned Word */
+    case 776:          /* Vector Multiply Even Signed Byte */
+    case 840:          /* Vector Multiply Even Signed Halfword */
+    case 904:          /* Vector Multiply Even Signed Word */
+    case 137:          /* Vector Multiply Unsigned Word Modulo */
+    case 1024:         /* Vector Subtract Unsigned Byte Modulo */
+    case 1088:         /* Vector Subtract Unsigned Halfword Modulo */
+    case 1152:         /* Vector Subtract Unsigned Word Modulo */
+    case 1216:         /* Vector Subtract Unsigned Doubleword Modulo */
+    case 1280:         /* Vector Subtract Unsigned Quadword Modulo */
+    case 1344:         /* Vector Subtract & write Carry Unsigned Quadword */
+    case 1408:         /* Vector Subtract and Write Carry-Out Unsigned Word */
+    case 1282:         /* Vector Average Signed Byte */
+    case 1346:         /* Vector Average Signed Halfword */
+    case 1410:         /* Vector Average Signed Word */
+    case 1026:         /* Vector Average Unsigned Byte */
+    case 1090:         /* Vector Average Unsigned Halfword */
+    case 1154:         /* Vector Average Unsigned Word */
+    case 258:          /* Vector Maximum Signed Byte */
+    case 322:          /* Vector Maximum Signed Halfword */
+    case 386:          /* Vector Maximum Signed Word */
+    case 450:          /* Vector Maximum Signed Doubleword */
+    case 2:            /* Vector Maximum Unsigned Byte */
+    case 66:           /* Vector Maximum Unsigned Halfword */
+    case 130:          /* Vector Maximum Unsigned Word */
+    case 194:          /* Vector Maximum Unsigned Doubleword */
+    case 770:          /* Vector Minimum Signed Byte */
+    case 834:          /* Vector Minimum Signed Halfword */
+    case 898:          /* Vector Minimum Signed Word */
+    case 962:          /* Vector Minimum Signed Doubleword */
+    case 514:          /* Vector Minimum Unsigned Byte */
+    case 578:          /* Vector Minimum Unsigned Halfword */
+    case 642:          /* Vector Minimum Unsigned Word */
+    case 706:          /* Vector Minimum Unsigned Doubleword */
+    case 1028:         /* Vector Logical AND */
+    case 1668:         /* Vector Logical Equivalent */
+    case 1092:         /* Vector Logical AND with Complement */
+    case 1412:         /* Vector Logical NAND */
+    case 1348:         /* Vector Logical OR with Complement */
+    case 1156:         /* Vector Logical OR */
+    case 1284:         /* Vector Logical NOR */
+    case 1220:         /* Vector Logical XOR */
+    case 4:            /* Vector Rotate Left Byte */
+    case 132:          /* Vector Rotate Left Word VX-form */
+    case 68:           /* Vector Rotate Left Halfword */
+    case 196:          /* Vector Rotate Left Doubleword */
+    case 260:          /* Vector Shift Left Byte */
+    case 388:          /* Vector Shift Left Word */
+    case 324:          /* Vector Shift Left Halfword */
+    case 1476:         /* Vector Shift Left Doubleword */
+    case 516:          /* Vector Shift Right Byte */
+    case 644:          /* Vector Shift Right Word */
+    case 580:          /* Vector Shift Right Halfword */
+    case 1732:         /* Vector Shift Right Doubleword */
+    case 772:          /* Vector Shift Right Algebraic Byte */
+    case 900:          /* Vector Shift Right Algebraic Word */
+    case 836:          /* Vector Shift Right Algebraic Halfword */
+    case 964:          /* Vector Shift Right Algebraic Doubleword */
+    case 10:           /* Vector Add Single-Precision */
+    case 74:           /* Vector Subtract Single-Precision */
+    case 1034:         /* Vector Maximum Single-Precision */
+    case 1098:         /* Vector Minimum Single-Precision */
+    case 842:          /* Vector Convert From Signed Fixed-Point Word */
+    case 778:          /* Vector Convert From Unsigned Fixed-Point Word */
+    case 714:          /* Vector Round to Single-Precision Integer toward -Infinity */
+    case 522:          /* Vector Round to Single-Precision Integer Nearest */
+    case 650:          /* Vector Round to Single-Precision Integer toward +Infinity */
+    case 586:          /* Vector Round to Single-Precision Integer toward Zero */
+    case 394:          /* Vector 2 Raised to the Exponent Estimate Floating-Point */
+    case 458:          /* Vector Log Base 2 Estimate Floating-Point */
+    case 266:          /* Vector Reciprocal Estimate Single-Precision */
+    case 330:          /* Vector Reciprocal Square Root Estimate Single-Precision */
+    case 1288:         /* Vector AES Cipher */
+    case 1289:         /* Vector AES Cipher Last */
+    case 1352:         /* Vector AES Inverse Cipher */
+    case 1353:         /* Vector AES Inverse Cipher Last */
+    case 1480:         /* Vector AES SubBytes */
+    case 1730:         /* Vector SHA-512 Sigma Doubleword */
+    case 1666:         /* Vector SHA-256 Sigma Word */
+    case 1032:         /* Vector Polynomial Multiply-Sum Byte */
+    case 1160:         /* Vector Polynomial Multiply-Sum Word */
+    case 1096:         /* Vector Polynomial Multiply-Sum Halfword */
+    case 1224:         /* Vector Polynomial Multiply-Sum Doubleword */
+    case 1292:         /* Vector Gather Bits by Bytes by Doubleword */
+    case 1794:         /* Vector Count Leading Zeros Byte */
+    case 1858:         /* Vector Count Leading Zeros Halfword */
+    case 1922:         /* Vector Count Leading Zeros Word */
+    case 1986:         /* Vector Count Leading Zeros Doubleword */
+    case 1795:         /* Vector Population Count Byte */
+    case 1859:         /* Vector Population Count Halfword */
+    case 1923:         /* Vector Population Count Word */
+    case 1987:         /* Vector Population Count Doubleword */
+    case 1356:         /* Vector Bit Permute Quadword */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_vr0_regnum + PPC_VRT (insn));
+      return 0;
+
+    case 1604:         /* Move To Vector Status and Control Register */
+      record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
+      return 0;
+    case 1540:         /* Move From Vector Status and Control Register */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_vr0_regnum + PPC_VRT (insn));
+      return 0;
+    }
+
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+                     "%08x at %08lx, 4-%d.\n", insn, addr, ext);
+  return -1;
+}
+
+/* Parse instructions of primary opcode-19.  */
+
+static int
+ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
+                          CORE_ADDR addr, uint32_t insn)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int ext = PPC_EXTOP (insn);
+
+  switch (ext)
+    {
+    case 0:            /* Move Condition Register Field */
+    case 33:           /* Condition Register NOR */
+    case 129:          /* Condition Register AND with Complement */
+    case 193:          /* Condition Register XOR */
+    case 225:          /* Condition Register NAND */
+    case 257:          /* Condition Register AND */
+    case 289:          /* Condition Register Equivalent */
+    case 417:          /* Condition Register OR with Complement */
+    case 449:          /* Condition Register OR */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+
+    case 16:           /* Branch Conditional */
+    case 560:          /* Branch Conditional to Branch Target Address Register */
+      if ((PPC_BO (insn) & 0x4) == 0)
+       record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum);
+      /* FALL-THROUGH */
+    case 528:          /* Branch Conditional to Count Register */
+      if (PPC_LK (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
+      return 0;
+
+    case 150:          /* Instruction Synchronize */
+      /* Do nothing.  */
+      return 0;
+    }
+
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+                     "%08x at %08lx, 19-%d.\n", insn, addr, ext);
+  return -1;
+}
+
+/* Parse instructions of primary opcode-31.  */
+
+static int
+ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
+                          CORE_ADDR addr, uint32_t insn)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int ext = PPC_EXTOP (insn);
+  int tmp, nr, nb, i;
+  CORE_ADDR at_dcsz, ea = 0;
+  ULONGEST rb, ra, xer;
+  int size = 0;
+
+  /* These instructions have OE bit.  */
+  switch (ext & 0x1ff)
+    {
+    /* These write RT and XER.  Update CR if RC is set.  */
+    case 8:            /* Subtract from carrying */
+    case 10:           /* Add carrying */
+    case 136:          /* Subtract from extended */
+    case 138:          /* Add extended */
+    case 200:          /* Subtract from zero extended */
+    case 202:          /* Add to zero extended */
+    case 232:          /* Subtract from minus one extended */
+    case 234:          /* Add to minus one extended */
+      /* CA is always altered, but SO/OV are only altered when OE=1.
+        In any case, XER is always altered.  */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+
+    /* These write RT.  Update CR if RC is set and update XER if OE is set.  */
+    case 40:           /* Subtract from */
+    case 104:          /* Negate */
+    case 233:          /* Multiply low doubleword */
+    case 235:          /* Multiply low word */
+    case 266:          /* Add */
+    case 393:          /* Divide Doubleword Extended Unsigned */
+    case 395:          /* Divide Word Extended Unsigned */
+    case 425:          /* Divide Doubleword Extended */
+    case 427:          /* Divide Word Extended */
+    case 457:          /* Divide Doubleword Unsigned */
+    case 459:          /* Divide Word Unsigned */
+    case 489:          /* Divide Doubleword */
+    case 491:          /* Divide Word */
+      if (PPC_OE (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      /* FALL-THROUGH */
+    case 9:            /* Multiply High Doubleword Unsigned */
+    case 11:           /* Multiply High Word Unsigned */
+    case 73:           /* Multiply High Doubleword */
+    case 75:           /* Multiply High Word */
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+    }
+
+  if ((ext & 0x1f) == 15)
+    {
+      /* Integer Select. bit[16:20] is used for BC.  */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+    }
+
+  switch (ext)
+    {
+    case 78:           /* Determine Leftmost Zero Byte */
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+
+    /* These only write RT.  */
+    case 19:           /* Move from condition register */
+                       /* Move From One Condition Register Field */
+    case 74:           /* Add and Generate Sixes */
+    case 74 | 0x200:   /* Add and Generate Sixes (bit-21 dont-care) */
+    case 302:          /* Move From Branch History Rolling Buffer */
+    case 339:          /* Move From Special Purpose Register */
+    case 371:          /* Move From Time Base [Phased-Out]  */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+
+    /* These only write to RA.  */
+    case 51:           /* Move From VSR Doubleword */
+    case 115:          /* Move From VSR Word and Zero */
+    case 122:          /* Population count bytes */
+    case 378:          /* Population count words */
+    case 506:          /* Population count doublewords */
+    case 154:          /* Parity Word */
+    case 186:          /* Parity Doubleword */
+    case 252:          /* Bit Permute Doubleword */
+    case 282:          /* Convert Declets To Binary Coded Decimal */
+    case 314:          /* Convert Binary Coded Decimal To Declets */
+    case 508:          /* Compare bytes */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RA (insn));
+      return 0;
+
+    /* These write CR and optional RA.  */
+    case 792:          /* Shift Right Algebraic Word */
+    case 794:          /* Shift Right Algebraic Doubleword */
+    case 824:          /* Shift Right Algebraic Word Immediate */
+    case 826:          /* Shift Right Algebraic Doubleword Immediate (413) */
+    case 826 | 1:      /* Shift Right Algebraic Doubleword Immediate (413) */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RA (insn));
+      /* FALL-THROUGH */
+    case 0:            /* Compare */
+    case 32:           /* Compare logical */
+    case 144:          /* Move To Condition Register Fields */
+                       /* Move To One Condition Register Field */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+
+    /* These write to RT.  Update RA if 'update indexed.'  */
+    case 53:           /* Load Doubleword with Update Indexed */
+    case 119:          /* Load Byte and Zero with Update Indexed */
+    case 311:          /* Load Halfword and Zero with Update Indexed */
+    case 55:           /* Load Word and Zero with Update Indexed */
+    case 375:          /* Load Halfword Algebraic with Update Indexed */
+    case 373:          /* Load Word Algebraic with Update Indexed */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RA (insn));
+      /* FALL-THROUGH */
+    case 21:           /* Load Doubleword Indexed */
+    case 52:           /* Load Byte And Reserve Indexed */
+    case 116:          /* Load Halfword And Reserve Indexed */
+    case 20:           /* Load Word And Reserve Indexed */
+    case 84:           /* Load Doubleword And Reserve Indexed */
+    case 87:           /* Load Byte and Zero Indexed */
+    case 279:          /* Load Halfword and Zero Indexed */
+    case 23:           /* Load Word and Zero Indexed */
+    case 343:          /* Load Halfword Algebraic Indexed */
+    case 341:          /* Load Word Algebraic Indexed */
+    case 790:          /* Load Halfword Byte-Reverse Indexed */
+    case 534:          /* Load Word Byte-Reverse Indexed */
+    case 532:          /* Load Doubleword Byte-Reverse Indexed */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+
+    case 597:          /* Load String Word Immediate */
+    case 533:          /* Load String Word Indexed */
+      if (ext == 597)
+       {
+       nr = PPC_NB (insn);
+       if (nr == 0)
+         nr = 32;
+       }
+      else
+       {
+         regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &xer);
+         nr = PPC_XER_NB (xer);
+       }
+
+      nr = (nr + 3) >> 2;
+
+      /* If n=0, the contents of register RT are undefined.  */
+      if (nr == 0)
+       nr = 1;
+
+      for (i = 0; i < nr; i++)
+       record_full_arch_list_add_reg (regcache,
+                                      tdep->ppc_gp0_regnum
+                                      + ((PPC_RT (insn) + i) & 0x1f));
+      return 0;
+
+    case 276:          /* Load Quadword And Reserve Indexed */
+      tmp = tdep->ppc_gp0_regnum + (PPC_RT (insn) & ~1);
+      record_full_arch_list_add_reg (regcache, tmp);
+      record_full_arch_list_add_reg (regcache, tmp + 1);
+      return 0;
+
+    /* These write VRT.  */
+    case 6:            /* Load Vector for Shift Left Indexed */
+    case 38:           /* Load Vector for Shift Right Indexed */
+    case 7:            /* Load Vector Element Byte Indexed */
+    case 39:           /* Load Vector Element Halfword Indexed */
+    case 71:           /* Load Vector Element Word Indexed */
+    case 103:          /* Load Vector Indexed */
+    case 359:          /* Load Vector Indexed LRU */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_vr0_regnum + PPC_VRT (insn));
+      return 0;
+
+    /* These write FRT.  Update RA if 'update indexed.'  */
+    case 567:          /* Load Floating-Point Single with Update Indexed */
+    case 631:          /* Load Floating-Point Double with Update Indexed */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RA (insn));
+      /* FALL-THROUGH */
+    case 535:          /* Load Floating-Point Single Indexed */
+    case 599:          /* Load Floating-Point Double Indexed */
+    case 855:          /* Load Floating-Point as Integer Word Algebraic Indexed */
+    case 887:          /* Load Floating-Point as Integer Word and Zero Indexed */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      return 0;
+
+    case 791:          /* Load Floating-Point Double Pair Indexed */
+      tmp = tdep->ppc_fp0_regnum + (PPC_FRT (insn) & ~1);
+      record_full_arch_list_add_reg (regcache, tmp);
+      record_full_arch_list_add_reg (regcache, tmp + 1);
+      return 0;
+
+    case 179:          /* Move To VSR Doubleword */
+    case 211:          /* Move To VSR Word Algebraic */
+    case 243:          /* Move To VSR Word and Zero */
+    case 588:          /* Load VSX Scalar Doubleword Indexed */
+    case 524:          /* Load VSX Scalar Single-Precision Indexed */
+    case 76:           /* Load VSX Scalar as Integer Word Algebraic Indexed */
+    case 12:           /* Load VSX Scalar as Integer Word and Zero Indexed */
+    case 844:          /* Load VSX Vector Doubleword*2 Indexed */
+    case 332:          /* Load VSX Vector Doubleword & Splat Indexed */
+    case 780:          /* Load VSX Vector Word*4 Indexed */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
+
+    /* These write RA.  Update CR if RC is set.  */
+    case 24:           /* Shift Left Word */
+    case 26:           /* Count Leading Zeros Word */
+    case 27:           /* Shift Left Doubleword */
+    case 28:           /* AND */
+    case 58:           /* Count Leading Zeros Doubleword */
+    case 60:           /* AND with Complement */
+    case 124:          /* NOR */
+    case 284:          /* Equivalent */
+    case 316:          /* XOR */
+    case 476:          /* NAND */
+    case 412:          /* OR with Complement */
+    case 444:          /* OR */
+    case 536:          /* Shift Right Word */
+    case 539:          /* Shift Right Doubleword */
+    case 922:          /* Extend Sign Halfword */
+    case 954:          /* Extend Sign Byte */
+    case 986:          /* Extend Sign Word */
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RA (insn));
+      return 0;
+
+    /* Store memory.  */
+    case 181:          /* Store Doubleword with Update Indexed */
+    case 183:          /* Store Word with Update Indexed */
+    case 247:          /* Store Byte with Update Indexed */
+    case 439:          /* Store Half Word with Update Indexed */
+    case 695:          /* Store Floating-Point Single with Update Indexed */
+    case 759:          /* Store Floating-Point Double with Update Indexed */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RA (insn));
+      /* FALL-THROUGH */
+    case 135:          /* Store Vector Element Byte Indexed */
+    case 167:          /* Store Vector Element Halfword Indexed */
+    case 199:          /* Store Vector Element Word Indexed */
+    case 231:          /* Store Vector Indexed */
+    case 487:          /* Store Vector Indexed LRU */
+    case 716:          /* Store VSX Scalar Doubleword Indexed */
+    case 140:          /* Store VSX Scalar as Integer Word Indexed */
+    case 652:          /* Store VSX Scalar Single-Precision Indexed */
+    case 972:          /* Store VSX Vector Doubleword*2 Indexed */
+    case 908:          /* Store VSX Vector Word*4 Indexed */
+    case 149:          /* Store Doubleword Indexed */
+    case 151:          /* Store Word Indexed */
+    case 215:          /* Store Byte Indexed */
+    case 407:          /* Store Half Word Indexed */
+    case 694:          /* Store Byte Conditional Indexed */
+    case 726:          /* Store Halfword Conditional Indexed */
+    case 150:          /* Store Word Conditional Indexed */
+    case 214:          /* Store Doubleword Conditional Indexed */
+    case 182:          /* Store Quadword Conditional Indexed */
+    case 662:          /* Store Word Byte-Reverse Indexed */
+    case 918:          /* Store Halfword Byte-Reverse Indexed */
+    case 660:          /* Store Doubleword Byte-Reverse Indexed */
+    case 663:          /* Store Floating-Point Single Indexed */
+    case 727:          /* Store Floating-Point Double Indexed */
+    case 919:          /* Store Floating-Point Double Pair Indexed */
+    case 983:          /* Store Floating-Point as Integer Word Indexed */
+      if (ext == 694 || ext == 726 || ext == 150 || ext == 214 || ext == 182)
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+
+      ra = 0;
+      if (PPC_RA (insn) != 0)
+       regcache_raw_read_unsigned (regcache,
+                                   tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
+      regcache_raw_read_unsigned (regcache,
+                                 tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
+      ea = ra + rb;
+
+      switch (ext)
+       {
+       case 183:       /* Store Word with Update Indexed */
+       case 199:       /* Store Vector Element Word Indexed */
+       case 140:       /* Store VSX Scalar as Integer Word Indexed */
+       case 652:       /* Store VSX Scalar Single-Precision Indexed */
+       case 151:       /* Store Word Indexed */
+       case 150:       /* Store Word Conditional Indexed */
+       case 662:       /* Store Word Byte-Reverse Indexed */
+       case 663:       /* Store Floating-Point Single Indexed */
+       case 695:       /* Store Floating-Point Single with Update Indexed */
+       case 983:       /* Store Floating-Point as Integer Word Indexed */
+         size = 4;
+         break;
+       case 247:       /* Store Byte with Update Indexed */
+       case 135:       /* Store Vector Element Byte Indexed */
+       case 215:       /* Store Byte Indexed */
+       case 694:       /* Store Byte Conditional Indexed */
+         size = 1;
+         break;
+       case 439:       /* Store Halfword with Update Indexed */
+       case 167:       /* Store Vector Element Halfword Indexed */
+       case 407:       /* Store Halfword Indexed */
+       case 726:       /* Store Halfword Conditional Indexed */
+       case 918:       /* Store Halfword Byte-Reverse Indexed */
+         size = 2;
+         break;
+       case 181:       /* Store Doubleword with Update Indexed */
+       case 716:       /* Store VSX Scalar Doubleword Indexed */
+       case 149:       /* Store Doubleword Indexed */
+       case 214:       /* Store Doubleword Conditional Indexed */
+       case 660:       /* Store Doubleword Byte-Reverse Indexed */
+       case 727:       /* Store Floating-Point Double Indexed */
+       case 759:       /* Store Floating-Point Double with Update Indexed */
+         size = 8;
+         break;
+       case 972:       /* Store VSX Vector Doubleword*2 Indexed */
+       case 908:       /* Store VSX Vector Word*4 Indexed */
+       case 182:       /* Store Quadword Conditional Indexed */
+       case 231:       /* Store Vector Indexed */
+       case 487:       /* Store Vector Indexed LRU */
+       case 919:       /* Store Floating-Point Double Pair Indexed */
+         size = 16;
+         break;
+       default:
+         gdb_assert (0);
+       }
+
+      /* Align address for Store Vector instructions.  */
+      switch (ext)
+       {
+       case 167:       /* Store Vector Element Halfword Indexed */
+         addr = addr & ~0x1ULL;
+         break;
+
+       case 199:       /* Store Vector Element Word Indexed */
+         addr = addr & ~0x3ULL;
+         break;
+
+       case 231:       /* Store Vector Indexed */
+       case 487:       /* Store Vector Indexed LRU */
+         addr = addr & ~0xfULL;
+         break;
+       }
+
+      record_full_arch_list_add_mem (addr, size);
+      return 0;
+
+    case 725:          /* Store String Word Immediate */
+      ra = 0;
+      if (PPC_RA (insn) != 0)
+       regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &ra);
+      ea += ra;
+
+      nb = PPC_NB (insn);
+      if (nb == 0)
+       nb = 32;
+
+      record_full_arch_list_add_mem (ea, nb);
+
+      return 0;
+
+    case 661:          /* Store String Word Indexed */
+      ra = 0;
+      if (PPC_RA (insn) != 0)
+       regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &ra);
+      ea += ra;
+
+      regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &xer);
+      nb = PPC_XER_NB (xer);
+
+      if (nb != 0)
+       {
+         regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &rb);
+         ea += rb;
+         record_full_arch_list_add_mem (ea, nb);
+       }
+
+      return 0;
+
+    case 467:          /* Move To Special Purpose Register */
+      switch (PPC_SPR (insn))
+       {
+       case 1:                 /* XER */
+         record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+         return 0;
+       case 8:                 /* LR */
+         record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
+         return 0;
+       case 9:                 /* CTR */
+         record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum);
+         return 0;
+       case 256:               /* VRSAVE */
+         record_full_arch_list_add_reg (regcache, tdep->ppc_vrsave_regnum);
+         return 0;
+       }
+
+      goto UNKNOWN_OP;
+
+    case 147:          /* Move To Split Little Endian */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_ps_regnum);
+      return 0;
+
+    case 512:          /* Move to Condition Register from XER */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      return 0;
+
+    case 4:            /* Trap Word */
+    case 68:           /* Trap Doubleword */
+    case 430:          /* Clear BHRB */
+    case 598:          /* Synchronize */
+    case 62:           /* Wait for Interrupt */
+    case 22:           /* Instruction Cache Block Touch */
+    case 854:          /* Enforce In-order Execution of I/O */
+    case 246:          /* Data Cache Block Touch for Store */
+    case 54:           /* Data Cache Block Store */
+    case 86:           /* Data Cache Block Flush */
+    case 278:          /* Data Cache Block Touch */
+    case 758:          /* Data Cache Block Allocate */
+    case 982:          /* Instruction Cache Block Invalidate */
+      return 0;
+
+    case 654:          /* Transaction Begin */
+    case 686:          /* Transaction End */
+    case 718:          /* Transaction Check */
+    case 750:          /* Transaction Suspend or Resume */
+    case 782:          /* Transaction Abort Word Conditional */
+    case 814:          /* Transaction Abort Doubleword Conditional */
+    case 846:          /* Transaction Abort Word Conditional Immediate */
+    case 878:          /* Transaction Abort Doubleword Conditional Immediate */
+    case 910:          /* Transaction Abort */
+      fprintf_unfiltered (gdb_stdlog, "Cannot record Transaction instructions. "
+                         "%08x at %08lx, 31-%d.\n", insn, addr, ext);
+      return -1;
+
+    case 1014:         /* Data Cache Block set to Zero */
+      if (target_auxv_search (&current_target, AT_DCACHEBSIZE, &at_dcsz) <= 0
+         || at_dcsz == 0)
+       at_dcsz = 128; /* Assume 128-byte cache line size (POWER8)  */
+
+      if (PPC_RA (insn) != 0)
+       regcache_raw_read_unsigned (regcache,
+                                   tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
+      regcache_raw_read_unsigned (regcache,
+                                 tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
+      ea = (ra + rb) & ~((ULONGEST) (at_dcsz - 1));
+      record_full_arch_list_add_mem (ea, at_dcsz);
+      return 0;
+    }
+
+UNKNOWN_OP:
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+                     "%08x at %08lx, 31-%d.\n", insn, addr, ext);
+  return -1;
+}
+
+/* Parse instructions of primary opcode-59.  */
+
+static int
+ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
+                          CORE_ADDR addr, uint32_t insn)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int ext = PPC_EXTOP (insn);
+
+  switch (ext & 0x1f)
+    {
+    case 18:           /* Floating Divide */
+    case 20:           /* Floating Subtract */
+    case 21:           /* Floating Add */
+    case 22:           /* Floating Square Root */
+    case 24:           /* Floating Reciprocal Estimate */
+    case 25:           /* Floating Multiply */
+    case 26:           /* Floating Reciprocal Square Root Estimate */
+    case 28:           /* Floating Multiply-Subtract */
+    case 29:           /* Floating Multiply-Add */
+    case 30:           /* Floating Negative Multiply-Subtract */
+    case 31:           /* Floating Negative Multiply-Add */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+
+      return 0;
+    }
+
+  switch (ext)
+    {
+    case 2:            /* DFP Add */
+    case 3:            /* DFP Quantize */
+    case 34:           /* DFP Multiply */
+    case 35:           /* DFP Reround */
+    case 67:           /* DFP Quantize Immediate */
+    case 99:           /* DFP Round To FP Integer With Inexact */
+    case 227:          /* DFP Round To FP Integer Without Inexact */
+    case 258:          /* DFP Convert To DFP Long! */
+    case 290:          /* DFP Convert To Fixed */
+    case 514:          /* DFP Subtract */
+    case 546:          /* DFP Divide */
+    case 770:          /* DFP Round To DFP Short! */
+    case 802:          /* DFP Convert From Fixed */
+    case 834:          /* DFP Encode BCD To DPD */
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      return 0;
+
+    case 130:          /* DFP Compare Ordered */
+    case 162:          /* DFP Test Exponent */
+    case 194:          /* DFP Test Data Class */
+    case 226:          /* DFP Test Data Group */
+    case 642:          /* DFP Compare Unordered */
+    case 674:          /* DFP Test Significance */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      return 0;
+
+    case 66:           /* DFP Shift Significand Left Immediate */
+    case 98:           /* DFP Shift Significand Right Immediate */
+    case 322:          /* DFP Decode DPD To BCD */
+    case 354:          /* DFP Extract Biased Exponent */
+    case 866:          /* DFP Insert Biased Exponent */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+
+    case 846:          /* Floating Convert From Integer Doubleword Single */
+    case 974:          /* Floating Convert From Integer Doubleword Unsigned
+                          Single */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+
+      return 0;
+    }
+
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+                     "%08x at %08lx, 59-%d.\n", insn, addr, ext);
+  return -1;
+}
+
+/* Parse instructions of primary opcode-60.  */
+
+static int
+ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
+                          CORE_ADDR addr, uint32_t insn)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int ext = PPC_EXTOP (insn);
+  int tmp;
+
+  switch (ext >> 2)
+    {
+    case 0:            /* VSX Scalar Add Single-Precision */
+    case 32:           /* VSX Scalar Add Double-Precision */
+    case 24:           /* VSX Scalar Divide Single-Precision */
+    case 56:           /* VSX Scalar Divide Double-Precision */
+    case 176:          /* VSX Scalar Copy Sign Double-Precision */
+    case 33:           /* VSX Scalar Multiply-Add Double-Precision */
+    case 41:           /* ditto */
+    case 1:            /* VSX Scalar Multiply-Add Single-Precision */
+    case 9:            /* ditto */
+    case 160:          /* VSX Scalar Maximum Double-Precision */
+    case 168:          /* VSX Scalar Minimum Double-Precision */
+    case 49:           /* VSX Scalar Multiply-Subtract Double-Precision */
+    case 57:           /* ditto */
+    case 17:           /* VSX Scalar Multiply-Subtract Single-Precision */
+    case 25:           /* ditto */
+    case 48:           /* VSX Scalar Multiply Double-Precision */
+    case 16:           /* VSX Scalar Multiply Single-Precision */
+    case 161:          /* VSX Scalar Negative Multiply-Add Double-Precision */
+    case 169:          /* ditto */
+    case 129:          /* VSX Scalar Negative Multiply-Add Single-Precision */
+    case 137:          /* ditto */
+    case 177:          /* VSX Scalar Negative Multiply-Subtract Double-Precision */
+    case 185:          /* ditto */
+    case 145:          /* VSX Scalar Negative Multiply-Subtract Single-Precision */
+    case 153:          /* ditto */
+    case 40:           /* VSX Scalar Subtract Double-Precision */
+    case 8:            /* VSX Scalar Subtract Single-Precision */
+    case 96:           /* VSX Vector Add Double-Precision */
+    case 64:           /* VSX Vector Add Single-Precision */
+    case 120:          /* VSX Vector Divide Double-Precision */
+    case 88:           /* VSX Vector Divide Single-Precision */
+    case 97:           /* VSX Vector Multiply-Add Double-Precision */
+    case 105:          /* ditto */
+    case 65:           /* VSX Vector Multiply-Add Single-Precision */
+    case 73:           /* ditto */
+    case 224:          /* VSX Vector Maximum Double-Precision */
+    case 192:          /* VSX Vector Maximum Single-Precision */
+    case 232:          /* VSX Vector Minimum Double-Precision */
+    case 200:          /* VSX Vector Minimum Single-Precision */
+    case 113:          /* VSX Vector Multiply-Subtract Double-Precision */
+    case 121:          /* ditto */
+    case 81:           /* VSX Vector Multiply-Subtract Single-Precision */
+    case 89:           /* ditto */
+    case 112:          /* VSX Vector Multiply Double-Precision */
+    case 80:           /* VSX Vector Multiply Single-Precision */
+    case 225:          /* VSX Vector Negative Multiply-Add Double-Precision */
+    case 233:          /* ditto */
+    case 193:          /* VSX Vector Negative Multiply-Add Single-Precision */
+    case 201:          /* ditto */
+    case 241:          /* VSX Vector Negative Multiply-Subtract Double-Precision */
+    case 249:          /* ditto */
+    case 209:          /* VSX Vector Negative Multiply-Subtract Single-Precision */
+    case 217:          /* ditto */
+    case 104:          /* VSX Vector Subtract Double-Precision */
+    case 72:           /* VSX Vector Subtract Single-Precision */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+    case 240:          /* VSX Vector Copy Sign Double-Precision */
+    case 208:          /* VSX Vector Copy Sign Single-Precision */
+    case 130:          /* VSX Logical AND */
+    case 138:          /* VSX Logical AND with Complement */
+    case 186:          /* VSX Logical Equivalence */
+    case 178:          /* VSX Logical NAND */
+    case 170:          /* VSX Logical OR with Complement */
+    case 162:          /* VSX Logical NOR */
+    case 146:          /* VSX Logical OR */
+    case 154:          /* VSX Logical XOR */
+    case 18:           /* VSX Merge High Word */
+    case 50:           /* VSX Merge Low Word */
+    case 10:           /* VSX Permute Doubleword Immediate (DM=0) */
+    case 10 | 0x20:    /* VSX Permute Doubleword Immediate (DM=1) */
+    case 10 | 0x40:    /* VSX Permute Doubleword Immediate (DM=2) */
+    case 10 | 0x60:    /* VSX Permute Doubleword Immediate (DM=3) */
+    case 2:            /* VSX Shift Left Double by Word Immediate (SHW=0) */
+    case 2 | 0x20:     /* VSX Shift Left Double by Word Immediate (SHW=1) */
+    case 2 | 0x40:     /* VSX Shift Left Double by Word Immediate (SHW=2) */
+    case 2 | 0x60:     /* VSX Shift Left Double by Word Immediate (SHW=3) */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
+
+    case 61:           /* VSX Scalar Test for software Divide Double-Precision */
+    case 125:          /* VSX Vector Test for software Divide Double-Precision */
+    case 93:           /* VSX Vector Test for software Divide Single-Precision */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+
+    case 35:           /* VSX Scalar Compare Unordered Double-Precision */
+    case 43:           /* VSX Scalar Compare Ordered Double-Precision */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      return 0;
+    }
+
+  switch ((ext >> 2) & 0x7f) /* Mask out Rc-bit.  */
+    {
+    case 99:           /* VSX Vector Compare Equal To Double-Precision */
+    case 67:           /* VSX Vector Compare Equal To Single-Precision */
+    case 115:          /* VSX Vector Compare Greater Than or
+                          Equal To Double-Precision */
+    case 83:           /* VSX Vector Compare Greater Than or
+                          Equal To Single-Precision */
+    case 107:          /* VSX Vector Compare Greater Than Double-Precision */
+    case 75:           /* VSX Vector Compare Greater Than Single-Precision */
+      if (PPC_Rc (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
+    }
+
+  switch (ext >> 1)
+    {
+    case 265:          /* VSX Scalar round Double-Precision to
+                          Single-Precision and Convert to
+                          Single-Precision format */
+    case 344:          /* VSX Scalar truncate Double-Precision to
+                          Integer and Convert to Signed Integer
+                          Doubleword format with Saturate */
+    case 88:           /* VSX Scalar truncate Double-Precision to
+                          Integer and Convert to Signed Integer Word
+                          Format with Saturate */
+    case 328:          /* VSX Scalar truncate Double-Precision integer
+                          and Convert to Unsigned Integer Doubleword
+                          Format with Saturate */
+    case 72:           /* VSX Scalar truncate Double-Precision to
+                          Integer and Convert to Unsigned Integer Word
+                          Format with Saturate */
+    case 329:          /* VSX Scalar Convert Single-Precision to
+                          Double-Precision format */
+    case 376:          /* VSX Scalar Convert Signed Integer
+                          Doubleword to floating-point format and
+                          Round to Double-Precision format */
+    case 312:          /* VSX Scalar Convert Signed Integer
+                          Doubleword to floating-point format and
+                          round to Single-Precision */
+    case 360:          /* VSX Scalar Convert Unsigned Integer
+                          Doubleword to floating-point format and
+                          Round to Double-Precision format */
+    case 296:          /* VSX Scalar Convert Unsigned Integer
+                          Doubleword to floating-point format and
+                          Round to Single-Precision */
+    case 73:           /* VSX Scalar Round to Double-Precision Integer
+                          Using Round to Nearest Away */
+    case 107:          /* VSX Scalar Round to Double-Precision Integer
+                          Exact using Current rounding mode */
+    case 121:          /* VSX Scalar Round to Double-Precision Integer
+                          Using Round toward -Infinity */
+    case 105:          /* VSX Scalar Round to Double-Precision Integer
+                          Using Round toward +Infinity */
+    case 89:           /* VSX Scalar Round to Double-Precision Integer
+                          Using Round toward Zero */
+    case 90:           /* VSX Scalar Reciprocal Estimate Double-Precision */
+    case 26:           /* VSX Scalar Reciprocal Estimate Single-Precision */
+    case 281:          /* VSX Scalar Round to Single-Precision */
+    case 74:           /* VSX Scalar Reciprocal Square Root Estimate
+                          Double-Precision */
+    case 10:           /* VSX Scalar Reciprocal Square Root Estimate
+                          Single-Precision */
+    case 75:           /* VSX Scalar Square Root Double-Precision */
+    case 11:           /* VSX Scalar Square Root Single-Precision */
+    case 393:          /* VSX Vector round Double-Precision to
+                          Single-Precision and Convert to
+                          Single-Precision format */
+    case 472:          /* VSX Vector truncate Double-Precision to
+                          Integer and Convert to Signed Integer
+                          Doubleword format with Saturate */
+    case 216:          /* VSX Vector truncate Double-Precision to
+                          Integer and Convert to Signed Integer Word
+                          Format with Saturate */
+    case 456:          /* VSX Vector truncate Double-Precision to
+                          Integer and Convert to Unsigned Integer
+                          Doubleword format with Saturate */
+    case 200:          /* VSX Vector truncate Double-Precision to
+                          Integer and Convert to Unsigned Integer Word
+                          Format with Saturate */
+    case 457:          /* VSX Vector Convert Single-Precision to
+                          Double-Precision format */
+    case 408:          /* VSX Vector truncate Single-Precision to
+                          Integer and Convert to Signed Integer
+                          Doubleword format with Saturate */
+    case 152:          /* VSX Vector truncate Single-Precision to
+                          Integer and Convert to Signed Integer Word
+                          Format with Saturate */
+    case 392:          /* VSX Vector truncate Single-Precision to
+                          Integer and Convert to Unsigned Integer
+                          Doubleword format with Saturate */
+    case 136:          /* VSX Vector truncate Single-Precision to
+                          Integer and Convert to Unsigned Integer Word
+                          Format with Saturate */
+    case 504:          /* VSX Vector Convert and round Signed Integer
+                          Doubleword to Double-Precision format */
+    case 440:          /* VSX Vector Convert and round Signed Integer
+                          Doubleword to Single-Precision format */
+    case 248:          /* VSX Vector Convert Signed Integer Word to
+                          Double-Precision format */
+    case 184:          /* VSX Vector Convert and round Signed Integer
+                          Word to Single-Precision format */
+    case 488:          /* VSX Vector Convert and round Unsigned
+                          Integer Doubleword to Double-Precision format */
+    case 424:          /* VSX Vector Convert and round Unsigned
+                          Integer Doubleword to Single-Precision format */
+    case 232:          /* VSX Vector Convert and round Unsigned
+                          Integer Word to Double-Precision format */
+    case 168:          /* VSX Vector Convert and round Unsigned
+                          Integer Word to Single-Precision format */
+    case 201:          /* VSX Vector Round to Double-Precision
+                          Integer using round to Nearest Away */
+    case 235:          /* VSX Vector Round to Double-Precision
+                          Integer Exact using Current rounding mode */
+    case 249:          /* VSX Vector Round to Double-Precision
+                          Integer using round toward -Infinity */
+    case 233:          /* VSX Vector Round to Double-Precision
+                          Integer using round toward +Infinity */
+    case 217:          /* VSX Vector Round to Double-Precision
+                          Integer using round toward Zero */
+    case 218:          /* VSX Vector Reciprocal Estimate Double-Precision */
+    case 154:          /* VSX Vector Reciprocal Estimate Single-Precision */
+    case 137:          /* VSX Vector Round to Single-Precision Integer
+                          Using Round to Nearest Away */
+    case 171:          /* VSX Vector Round to Single-Precision Integer
+                          Exact Using Current rounding mode */
+    case 185:          /* VSX Vector Round to Single-Precision Integer
+                          Using Round toward -Infinity */
+    case 169:          /* VSX Vector Round to Single-Precision Integer
+                          Using Round toward +Infinity */
+    case 153:          /* VSX Vector Round to Single-Precision Integer
+                          Using round toward Zero */
+    case 202:          /* VSX Vector Reciprocal Square Root Estimate
+                          Double-Precision */
+    case 138:          /* VSX Vector Reciprocal Square Root Estimate
+                          Single-Precision */
+    case 203:          /* VSX Vector Square Root Double-Precision */
+    case 139:          /* VSX Vector Square Root Single-Precision */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+    case 345:          /* VSX Scalar Absolute Value Double-Precision */
+    case 267:          /* VSX Scalar Convert Scalar Single-Precision to
+                          Vector Single-Precision format Non-signalling */
+    case 331:          /* VSX Scalar Convert Single-Precision to
+                          Double-Precision format Non-signalling */
+    case 361:          /* VSX Scalar Negative Absolute Value Double-Precision */
+    case 377:          /* VSX Scalar Negate Double-Precision */
+    case 473:          /* VSX Vector Absolute Value Double-Precision */
+    case 409:          /* VSX Vector Absolute Value Single-Precision */
+    case 489:          /* VSX Vector Negative Absolute Value Double-Precision */
+    case 425:          /* VSX Vector Negative Absolute Value Single-Precision */
+    case 505:          /* VSX Vector Negate Double-Precision */
+    case 441:          /* VSX Vector Negate Single-Precision */
+    case 164:          /* VSX Splat Word */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
+
+    case 106:          /* VSX Scalar Test for software Square Root
+                          Double-Precision */
+    case 234:          /* VSX Vector Test for software Square Root
+                          Double-Precision */
+    case 170:          /* VSX Vector Test for software Square Root
+                          Single-Precision */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+    }
+
+  if (((ext >> 3) & 0x3) == 3) /* VSX Select */
+    {
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
+    }
+
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+                     "%08x at %08lx, 60-%d.\n", insn, addr, ext);
+  return -1;
+}
+
+/* Parse instructions of primary opcode-63.  */
+
+static int
+ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
+                          CORE_ADDR addr, uint32_t insn)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int ext = PPC_EXTOP (insn);
+  int tmp;
+
+  switch (ext & 0x1f)
+    {
+    case 18:           /* Floating Divide */
+    case 20:           /* Floating Subtract */
+    case 21:           /* Floating Add */
+    case 22:           /* Floating Square Root */
+    case 24:           /* Floating Reciprocal Estimate */
+    case 25:           /* Floating Multiply */
+    case 26:           /* Floating Reciprocal Square Root Estimate */
+    case 28:           /* Floating Multiply-Subtract */
+    case 29:           /* Floating Multiply-Add */
+    case 30:           /* Floating Negative Multiply-Subtract */
+    case 31:           /* Floating Negative Multiply-Add */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      return 0;
+
+    case 23:           /* Floating Select */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+    }
+
+  switch (ext)
+    {
+    case 2:            /* DFP Add Quad */
+    case 3:            /* DFP Quantize Quad */
+    case 34:           /* DFP Multiply Quad */
+    case 35:           /* DFP Reround Quad */
+    case 67:           /* DFP Quantize Immediate Quad */
+    case 99:           /* DFP Round To FP Integer With Inexact Quad */
+    case 227:          /* DFP Round To FP Integer Without Inexact Quad */
+    case 258:          /* DFP Convert To DFP Extended Quad */
+    case 514:          /* DFP Subtract Quad */
+    case 546:          /* DFP Divide Quad */
+    case 770:          /* DFP Round To DFP Long Quad */
+    case 802:          /* DFP Convert From Fixed Quad */
+    case 834:          /* DFP Encode BCD To DPD Quad */
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      tmp = tdep->ppc_fp0_regnum + (PPC_FRT (insn) & ~1);
+      record_full_arch_list_add_reg (regcache, tmp);
+      record_full_arch_list_add_reg (regcache, tmp + 1);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      return 0;
+
+    case 130:          /* DFP Compare Ordered Quad */
+    case 162:          /* DFP Test Exponent Quad */
+    case 194:          /* DFP Test Data Class Quad */
+    case 226:          /* DFP Test Data Group Quad */
+    case 642:          /* DFP Compare Unordered Quad */
+    case 674:          /* DFP Test Significance Quad */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      return 0;
+
+    case 66:           /* DFP Shift Significand Left Immediate Quad */
+    case 98:           /* DFP Shift Significand Right Immediate Quad */
+    case 322:          /* DFP Decode DPD To BCD Quad */
+    case 866:          /* DFP Insert Biased Exponent Quad */
+      tmp = tdep->ppc_fp0_regnum + (PPC_FRT (insn) & ~1);
+      record_full_arch_list_add_reg (regcache, tmp);
+      record_full_arch_list_add_reg (regcache, tmp + 1);
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+
+    case 290:          /* DFP Convert To Fixed Quad */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      break;
+
+    case 354:          /* DFP Extract Biased Exponent Quad */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+
+    case 12:           /* Floating Round to Single-Precision */
+    case 14:           /* Floating Convert To Integer Word */
+    case 15:           /* Floating Convert To Integer Word
+                          with round toward Zero */
+    case 142:          /* Floating Convert To Integer Word Unsigned */
+    case 143:          /* Floating Convert To Integer Word Unsigned
+                          with round toward Zero */
+    case 392:          /* Floating Round to Integer Nearest */
+    case 424:          /* Floating Round to Integer Toward Zero */
+    case 456:          /* Floating Round to Integer Plus */
+    case 488:          /* Floating Round to Integer Minus */
+    case 814:          /* Floating Convert To Integer Doubleword */
+    case 815:          /* Floating Convert To Integer Doubleword
+                          with round toward Zero */
+    case 846:          /* Floating Convert From Integer Doubleword */
+    case 942:          /* Floating Convert To Integer Doubleword Unsigned */
+    case 943:          /* Floating Convert To Integer Doubleword Unsigned
+                          with round toward Zero */
+    case 974:          /* Floating Convert From Integer Doubleword Unsigned */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      return 0;
+
+    case 583:          /* Move From FPSCR */
+    case 8:            /* Floating Copy Sign */
+    case 40:           /* Floating Negate */
+    case 72:           /* Floating Move Register */
+    case 136:          /* Floating Negative Absolute Value */
+    case 264:          /* Floating Absolute Value */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+
+    case 838:          /* Floating Merge Odd Word */
+    case 966:          /* Floating Merge Even Word */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      return 0;
+
+    case 38:           /* Move To FPSCR Bit 1 */
+    case 70:           /* Move To FPSCR Bit 0 */
+    case 134:          /* Move To FPSCR Field Immediate */
+    case 711:          /* Move To FPSCR Fields */
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      break;
+
+    case 0:            /* Floating Compare Unordered */
+    case 32:           /* Floating Compare Ordered */
+    case 64:           /* Move to Condition Register from FPSCR */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
+    case 128:          /* Floating Test for software Divide */
+    case 160:          /* Floating Test for software Square Root */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+
+    }
+
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+                     "%08x at %08lx, 59-%d.\n", insn, addr, ext);
+  return -1;
+}
+
+/* Parse the current instruction and record the values of the registers and
+   memory that will be changed in current instruction to "record_arch_list".
+   Return -1 if something wrong.  */
+
+int
+ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
+                     CORE_ADDR addr)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  uint32_t insn;
+  int op6, tmp, i;
+
+  insn = read_memory_unsigned_integer (addr, 4, byte_order);
+  op6 = PPC_OP6 (insn);
+
+  switch (op6)
+    {
+    case 2:            /* Trap Doubleword Immediate */
+    case 3:            /* Trap Word Immediate */
+      /* Do nothing.  */
+      break;
+
+    case 4:
+      if (ppc_process_record_op4 (gdbarch, regcache, addr, insn) != 0)
+       return -1;
+      break;
+
+    case 17:           /* System call */
+      if (PPC_LEV (insn) != 0)
+       goto UNKNOWN_OP;
+
+      if (tdep->ppc_syscall_record != NULL)
+       {
+         if (tdep->ppc_syscall_record (regcache) != 0)
+           return -1;
+       }
+      else
+       {
+         printf_unfiltered (_("no syscall record support\n"));
+         return -1;
+       }
+      break;
+
+    case 7:            /* Multiply Low Immediate */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      break;
+
+    case 8:            /* Subtract From Immediate Carrying */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      break;
+
+    case 10:           /* Compare Logical Immediate  */
+    case 11:           /* Compare Immediate */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      break;
+
+    case 13:           /* Add Immediate Carrying and Record */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      /* FALL-THROUGH */
+    case 12:           /* Add Immediate Carrying */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      /* FALL-THROUGH */
+    case 14:           /* Add Immediate */
+    case 15:           /* Add Immediate Shifted */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      break;
+
+    case 16:           /* Branch Conditional */
+      if ((PPC_BO (insn) & 0x4) == 0)
+       record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum);
+      /* FALL-THROUGH */
+    case 18:           /* Branch */
+      if (PPC_LK (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
+      break;
+
+    case 19:
+      if (ppc_process_record_op19 (gdbarch, regcache, addr, insn) != 0)
+       return -1;
+      break;
+
+    case 20:           /* Rotate Left Word Immediate then Mask Insert */
+    case 21:           /* Rotate Left Word Immediate then AND with Mask */
+    case 23:           /* Rotate Left Word then AND with Mask */
+    case 30:           /* Rotate Left Doubleword Immediate then Clear Left */
+                       /* Rotate Left Doubleword Immediate then Clear Right */
+                       /* Rotate Left Doubleword Immediate then Clear */
+                       /* Rotate Left Doubleword then Clear Left */
+                       /* Rotate Left Doubleword then Clear Right */
+                       /* Rotate Left Doubleword Immediate then Mask Insert */
+      if (PPC_RC (insn))
+       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RA (insn));
+      break;
+
+    case 28:           /* AND Immediate */
+    case 29:           /* AND Immediate Shifted */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      /* FALL-THROUGH */
+    case 24:           /* OR Immediate */
+    case 25:           /* OR Immediate Shifted */
+    case 26:           /* XOR Immediate */
+    case 27:           /* XOR Immediate Shifted */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RA (insn));
+      break;
+
+    case 31:
+      if (ppc_process_record_op31 (gdbarch, regcache, addr, insn) != 0)
+       return -1;
+      break;
+
+    case 33:           /* Load Word and Zero with Update */
+    case 35:           /* Load Byte and Zero with Update */
+    case 41:           /* Load Halfword and Zero with Update */
+    case 43:           /* Load Halfword Algebraic with Update */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RA (insn));
+      /* FALL-THROUGH */
+    case 32:           /* Load Word and Zero */
+    case 34:           /* Load Byte and Zero */
+    case 40:           /* Load Halfword and Zero */
+    case 42:           /* Load Halfword Algebraic */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      break;
+
+    case 46:           /* Load Multiple Word */
+      for (i = PPC_RT (insn); i < 32; i++)
+       record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + i);
+      break;
+
+    case 56:           /* Load Quadword */
+      tmp = tdep->ppc_gp0_regnum + (PPC_RT (insn) & ~1);
+      record_full_arch_list_add_reg (regcache, tmp);
+      record_full_arch_list_add_reg (regcache, tmp + 1);
+      break;
+
+    case 49:           /* Load Floating-Point Single with Update */
+    case 51:           /* Load Floating-Point Double with Update */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RA (insn));
+      /* FALL-THROUGH */
+    case 48:           /* Load Floating-Point Single */
+    case 50:           /* Load Floating-Point Double */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_fp0_regnum + PPC_FRT (insn));
+      break;
+
+    case 47:           /* Store Multiple Word */
+       {
+         ULONGEST addr = 0;
+
+         if (PPC_RA (insn) != 0)
+           regcache_raw_read_unsigned (regcache,
+                                       tdep->ppc_gp0_regnum + PPC_RA (insn),
+                                       &addr);
+
+         addr += PPC_D (insn);
+         record_full_arch_list_add_mem (addr, 4 * (32 - PPC_RS (insn)));
+       }
+      break;
+
+    case 37:           /* Store Word with Update */
+    case 39:           /* Store Byte with Update */
+    case 45:           /* Store Halfword with Update */
+    case 53:           /* Store Floating-Point Single with Update */
+    case 55:           /* Store Floating-Point Double with Update */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RA (insn));
+      /* FALL-THROUGH */
+    case 36:           /* Store Word */
+    case 38:           /* Store Byte */
+    case 44:           /* Store Halfword */
+    case 52:           /* Store Floating-Point Single */
+    case 54:           /* Store Floating-Point Double */
+       {
+         ULONGEST addr = 0;
+         int size = -1;
+
+         if (PPC_RA (insn) != 0)
+           regcache_raw_read_unsigned (regcache,
+                                       tdep->ppc_gp0_regnum + PPC_RA (insn),
+                                       &addr);
+         addr += PPC_D (insn);
+
+         if (op6 == 36 || op6 == 37 || op6 == 52 || op6 == 53)
+           size = 4;
+         else if (op6 == 54 || op6 == 55)
+           size = 8;
+         else if (op6 == 44 || op6 == 45)
+           size = 2;
+         else if (op6 == 38 || op6 == 39)
+           size = 1;
+         else
+           gdb_assert (0);
+
+         record_full_arch_list_add_mem (addr, size);
+       }
+      break;
+
+    case 57:           /* Load Floating-Point Double Pair */
+      if (PPC_FIELD (insn, 30, 2) != 0)
+       goto UNKNOWN_OP;
+      tmp = tdep->ppc_fp0_regnum + (PPC_RT (insn) & ~1);
+      record_full_arch_list_add_reg (regcache, tmp);
+      record_full_arch_list_add_reg (regcache, tmp + 1);
+      break;
+
+    case 58:           /* Load Doubleword */
+                       /* Load Doubleword with Update */
+                       /* Load Word Algebraic */
+      if (PPC_FIELD (insn, 30, 2) > 2)
+       goto UNKNOWN_OP;
+
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      if (PPC_BIT (insn, 31))
+       record_full_arch_list_add_reg (regcache,
+                                      tdep->ppc_gp0_regnum + PPC_RA (insn));
+      break;
+
+    case 59:
+      if (ppc_process_record_op59 (gdbarch, regcache, addr, insn) != 0)
+       return -1;
+      break;
+
+    case 60:
+      if (ppc_process_record_op60 (gdbarch, regcache, addr, insn) != 0)
+       return -1;
+      break;
+
+    case 61:           /* Store Floating-Point Double Pair */
+    case 62:           /* Store Doubleword */
+                       /* Store Doubleword with Update */
+                       /* Store Quadword with Update */
+       {
+         ULONGEST addr = 0;
+         int size;
+         int sub2 = PPC_FIELD (insn, 30, 2);
+
+         if ((op6 == 61 && sub2 != 0) || (op6 == 62 && sub2 > 2))
+           goto UNKNOWN_OP;
+
+         if (PPC_RA (insn) != 0)
+           regcache_raw_read_unsigned (regcache,
+                                       tdep->ppc_gp0_regnum + PPC_RA (insn),
+                                       &addr);
+
+         size = ((op6 == 61) || sub2 == 2) ? 16 : 8;
+
+         addr += PPC_DS (insn) << 2;
+         record_full_arch_list_add_mem (addr, size);
+
+         if (op6 == 62 && sub2 == 1)
+           record_full_arch_list_add_reg (regcache,
+                                          tdep->ppc_gp0_regnum +
+                                          PPC_RA (insn));
+
+         break;
+       }
+
+    case 63:
+      if (ppc_process_record_op63 (gdbarch, regcache, addr, insn) != 0)
+       return -1;
+      break;
+
+    default:
+UNKNOWN_OP:
+      fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+                         "%08x at %08lx, %d.\n", insn, addr, op6);
+      return -1;
+    }
+
+  if (record_full_arch_list_add_reg (regcache, PPC_PC_REGNUM))
+    return -1;
+  if (record_full_arch_list_add_end ())
+    return -1;
+  return 0;
+}
+
 /* 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.
index 0558960a57f0f8c63de81fb8bf46241b11132a84..9dd10f070f088ef7b4458efb817442a2c9cdd9fb 100644 (file)
@@ -1,3 +1,9 @@
+2015-01-17  Wei-cheng Wang  <cole945@gmail.com>
+
+       * lib/gdb.exp (supports_process_record): Return true for
+       powerpc*-*-linux*.
+       (supports_reverse): Likewise.
+
 2015-01-15  Don Breazeal  <donb@codesourcery.com>
 
        * gdb.base/attach-pie-noexec.exp: Use can_spawn_for_attach
index fc6bc83363b31f9bbc7b82f4258a1592791a8522..d3a3350a253f9a674c94f519bcda99cd9cdd2529 100644 (file)
@@ -1890,7 +1890,8 @@ proc supports_process_record {} {
     }
 
     if { [istarget "arm*-*-linux*"] || [istarget "x86_64-*-linux*"]
-         || [istarget "i\[34567\]86-*-linux*"] } {
+         || [istarget "i\[34567\]86-*-linux*"]
+         || [istarget "powerpc*-*-linux*"] } {
        return 1
     }
 
@@ -1906,7 +1907,8 @@ proc supports_reverse {} {
     }
 
     if { [istarget "arm*-*-linux*"] || [istarget "x86_64-*-linux*"]
-         || [istarget "i\[34567\]86-*-linux*"] } {
+         || [istarget "i\[34567\]86-*-linux*"]
+         || [istarget "powerpc*-*-linux*"] } {
        return 1
     }