gdbarch: Use an anonymous union for target data in `gdbarch_info'
[deliverable/binutils-gdb.git] / gdb / rs6000-tdep.c
index 565c6201bcee3d8ab5fad68babac8619c69c5331..59d689635112372eabcc9905212e81f31e95a624 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2016 Free Software Foundation, Inc.
+   Copyright (C) 1986-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -43,7 +43,6 @@
 #include "record-full.h"
 #include "auxv.h"
 
-#include "libbfd.h"            /* for bfd_default_set_arch_mach */
 #include "coff/internal.h"     /* for libcoff.h */
 #include "libcoff.h"           /* for xcoff_data */
 #include "coff/xcoff.h"
@@ -65,6 +64,7 @@
 
 #include "ax.h"
 #include "ax-gdb.h"
+#include <algorithm>
 
 #include "features/rs6000/powerpc-32.c"
 #include "features/rs6000/powerpc-altivec32.c"
     && (regnum) >= (tdep)->ppc_efpr0_regnum \
     && (regnum) < (tdep)->ppc_efpr0_regnum + ppc_num_efprs)
 
+/* Holds the current set of options to be passed to the disassembler.  */
+static char *powerpc_disassembler_options;
+
 /* The list of available "set powerpc ..." and "show powerpc ..."
    commands.  */
 static struct cmd_list_element *setpowerpccmdlist = NULL;
@@ -967,18 +970,11 @@ rs6000_fetch_pointer_argument (struct frame_info *frame, int argi,
 
 /* Sequence of bytes for breakpoint instruction.  */
 
-static const unsigned char *
-rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
-                          int *bp_size)
-{
-  static unsigned char big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 };
-  static unsigned char little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d };
-  *bp_size = 4;
-  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
-    return big_breakpoint;
-  else
-    return little_breakpoint;
-}
+constexpr gdb_byte big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 };
+constexpr gdb_byte little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d };
+
+typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint)
+  rs6000_breakpoint;
 
 /* Instruction masks for displaced stepping.  */
 #define BRANCH_MASK 0xfc000000
@@ -990,12 +986,33 @@ rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
 
 /* Instruction masks used during single-stepping of atomic
    sequences.  */
-#define LWARX_MASK 0xfc0007fe
+#define LOAD_AND_RESERVE_MASK 0xfc0007fe
 #define LWARX_INSTRUCTION 0x7c000028
 #define LDARX_INSTRUCTION 0x7c0000A8
-#define STWCX_MASK 0xfc0007ff
+#define LBARX_INSTRUCTION 0x7c000068
+#define LHARX_INSTRUCTION 0x7c0000e8
+#define LQARX_INSTRUCTION 0x7c000228
+#define STORE_CONDITIONAL_MASK 0xfc0007ff
 #define STWCX_INSTRUCTION 0x7c00012d
 #define STDCX_INSTRUCTION 0x7c0001ad
+#define STBCX_INSTRUCTION 0x7c00056d
+#define STHCX_INSTRUCTION 0x7c0005ad
+#define STQCX_INSTRUCTION 0x7c00016d
+
+/* Check if insn is one of the Load And Reserve instructions used for atomic
+   sequences.  */
+#define IS_LOAD_AND_RESERVE_INSN(insn) ((insn & LOAD_AND_RESERVE_MASK) == LWARX_INSTRUCTION \
+                                        || (insn & LOAD_AND_RESERVE_MASK) == LDARX_INSTRUCTION \
+                                        || (insn & LOAD_AND_RESERVE_MASK) == LBARX_INSTRUCTION \
+                                        || (insn & LOAD_AND_RESERVE_MASK) == LHARX_INSTRUCTION \
+                                        || (insn & LOAD_AND_RESERVE_MASK) == LQARX_INSTRUCTION)
+/* Check if insn is one of the Store Conditional instructions used for atomic
+   sequences.  */
+#define IS_STORE_CONDITIONAL_INSN(insn)        ((insn & STORE_CONDITIONAL_MASK) == STWCX_INSTRUCTION \
+                                        || (insn & STORE_CONDITIONAL_MASK) == STDCX_INSTRUCTION \
+                                        || (insn & STORE_CONDITIONAL_MASK) == STBCX_INSTRUCTION \
+                                        || (insn & STORE_CONDITIONAL_MASK) == STHCX_INSTRUCTION \
+                                        || (insn & STORE_CONDITIONAL_MASK) == STQCX_INSTRUCTION)
 
 /* We can't displaced step atomic sequences.  Otherwise this is just
    like simple_displaced_step_copy_insn.  */
@@ -1015,9 +1032,8 @@ ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
 
   insn = extract_signed_integer (buf, PPC_INSN_SIZE, byte_order);
 
-  /* Assume all atomic sequences start with a lwarx/ldarx instruction.  */
-  if ((insn & LWARX_MASK) == LWARX_INSTRUCTION
-      || (insn & LWARX_MASK) == LDARX_INSTRUCTION)
+  /* Assume all atomic sequences start with a Load and Reserve instruction.  */
+  if (IS_LOAD_AND_RESERVE_INSN (insn))
     {
       if (debug_displaced)
        {
@@ -1145,18 +1161,16 @@ ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
   return 1;
 }
 
-/* Checks for an atomic sequence of instructions beginning with a LWARX/LDARX
-   instruction and ending with a STWCX/STDCX instruction.  If such a sequence
-   is found, attempt to step through it.  A breakpoint is placed at the end of 
-   the sequence.  */
-
-int 
-ppc_deal_with_atomic_sequence (struct frame_info *frame)
+/* Checks for an atomic sequence of instructions beginning with a
+   Load And Reserve instruction and ending with a Store Conditional
+   instruction.  If such a sequence is found, attempt to step through it.
+   A breakpoint is placed at the end of the sequence.  */
+std::vector<CORE_ADDR>
+ppc_deal_with_atomic_sequence (struct regcache *regcache)
 {
-  struct gdbarch *gdbarch = get_frame_arch (frame);
-  struct address_space *aspace = get_frame_address_space (frame);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  CORE_ADDR pc = get_frame_pc (frame);
+  CORE_ADDR pc = regcache_read_pc (regcache);
   CORE_ADDR breaks[2] = {-1, -1};
   CORE_ADDR loc = pc;
   CORE_ADDR closing_insn; /* Instruction that closes the atomic sequence.  */
@@ -1165,13 +1179,11 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
   int index;
   int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed).  */  
   const int atomic_sequence_length = 16; /* Instruction sequence length.  */
-  int opcode; /* Branch instruction's OPcode.  */
   int bc_insn_count = 0; /* Conditional branch instruction count.  */
 
-  /* Assume all atomic sequences start with a lwarx/ldarx instruction.  */
-  if ((insn & LWARX_MASK) != LWARX_INSTRUCTION
-      && (insn & LWARX_MASK) != LDARX_INSTRUCTION)
-    return 0;
+  /* Assume all atomic sequences start with a Load And Reserve instruction.  */
+  if (!IS_LOAD_AND_RESERVE_INSN (insn))
+    return {};
 
   /* Assume that no atomic sequence is longer than "atomic_sequence_length" 
      instructions.  */
@@ -1189,8 +1201,8 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
           int absolute = insn & 2;
 
           if (bc_insn_count >= 1)
-            return 0; /* More than one conditional branch found, fallback 
-                         to the standard single-step code.  */
+            return {}; /* More than one conditional branch found, fallback
+                          to the standard single-step code.  */
  
          if (absolute)
            breaks[1] = immediate;
@@ -1201,15 +1213,14 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
          last_breakpoint++;
         }
 
-      if ((insn & STWCX_MASK) == STWCX_INSTRUCTION
-          || (insn & STWCX_MASK) == STDCX_INSTRUCTION)
+      if (IS_STORE_CONDITIONAL_INSN (insn))
         break;
     }
 
-  /* Assume that the atomic sequence ends with a stwcx/stdcx instruction.  */
-  if ((insn & STWCX_MASK) != STWCX_INSTRUCTION
-      && (insn & STWCX_MASK) != STDCX_INSTRUCTION)
-    return 0;
+  /* Assume that the atomic sequence ends with a Store Conditional
+     instruction.  */
+  if (!IS_STORE_CONDITIONAL_INSN (insn))
+    return {};
 
   closing_insn = loc;
   loc += PPC_INSN_SIZE;
@@ -1225,11 +1236,12 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
          || (breaks[1] >= pc && breaks[1] <= closing_insn)))
     last_breakpoint = 0;
 
-  /* Effectively inserts the breakpoints.  */
+  std::vector<CORE_ADDR> next_pcs;
+
   for (index = 0; index <= last_breakpoint; index++)
-    insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
+    next_pcs.push_back (breaks[index]);
 
-  return 1;
+  return next_pcs;
 }
 
 
@@ -2187,7 +2199,7 @@ rs6000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
       CORE_ADDR post_prologue_pc
        = skip_prologue_using_sal (gdbarch, func_addr);
       if (post_prologue_pc != 0)
-       return max (pc, post_prologue_pc);
+       return std::max (pc, post_prologue_pc);
     }
 
   /* Can't determine prologue from the symbol table, need to examine
@@ -2599,7 +2611,7 @@ rs6000_register_to_value (struct frame_info *frame,
                          int *optimizedp, int *unavailablep)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte from[MAX_REGISTER_SIZE];
+  gdb_byte from[PPC_MAX_REGISTER_SIZE];
   
   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
 
@@ -2621,7 +2633,7 @@ rs6000_value_to_register (struct frame_info *frame,
                           const gdb_byte *from)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte to[MAX_REGISTER_SIZE];
+  gdb_byte to[PPC_MAX_REGISTER_SIZE];
 
   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
 
@@ -3135,10 +3147,10 @@ rs6000_adjust_frame_regnum (struct gdbarch *gdbarch, int num, int eh_frame_p)
 struct variant
   {
     /* Name of this variant.  */
-    char *name;
+    const char *name;
 
     /* English description of the variant.  */
-    char *description;
+    const char *description;
 
     /* bfd_arch_info.arch corresponding to variant.  */
     enum bfd_architecture arch;
@@ -3221,14 +3233,6 @@ find_variant_by_arch (enum bfd_architecture arch, unsigned long mach)
   return NULL;
 }
 
-static int
-gdb_print_insn_powerpc (bfd_vma memaddr, disassemble_info *info)
-{
-  if (info->endian == BFD_ENDIAN_BIG)
-    return print_insn_big_powerpc (memaddr, info);
-  else
-    return print_insn_little_powerpc (memaddr, info);
-}
 \f
 static CORE_ADDR
 rs6000_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
@@ -3336,10 +3340,10 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
   if (!fdata.frameless)
     {
       /* Frameless really means stackless.  */
-      LONGEST backchain;
+      ULONGEST backchain;
 
-      if (safe_read_memory_integer (cache->base, wordsize,
-                                   byte_order, &backchain))
+      if (safe_read_memory_unsigned_integer (cache->base, wordsize,
+                                            byte_order, &backchain))
         cache->base = (CORE_ADDR) backchain;
     }
 
@@ -3818,6 +3822,7 @@ bfd_uses_spe_extensions (bfd *abfd)
 #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_DQ(insn)   PPC_SEXT (PPC_FIELD (insn, 16, 12), 12)
 #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)
@@ -3865,6 +3870,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int ext = PPC_FIELD (insn, 21, 11);
+  int vra = PPC_FIELD (insn, 11, 5);
 
   switch (ext & 0x3f)
     {
@@ -3876,6 +3882,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
       /* FALL-THROUGH */
     case 42:           /* Vector Select */
     case 43:           /* Vector Permute */
+    case 59:           /* Vector Permute Right-indexed */
     case 44:           /* Vector Shift Left Double by Octet Immediate */
     case 45:           /* Vector Permute and Exclusive-OR */
     case 60:           /* Vector Add Extended Unsigned Quadword Modulo */
@@ -3883,6 +3890,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     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 35:           /* Vector Multiply-Sum Unsigned Doubleword 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 */
@@ -3892,14 +3900,37 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache,
                                     tdep->ppc_vr0_regnum + PPC_VRT (insn));
       return 0;
+
+    case 48:           /* Multiply-Add High Doubleword */
+    case 49:           /* Multiply-Add High Doubleword Unsigned */
+    case 51:           /* Multiply-Add Low Doubleword */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
     }
 
   switch ((ext & 0x1ff))
     {
+    case 385:
+      if (vra != 0     /* Decimal Convert To Signed Quadword */
+         && vra != 2   /* Decimal Convert From Signed Quadword */
+         && vra != 4   /* Decimal Convert To Zoned */
+         && vra != 5   /* Decimal Convert To National */
+         && vra != 6   /* Decimal Convert From Zoned */
+         && vra != 7   /* Decimal Convert From National */
+         && vra != 31) /* Decimal Set Sign */
+       break;
                        /* 5.16 Decimal Integer Arithmetic Instructions */
     case 1:            /* Decimal Add Modulo */
     case 65:           /* Decimal Subtract Modulo */
 
+    case 193:          /* Decimal Shift */
+    case 129:          /* Decimal Unsigned Shift */
+    case 449:          /* Decimal Shift and Round */
+
+    case 257:          /* Decimal Truncate */
+    case 321:          /* Decimal Unsigned Truncate */
+
       /* Bit-21 should be set.  */
       if (!PPC_BIT (insn, 21))
        break;
@@ -3929,6 +3960,12 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     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 */
+    case 7:            /* Vector Compare Not Equal Byte */
+    case 71:           /* Vector Compare Not Equal Halfword */
+    case 135:          /* Vector Compare Not Equal Word */
+    case 263:          /* Vector Compare Not Equal or Zero Byte */
+    case 327:          /* Vector Compare Not Equal or Zero Halfword */
+    case 391:          /* Vector Compare Not Equal or Zero Word */
       if (PPC_Rc (insn))
        record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache,
@@ -3936,6 +3973,38 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
+  if (ext  == 1538)
+    {
+      switch (vra)
+       {
+       case 0:         /* Vector Count Leading Zero Least-Significant Bits
+                          Byte */
+       case 1:         /* Vector Count Trailing Zero Least-Significant Bits
+                          Byte */
+         record_full_arch_list_add_reg (regcache,
+                                        tdep->ppc_gp0_regnum + PPC_RT (insn));
+         return 0;
+
+       case 6:         /* Vector Negate Word */
+       case 7:         /* Vector Negate Doubleword */
+       case 8:         /* Vector Parity Byte Word */
+       case 9:         /* Vector Parity Byte Doubleword */
+       case 10:        /* Vector Parity Byte Quadword */
+       case 16:        /* Vector Extend Sign Byte To Word */
+       case 17:        /* Vector Extend Sign Halfword To Word */
+       case 24:        /* Vector Extend Sign Byte To Doubleword */
+       case 25:        /* Vector Extend Sign Halfword To Doubleword */
+       case 26:        /* Vector Extend Sign Word To Doubleword */
+       case 28:        /* Vector Count Trailing Zeros Byte */
+       case 29:        /* Vector Count Trailing Zeros Halfword */
+       case 30:        /* Vector Count Trailing Zeros Word */
+       case 31:        /* Vector Count Trailing Zeros Doubleword */
+         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 */
@@ -4107,10 +4176,44 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 1923:         /* Vector Population Count Word */
     case 1987:         /* Vector Population Count Doubleword */
     case 1356:         /* Vector Bit Permute Quadword */
+    case 1484:         /* Vector Bit Permute Doubleword */
+    case 513:          /* Vector Multiply-by-10 Unsigned Quadword */
+    case 1:            /* Vector Multiply-by-10 & write Carry Unsigned
+                          Quadword */
+    case 577:          /* Vector Multiply-by-10 Extended Unsigned Quadword */
+    case 65:           /* Vector Multiply-by-10 Extended & write Carry
+                          Unsigned Quadword */
+    case 1027:         /* Vector Absolute Difference Unsigned Byte */
+    case 1091:         /* Vector Absolute Difference Unsigned Halfword */
+    case 1155:         /* Vector Absolute Difference Unsigned Word */
+    case 1796:         /* Vector Shift Right Variable */
+    case 1860:         /* Vector Shift Left Variable */
+    case 133:          /* Vector Rotate Left Word then Mask Insert */
+    case 197:          /* Vector Rotate Left Doubleword then Mask Insert */
+    case 389:          /* Vector Rotate Left Word then AND with Mask */
+    case 453:          /* Vector Rotate Left Doubleword then AND with Mask */
+    case 525:          /* Vector Extract Unsigned Byte */
+    case 589:          /* Vector Extract Unsigned Halfword */
+    case 653:          /* Vector Extract Unsigned Word */
+    case 717:          /* Vector Extract Doubleword */
+    case 781:          /* Vector Insert Byte */
+    case 845:          /* Vector Insert Halfword */
+    case 909:          /* Vector Insert Word */
+    case 973:          /* Vector Insert Doubleword */
       record_full_arch_list_add_reg (regcache,
                                     tdep->ppc_vr0_regnum + PPC_VRT (insn));
       return 0;
 
+    case 1549:         /* Vector Extract Unsigned Byte Left-Indexed */
+    case 1613:         /* Vector Extract Unsigned Halfword Left-Indexed */
+    case 1677:         /* Vector Extract Unsigned Word Left-Indexed */
+    case 1805:         /* Vector Extract Unsigned Byte Right-Indexed */
+    case 1869:         /* Vector Extract Unsigned Halfword Right-Indexed */
+    case 1933:         /* Vector Extract Unsigned Word Right-Indexed */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+
     case 1604:         /* Move To Vector Status and Control Register */
       record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
       return 0;
@@ -4118,6 +4221,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache,
                                     tdep->ppc_vr0_regnum + PPC_VRT (insn));
       return 0;
+    case 833:          /* Decimal Copy Sign */
+      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;
     }
 
   fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
@@ -4135,6 +4243,14 @@ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
 
+  switch (ext & 0x01f)
+    {
+    case 2:            /* Add PC Immediate Shifted */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+    }
+
   switch (ext)
     {
     case 0:            /* Move Condition Register Field */
@@ -4240,6 +4356,15 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
+  if ((ext & 0xff) == 170)
+    {
+      /* Add Extended using alternate carry bits */
+      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;
+    }
+
   switch (ext)
     {
     case 78:           /* Determine Leftmost Zero Byte */
@@ -4258,6 +4383,9 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 302:          /* Move From Branch History Rolling Buffer */
     case 339:          /* Move From Special Purpose Register */
     case 371:          /* Move From Time Base [Phased-Out]  */
+    case 309:          /* Load Doubleword Monitored Indexed  */
+    case 128:          /* Set Boolean */
+    case 755:          /* Deliver A Random Number */
       record_full_arch_list_add_reg (regcache,
                                     tdep->ppc_gp0_regnum + PPC_RT (insn));
       return 0;
@@ -4274,6 +4402,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 282:          /* Convert Declets To Binary Coded Decimal */
     case 314:          /* Convert Binary Coded Decimal To Declets */
     case 508:          /* Compare bytes */
+    case 307:          /* Move From VSR Lower Doubleword */
       record_full_arch_list_add_reg (regcache,
                                     tdep->ppc_gp0_regnum + PPC_RA (insn));
       return 0;
@@ -4292,6 +4421,12 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 32:           /* Compare logical */
     case 144:          /* Move To Condition Register Fields */
                        /* Move To One Condition Register Field */
+    case 192:          /* Compare Ranged Byte */
+    case 224:          /* Compare Equal Byte */
+    case 576:          /* Move XER to CR Extended */
+    case 902:          /* Paste (should always fail due to single-stepping and
+                          the memory location might not be accessible, so
+                          record only CR) */
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       return 0;
 
@@ -4318,6 +4453,12 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 790:          /* Load Halfword Byte-Reverse Indexed */
     case 534:          /* Load Word Byte-Reverse Indexed */
     case 532:          /* Load Doubleword Byte-Reverse Indexed */
+    case 582:          /* Load Word Atomic */
+    case 614:          /* Load Doubleword Atomic */
+    case 265:          /* Modulo Unsigned Doubleword */
+    case 777:          /* Modulo Signed Doubleword */
+    case 267:          /* Modulo Unsigned Word */
+    case 779:          /* Modulo Signed Word */
       record_full_arch_list_add_reg (regcache,
                                     tdep->ppc_gp0_regnum + PPC_RT (insn));
       return 0;
@@ -4396,6 +4537,16 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 844:          /* Load VSX Vector Doubleword*2 Indexed */
     case 332:          /* Load VSX Vector Doubleword & Splat Indexed */
     case 780:          /* Load VSX Vector Word*4 Indexed */
+    case 268:          /* Load VSX Vector Indexed */
+    case 364:          /* Load VSX Vector Word & Splat Indexed */
+    case 812:          /* Load VSX Vector Halfword*8 Indexed */
+    case 876:          /* Load VSX Vector Byte*16 Indexed */
+    case 269:          /* Load VSX Vector with Length */
+    case 301:          /* Load VSX Vector Left-justified with Length */
+    case 781:          /* Load VSX Scalar as Integer Byte & Zero Indexed */
+    case 813:          /* Load VSX Scalar as Integer Halfword & Zero Indexed */
+    case 403:          /* Move To VSR Word & Splat */
+    case 435:          /* Move To VSR Double Doubleword */
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
 
@@ -4417,6 +4568,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 922:          /* Extend Sign Halfword */
     case 954:          /* Extend Sign Byte */
     case 986:          /* Extend Sign Word */
+    case 538:          /* Count Trailing Zeros Word */
+    case 570:          /* Count Trailing Zeros Doubleword */
+    case 890:          /* Extend-Sign Word and Shift Left Immediate (445) */
+    case 890 | 1:      /* Extend-Sign Word and Shift Left Immediate (445) */
       if (PPC_RC (insn))
        record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache,
@@ -4459,6 +4614,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 727:          /* Store Floating-Point Double Indexed */
     case 919:          /* Store Floating-Point Double Pair Indexed */
     case 983:          /* Store Floating-Point as Integer Word Indexed */
+    case 396:          /* Store VSX Vector Indexed */
+    case 940:          /* Store VSX Vector Halfword*8 Indexed */
+    case 1004:         /* Store VSX Vector Byte*16 Indexed */
+    case 909:          /* Store VSX Scalar as Integer Byte Indexed */
+    case 941:          /* Store VSX Scalar as Integer Halfword Indexed */
       if (ext == 694 || ext == 726 || ext == 150 || ext == 214 || ext == 182)
        record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
 
@@ -4488,6 +4648,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
        case 135:       /* Store Vector Element Byte Indexed */
        case 215:       /* Store Byte Indexed */
        case 694:       /* Store Byte Conditional Indexed */
+       case 909:       /* Store VSX Scalar as Integer Byte Indexed */
          size = 1;
          break;
        case 439:       /* Store Halfword with Update Indexed */
@@ -4495,6 +4656,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
        case 407:       /* Store Halfword Indexed */
        case 726:       /* Store Halfword Conditional Indexed */
        case 918:       /* Store Halfword Byte-Reverse Indexed */
+       case 941:       /* Store VSX Scalar as Integer Halfword Indexed */
          size = 2;
          break;
        case 181:       /* Store Doubleword with Update Indexed */
@@ -4512,6 +4674,9 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
        case 231:       /* Store Vector Indexed */
        case 487:       /* Store Vector Indexed LRU */
        case 919:       /* Store Floating-Point Double Pair Indexed */
+       case 396:       /* Store VSX Vector Indexed */
+       case 940:       /* Store VSX Vector Halfword*8 Indexed */
+       case 1004:      /* Store VSX Vector Byte*16 Indexed */
          size = 16;
          break;
        default:
@@ -4538,10 +4703,47 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_mem (addr, size);
       return 0;
 
+    case 397:          /* Store VSX Vector with Length */
+    case 429:          /* Store VSX Vector Left-justified with Length */
+      ra = 0;
+      if (PPC_RA (insn) != 0)
+       regcache_raw_read_unsigned (regcache,
+                                   tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
+      ea = ra;
+      regcache_raw_read_unsigned (regcache,
+                                 tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
+      /* Store up to 16 bytes.  */
+      nb = (rb & 0xff) > 16 ? 16 : (rb & 0xff);
+      if (nb > 0)
+       record_full_arch_list_add_mem (ea, nb);
+      return 0;
+
+    case 710:          /* Store Word Atomic */
+    case 742:          /* Store Doubleword Atomic */
+      ra = 0;
+      if (PPC_RA (insn) != 0)
+       regcache_raw_read_unsigned (regcache,
+                                   tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
+      ea = ra;
+      switch (ext)
+       {
+       case 710:       /* Store Word Atomic */
+         size = 8;
+         break;
+       case 742:       /* Store Doubleword Atomic */
+         size = 16;
+         break;
+       default:
+         gdb_assert (0);
+       }
+      record_full_arch_list_add_mem (ea, 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);
+       regcache_raw_read_unsigned (regcache,
+                                   tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
       ea += ra;
 
       nb = PPC_NB (insn);
@@ -4555,7 +4757,8 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 661:          /* Store String Word Indexed */
       ra = 0;
       if (PPC_RA (insn) != 0)
-       regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &ra);
+       regcache_raw_read_unsigned (regcache,
+                                   tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
       ea += ra;
 
       regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &xer);
@@ -4563,7 +4766,9 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 
       if (nb != 0)
        {
-         regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &rb);
+         regcache_raw_read_unsigned (regcache,
+                                     tdep->ppc_gp0_regnum + PPC_RB (insn),
+                                     &rb);
          ea += rb;
          record_full_arch_list_add_mem (ea, nb);
        }
@@ -4603,6 +4808,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 430:          /* Clear BHRB */
     case 598:          /* Synchronize */
     case 62:           /* Wait for Interrupt */
+    case 30:           /* Wait */
     case 22:           /* Instruction Cache Block Touch */
     case 854:          /* Enforce In-order Execution of I/O */
     case 246:          /* Data Cache Block Touch for Store */
@@ -4611,27 +4817,30 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 278:          /* Data Cache Block Touch */
     case 758:          /* Data Cache Block Allocate */
     case 982:          /* Instruction Cache Block Invalidate */
+    case 774:          /* Copy */
+    case 838:          /* CP_Abort */
       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 %s, 31-%d.\n",
-                         insn, paddress (gdbarch, addr), ext);
-      return -1;
+      record_full_arch_list_add_reg (regcache, tdep->ppc_ps_regnum);
+      /* FALL-THROUGH */
+    case 718:          /* Transaction Check */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
 
     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)  */
 
+      ra = 0;
       if (PPC_RA (insn) != 0)
        regcache_raw_read_unsigned (regcache,
                                    tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
@@ -4709,6 +4918,7 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 226:          /* DFP Test Data Group */
     case 642:          /* DFP Compare Unordered */
     case 674:          /* DFP Test Significance */
+    case 675:          /* DFP Test Significance Immediate */
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       return 0;
@@ -4808,7 +5018,16 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 217:          /* ditto */
     case 104:          /* VSX Vector Subtract Double-Precision */
     case 72:           /* VSX Vector Subtract Single-Precision */
+    case 128:          /* VSX Scalar Maximum Type-C Double-Precision */
+    case 136:          /* VSX Scalar Minimum Type-C Double-Precision */
+    case 144:          /* VSX Scalar Maximum Type-J Double-Precision */
+    case 152:          /* VSX Scalar Minimum Type-J Double-Precision */
+    case 3:            /* VSX Scalar Compare Equal Double-Precision */
+    case 11:           /* VSX Scalar Compare Greater Than Double-Precision */
+    case 19:           /* VSX Scalar Compare Greater Than or Equal
+                          Double-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
     case 240:          /* VSX Vector Copy Sign Double-Precision */
     case 208:          /* VSX Vector Copy Sign Single-Precision */
     case 130:          /* VSX Logical AND */
@@ -4829,6 +5048,14 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
     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) */
+    case 216:          /* VSX Vector Insert Exponent Single-Precision */
+    case 248:          /* VSX Vector Insert Exponent Double-Precision */
+    case 26:           /* VSX Vector Permute */
+    case 58:           /* VSX Vector Permute Right-indexed */
+    case 213:          /* VSX Vector Test Data Class Single-Precision (DC=0) */
+    case 213 | 0x8:    /* VSX Vector Test Data Class Single-Precision (DC=1) */
+    case 245:          /* VSX Vector Test Data Class Double-Precision (DC=0) */
+    case 245 | 0x8:    /* VSX Vector Test Data Class Double-Precision (DC=1) */
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
 
@@ -4840,6 +5067,7 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
 
     case 35:           /* VSX Scalar Compare Unordered Double-Precision */
     case 43:           /* VSX Scalar Compare Ordered Double-Precision */
+    case 59:           /* VSX Scalar Compare Exponents 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;
@@ -4986,6 +5214,7 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
     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);
+      /* FALL-THROUGH */
     case 345:          /* VSX Scalar Absolute Value Double-Precision */
     case 267:          /* VSX Scalar Convert Scalar Single-Precision to
                           Vector Single-Precision format Non-signalling */
@@ -5000,9 +5229,15 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 505:          /* VSX Vector Negate Double-Precision */
     case 441:          /* VSX Vector Negate Single-Precision */
     case 164:          /* VSX Splat Word */
+    case 165:          /* VSX Vector Extract Unsigned Word */
+    case 181:          /* VSX Vector Insert Word */
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
 
+    case 298:          /* VSX Scalar Test Data Class Single-Precision */
+    case 362:          /* VSX Scalar Test Data Class Double-Precision */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
     case 106:          /* VSX Scalar Test for software Square Root
                           Double-Precision */
     case 234:          /* VSX Vector Test for software Square Root
@@ -5011,6 +5246,60 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
                           Single-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       return 0;
+
+    case 347:
+      switch (PPC_FIELD (insn, 11, 5))
+       {
+       case 0:         /* VSX Scalar Extract Exponent Double-Precision */
+       case 1:         /* VSX Scalar Extract Significand Double-Precision */
+          record_full_arch_list_add_reg (regcache,
+                                        tdep->ppc_gp0_regnum + PPC_RT (insn));
+         return 0;
+       case 16:        /* VSX Scalar Convert Half-Precision format to
+                          Double-Precision format */
+       case 17:        /* VSX Scalar round & Convert Double-Precision format
+                          to Half-Precision format */
+         record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+         ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+         return 0;
+       }
+      break;
+
+    case 475:
+      switch (PPC_FIELD (insn, 11, 5))
+       {
+       case 24:        /* VSX Vector Convert Half-Precision format to
+                          Single-Precision format */
+       case 25:        /* VSX Vector round and Convert Single-Precision format
+                          to Half-Precision format */
+         record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+         /* FALL-THROUGH */
+       case 0:         /* VSX Vector Extract Exponent Double-Precision */
+       case 1:         /* VSX Vector Extract Significand Double-Precision */
+       case 7:         /* VSX Vector Byte-Reverse Halfword */
+       case 8:         /* VSX Vector Extract Exponent Single-Precision */
+       case 9:         /* VSX Vector Extract Significand Single-Precision */
+       case 15:        /* VSX Vector Byte-Reverse Word */
+       case 23:        /* VSX Vector Byte-Reverse Doubleword */
+       case 31:        /* VSX Vector Byte-Reverse Quadword */
+         ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+         return 0;
+       }
+      break;
+    }
+
+  switch (ext)
+    {
+    case 360:          /* VSX Vector Splat Immediate Byte */
+      if (PPC_FIELD (insn, 11, 2) == 0)
+       {
+         ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+         return 0;
+       }
+      break;
+    case 918:          /* VSX Scalar Insert Exponent Double-Precision */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
     }
 
   if (((ext >> 3) & 0x3) == 3) /* VSX Select */
@@ -5024,6 +5313,65 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record instructions of primary opcode-61 at ADDR.
+   Return 0 if successful.  */
+
+static int
+ppc_process_record_op61 (struct gdbarch *gdbarch, struct regcache *regcache,
+                          CORE_ADDR addr, uint32_t insn)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ULONGEST ea = 0;
+  int size;
+
+  switch (insn & 0x3)
+    {
+    case 0:            /* Store Floating-Point Double Pair */
+    case 2:            /* Store VSX Scalar Doubleword */
+    case 3:            /* Store VSX Scalar Single */
+      if (PPC_RA (insn) != 0)
+       regcache_raw_read_unsigned (regcache,
+                                   tdep->ppc_gp0_regnum + PPC_RA (insn),
+                                   &ea);
+      ea += PPC_DS (insn) << 2;
+      switch (insn & 0x3)
+       {
+       case 0:         /* Store Floating-Point Double Pair */
+         size = 16;
+         break;
+       case 2:         /* Store VSX Scalar Doubleword */
+         size = 8;
+         break;
+       case 3:         /* Store VSX Scalar Single */
+         size = 4;
+         break;
+       default:
+         gdb_assert (0);
+       }
+      record_full_arch_list_add_mem (ea, size);
+      return 0;
+    }
+
+  switch (insn & 0x7)
+    {
+    case 1:            /* Load VSX Vector */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
+    case 5:            /* Store VSX Vector */
+      if (PPC_RA (insn) != 0)
+       regcache_raw_read_unsigned (regcache,
+                                   tdep->ppc_gp0_regnum + PPC_RA (insn),
+                                   &ea);
+      ea += PPC_DQ (insn) << 4;
+      record_full_arch_list_add_mem (ea, 16);
+      return 0;
+    }
+
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                     "at %s.\n", insn, paddress (gdbarch, addr));
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-63 at ADDR.
    Return 0 if successful.  */
 
@@ -5060,6 +5408,17 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *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;
+    }
+
+  switch (ext & 0xff)
+    {
+    case 5:            /* VSX Scalar Round to Quad-Precision Integer */
+    case 37:           /* VSX Scalar Round Quad-Precision to Double-Extended
+                          Precision */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+      return 0;
     }
 
   switch (ext)
@@ -5091,6 +5450,7 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 226:          /* DFP Test Data Group Quad */
     case 642:          /* DFP Compare Unordered Quad */
     case 674:          /* DFP Test Significance Quad */
+    case 675:          /* DFP Test Significance Immediate 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;
@@ -5112,7 +5472,7 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
       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;
+      return 0;
 
     case 354:          /* DFP Extract Biased Exponent Quad */
       record_full_arch_list_add_reg (regcache,
@@ -5147,7 +5507,26 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       return 0;
 
-    case 583:          /* Move From FPSCR */
+    case 583:
+      switch (PPC_FIELD (insn, 11, 5))
+        {
+         case 1:       /* Move From FPSCR & Clear Enables */
+         case 20:      /* Move From FPSCR Control & set DRN */
+         case 21:      /* Move From FPSCR Control & set DRN Immediate */
+         case 22:      /* Move From FPSCR Control & set RN */
+         case 23:      /* Move From FPSCR Control & set RN Immediate */
+           record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+         case 0:       /* Move From FPSCR */
+         case 24:      /* Move From FPSCR Lightweight */
+           if (PPC_FIELD (insn, 11, 5) == 0 && 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));
+           return 0;
+        }
+      break;
+
     case 8:            /* Floating Copy Sign */
     case 40:           /* Floating Negate */
     case 72:           /* Floating Move Register */
@@ -5172,11 +5551,15 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
       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;
+      return 0;
 
     case 0:            /* Floating Compare Unordered */
     case 32:           /* Floating Compare Ordered */
     case 64:           /* Move to Condition Register from FPSCR */
+    case 132:          /* VSX Scalar Compare Ordered Quad-Precision */
+    case 164:          /* VSX Scalar Compare Exponents Quad-Precision */
+    case 644:          /* VSX Scalar Compare Unordered Quad-Precision */
+    case 708:          /* VSX Scalar Test Data Class Quad-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       /* FALL-THROUGH */
     case 128:          /* Floating Test for software Divide */
@@ -5184,10 +5567,65 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       return 0;
 
+    case 4:            /* VSX Scalar Add Quad-Precision */
+    case 36:           /* VSX Scalar Multiply Quad-Precision */
+    case 388:          /* VSX Scalar Multiply-Add Quad-Precision */
+    case 420:          /* VSX Scalar Multiply-Subtract Quad-Precision */
+    case 452:          /* VSX Scalar Negative Multiply-Add Quad-Precision */
+    case 484:          /* VSX Scalar Negative Multiply-Subtract
+                          Quad-Precision */
+    case 516:          /* VSX Scalar Subtract Quad-Precision */
+    case 548:          /* VSX Scalar Divide Quad-Precision */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
+    case 100:          /* VSX Scalar Copy Sign Quad-Precision */
+    case 868:          /* VSX Scalar Insert Exponent Quad-Precision */
+      ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+      return 0;
+
+    case 804:
+      switch (PPC_FIELD (insn, 11, 5))
+       {
+       case 27:        /* VSX Scalar Square Root Quad-Precision */
+         record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+         /* FALL-THROUGH */
+       case 0:         /* VSX Scalar Absolute Quad-Precision */
+       case 2:         /* VSX Scalar Extract Exponent Quad-Precision */
+       case 8:         /* VSX Scalar Negative Absolute Quad-Precision */
+       case 16:        /* VSX Scalar Negate Quad-Precision */
+       case 18:        /* VSX Scalar Extract Significand Quad-Precision */
+         ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+         return 0;
+       }
+      break;
+
+    case 836:
+      switch (PPC_FIELD (insn, 11, 5))
+       {
+       case 1:         /* VSX Scalar truncate & Convert Quad-Precision format
+                          to Unsigned Word format */
+       case 2:         /* VSX Scalar Convert Unsigned Doubleword format to
+                          Quad-Precision format */
+       case 9:         /* VSX Scalar truncate & Convert Quad-Precision format
+                          to Signed Word format */
+       case 10:        /* VSX Scalar Convert Signed Doubleword format to
+                          Quad-Precision format */
+       case 17:        /* VSX Scalar truncate & Convert Quad-Precision format
+                          to Unsigned Doubleword format */
+       case 20:        /* VSX Scalar round & Convert Quad-Precision format to
+                          Double-Precision format */
+       case 22:        /* VSX Scalar Convert Double-Precision format to
+                          Quad-Precision format */
+       case 25:        /* VSX Scalar truncate & Convert Quad-Precision format
+                          to Signed Doubleword format */
+         record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+         ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+         return 0;
+       }
     }
 
   fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
-                     "at %s, 59-%d.\n", insn, paddress (gdbarch, addr), ext);
+                     "at %s, 63-%d.\n", insn, paddress (gdbarch, addr), ext);
   return -1;
 }
 
@@ -5398,12 +5836,21 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
        }
       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);
+    case 57:
+      switch (insn & 0x3)
+        {
+       case 0:         /* Load Floating-Point Double Pair */
+         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 2:         /* Load VSX Scalar Doubleword */
+       case 3:         /* Load VSX Scalar Single */
+         ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+         break;
+       default:
+         goto UNKNOWN_OP;
+       }
       break;
 
     case 58:           /* Load Doubleword */
@@ -5429,7 +5876,11 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
        return -1;
       break;
 
-    case 61:           /* Store Floating-Point Double Pair */
+    case 61:
+      if (ppc_process_record_op61 (gdbarch, regcache, addr, insn) != 0)
+       return -1;
+      break;
+
     case 62:           /* Store Doubleword */
                        /* Store Doubleword with Update */
                        /* Store Quadword with Update */
@@ -5438,7 +5889,7 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
          int size;
          int sub2 = PPC_FIELD (insn, 30, 2);
 
-         if ((op6 == 61 && sub2 != 0) || (op6 == 62 && sub2 > 2))
+         if (sub2 > 2)
            goto UNKNOWN_OP;
 
          if (PPC_RA (insn) != 0)
@@ -5446,7 +5897,7 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
                                        tdep->ppc_gp0_regnum + PPC_RA (insn),
                                        &addr);
 
-         size = ((op6 == 61) || sub2 == 2) ? 16 : 8;
+         size = (sub2 == 2) ? 16 : 8;
 
          addr += PPC_DS (insn) << 2;
          record_full_arch_list_add_mem (addr, size);
@@ -5958,7 +6409,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM);
   set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1);
-  set_gdbarch_deprecated_fp_regnum (gdbarch, PPC_R0_REGNUM + 1);
   set_gdbarch_fp0_regnum (gdbarch, tdep->ppc_fp0_regnum);
   set_gdbarch_register_sim_regno (gdbarch, rs6000_register_sim_regno);
 
@@ -5991,12 +6441,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
 
-  /* Select instruction printer.  */
-  if (arch == bfd_arch_rs6000)
-    set_gdbarch_print_insn (gdbarch, print_insn_rs6000);
-  else
-    set_gdbarch_print_insn (gdbarch, gdb_print_insn_powerpc);
-
   set_gdbarch_num_regs (gdbarch, PPC_NUM_REGS);
 
   if (have_spe)
@@ -6041,7 +6485,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_skip_main_prologue (gdbarch, rs6000_skip_main_prologue);
 
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
-  set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
+
+  set_gdbarch_breakpoint_kind_from_pc (gdbarch,
+                                      rs6000_breakpoint::kind_from_pc);
+  set_gdbarch_sw_breakpoint_from_kind (gdbarch,
+                                      rs6000_breakpoint::bp_from_kind);
 
   /* The value of symbols of type N_SO and N_FUN maybe null when
      it shouldn't be.  */
@@ -6074,8 +6522,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_displaced_step_hw_singlestep (gdbarch,
                                            ppc_displaced_step_hw_singlestep);
   set_gdbarch_displaced_step_fixup (gdbarch, ppc_displaced_step_fixup);
-  set_gdbarch_displaced_step_free_closure (gdbarch,
-                                          simple_displaced_step_free_closure);
   set_gdbarch_displaced_step_location (gdbarch,
                                       displaced_step_at_entry_point);
 
@@ -6083,14 +6529,13 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   info.target_desc = tdesc;
-  info.tdep_info = tdesc_data;
+  info.tdesc_data = tdesc_data;
   gdbarch_init_osabi (info, gdbarch);
 
   switch (info.osabi)
     {
     case GDB_OSABI_LINUX:
-    case GDB_OSABI_NETBSD_AOUT:
-    case GDB_OSABI_NETBSD_ELF:
+    case GDB_OSABI_NETBSD:
     case GDB_OSABI_UNKNOWN:
       set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
       frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
@@ -6152,6 +6597,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   else
     register_ppc_ravenscar_ops (gdbarch);
 
+  set_gdbarch_disassembler_options (gdbarch, &powerpc_disassembler_options);
+  set_gdbarch_valid_disassembler_options (gdbarch,
+                                         disassembler_options_powerpc ());
+
   return gdbarch;
 }
 
This page took 0.0388 seconds and 4 git commands to generate.