public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Add recording support for the ISA 3.1 Powerpc instructions
@ 2022-03-04 19:46 Carl Love
  2022-03-04 19:52 ` [PATCH 1/2] " Carl Love
                   ` (2 more replies)
  0 siblings, 3 replies; 25+ messages in thread
From: Carl Love @ 2022-03-04 19:46 UTC (permalink / raw)
  To: gdb-patches, Ulrich Weigand; +Cc: Will Schmidt, Tulio Magno, Rogerio Alves, cel

GDB maintainers:

The gdb record functionality does not have support for the the Powerpc
ISA 3.1 instructions.  

The first patch in this series will add the missing support to record
the registers for each of the ISA 3.1 instructions.

The second patch in the series adds two test cases.  The first test
case verifies the recording works for a few of the ISA 2.06
instructions.  The second case verifies recording of a few ISA 3.1
instructions.

I have used the Valgrind ISA 3.1 testsuite to verify that all of the
ISA 3.1 instructions are recognized by gdb record.  Additionally, I
manually ran gdb stoping at the Valgrind test function for each of the
new instructions.  I then verified that all of the expected registers
changed and were then restored when the instruction was executed in
reverse.  Basically, the test process consisted of stopping at the isa
instruction, issue the gdb command record command, info registers all
saving the output file 1, si,  info registers all saving the output
file 2, reverse-stepi, info registers all saving the output file 3.  I
then diffed files 1 and 2 to verify the test changed all of the
registers specified in the ISA. Finally, diff files 1 and 3 to verify
all of the registers were restored.

                        Carl Love


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 1/2] Add recording support for the ISA 3.1 Powerpc instructions
  2022-03-04 19:46 [PATCH 0/2] Add recording support for the ISA 3.1 Powerpc instructions Carl Love
@ 2022-03-04 19:52 ` Carl Love
  2022-03-06 11:53   ` Joel Brobecker
  2022-03-04 19:53 ` [PATCH 2/2] " Carl Love
  2022-04-12 17:09 ` [PATCH 0/2 Version 2] " Carl Love
  2 siblings, 1 reply; 25+ messages in thread
From: Carl Love @ 2022-03-04 19:52 UTC (permalink / raw)
  To: gdb-patches, Ulrich Weigand; +Cc: Will Schmidt, Tulio Magno, Rogerio Alves, cel

GDB maintainers:

The gdb record functionality does not have support for the the
PowerpcISA 3.1 instructions.  The following patch adds the missing gdb
record support for power. 

As mentioned in message [0/2], I have used the Valgrind ISA 3.1
testsuite to verify that all of the ISA 3.1 instructions are recognized
by gdb record with this patch applied. Please let me know if this patch
is accepatble to commit to the gdb mainline repository.   Thanks.

                         Carl Love

------------------------------------------------

Add recording support for the ISA 3.1 Powerpc  instructions.

This patch adds support for the Powerpc ISA 3.1 instructions to the Powerpc
gdb instruction recording routines.  Case statement entries are added to a
number of the existing routines for recording the 32-bit word instructions.
A few new functions were added to handle the new word instructions.  The 64-bit
prefix instructions are all handled by a set of new routines.  The function
ppc_process_prefix_instruction() is the primary function to handle the
prefixed instructions. It calls additional functions to handle specific
sets of prefixed instructions.  These new functions are:

  ppc_process_record_prefix_vsx_d_form(),
  ppc_process_record_prefix_store_vsx_ds_form(),
  ppc_process_record_prefix_op34(),
  ppc_process_record_prefix_op33(),
  ppc_process_record_prefix_op32(),
  ppc_process_record_prefix_store(),
  ppc_process_record_prefix_op59_XX3(),
  ppc_process_record_prefix_op42().
---
 gdb/rs6000-tdep.c | 1110 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 1082 insertions(+), 28 deletions(-)

diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index ee3f051dda6..e182bb08877 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -4123,8 +4123,26 @@ bfd_uses_spe_extensions (bfd *abfd)
 #define PPC_LEV(insn)	PPC_FIELD (insn, 20, 7)
 
 #define PPC_XT(insn)	((PPC_TX (insn) << 5) | PPC_T (insn))
+#define PPC_XTp(insn)	((PPC_BIT (insn, 10) << 5)	\
+			 | PPC_FIELD (insn, 6, 4) << 1)
+#define PPC_XSp(insn)	((PPC_BIT (insn, 10) << 5)	\
+			 | PPC_FIELD (insn, 6, 4) << 1)
 #define PPC_XER_NB(xer)	(xer & 0x7f)
 
+/* The following macros are for the prefixed instructions.  */
+#define P_PPC_D(insn_prefix, insn_suffix) \
+  PPC_SEXT (PPC_FIELD (insn_prefix, 14, 18) << 16 \
+	    | PPC_FIELD (insn_suffix, 16, 16), 34)
+#define P_PPC_TX5(insn_sufix)	PPC_BIT (insn_suffix, 5)
+#define P_PPC_TX15(insn_suffix) PPC_BIT (insn_suffix, 15)
+#define P_PPC_XT(insn_suffix)	((PPC_TX (insn_suffix) << 5) \
+				 | PPC_T (insn_suffix))
+#define P_PPC_XT5(insn_suffix) ((P_PPC_TX5 (insn_suffix) << 5) \
+				| PPC_T (insn_suffix))
+#define P_PPC_XT15(insn_suffix) \
+  ((P_PPC_TX15 (insn_suffix) << 5) | PPC_T (insn_suffix))
+
+
 /* Record Vector-Scalar Registers.
    For VSR less than 32, it's represented by an FPR and an VSR-upper register.
    Otherwise, it's just a VR register.  Record them accordingly.  */
@@ -4152,6 +4170,52 @@ ppc_record_vsr (struct regcache *regcache, ppc_gdbarch_tdep *tdep, int vsr)
   return 0;
 }
 
+#define RECORD_FPSCR 1
+#define DO_NOT_RECORD_FPSCR 0
+
+static int
+ppc_record_ACC_fpscr (struct regcache *regcache, ppc_gdbarch_tdep *tdep,
+		      int at, int save_fpscr)
+{
+  int i;
+  if (at < 0 || at >= 8)
+    return -1;
+
+  /* The ACC consists of 8 entries, each entries consist of four 128-bit
+     rows.
+
+     The ACC rows map to specific VSR registers.
+         ACC[0][0] -> VSR[0]
+         ACC[0][1] -> VSR[1]
+         ACC[0][2] -> VSR[2]
+         ACC[0][3] -> VSR[3]
+              ...
+         ACC[7][0] -> VSR[28]
+         ACC[7][1] -> VSR[29]
+         ACC[7][2] -> VSR[30]
+         ACC[7][3] -> VSR[31]
+
+     NOTE:
+     In ISA 3.1 the ACC is mapped on top of VSR[0] thru VSR[31].
+
+     In the future, the ACC may be implemented as an independent register file
+     rather then mapping on top of the VSRs. This will then require the ACC to
+     be assigned its on register number and the ptrace interface to be able
+     access the ACC.
+  */
+
+  /* ACC maps over the same VSR space as the fp registers.  */
+  for (i = 0; i<4; i++) {
+    record_full_arch_list_add_reg (regcache, tdep->ppc_fp0_regnum + at*4 + i);
+    record_full_arch_list_add_reg (regcache,
+				   tdep->ppc_vsr0_upper_regnum + at*4 + i);
+  }
+  if (save_fpscr)
+    record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+
+  return 0;
+}
+
 /* Parse and record instructions primary opcode-4 at ADDR.
    Return 0 if successful.  */
 
@@ -4170,10 +4234,36 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     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 20:		/* Move To VSR Byte Mask Immediate opcode, ignore
+			   bit 31 */
+    case 21:		/* Move To VSR Byte Mask Immediate opcode, ignore
+			   bit 31 */
+    case 23:		/* Vector Multiply-Sum & write Carry-out Unsigned
+			   Doubleword */
+    case 24:		/* Vector Extract Double Unsigned Byte to VSR
+			   using GPR-specified Left-Index */
+    case 25:		/* Vector Extract Double Unsigned Byte to VSR
+			   using GPR-specified Right-Index */
+    case 26:		/* Vector Extract Double Unsigned Halfword to VSR
+			   using GPR-specified Left-Index */
+    case 27:		/* Vector Extract Double Unsigned Halfword to VSR
+			   using GPR-specified Right-Index */
+    case 28:		/* Vector Extract Double Unsigned Word to VSR
+			   using GPR-specified Left-Index */
+    case 29:		/* Vector Extract Double Unsigned Word to VSR
+			   using GPR-specified Right-Index */
+    case 30:		/* Vector Extract Double Unsigned Doubleword to VSR
+			   using GPR-specified Left-Index */
+    case 31:		/* Vector Extract Double Unsigned Doubleword to VSR
+			   using GPR-specified Right-Index */
     case 42:		/* Vector Select */
     case 43:		/* Vector Permute */
     case 59:		/* Vector Permute Right-indexed */
+    case 22: 		/* Vector Shift
+			      Left  Double by Bit Immediate if insn[21] = 0
+			      Right Double by Bit Immediate if insn[21] = 1 */
     case 44:		/* Vector Shift Left Double by Octet Immediate */
     case 45:		/* Vector Permute and Exclusive-OR */
     case 60:		/* Vector Add Extended Unsigned Quadword Modulo */
@@ -4233,9 +4323,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
-  /* Bit-21 is used for RC */
   switch (ext & 0x3ff)
     {
+    case 5:		/* Vector Rotate Left Quadword */
+    case 69:		/* Vector Rotate Left Quadword then Mask Insert */
+    case 325:		/* Vector Rotate Left Quadword then AND with Mask */
     case 6:		/* Vector Compare Equal To Unsigned Byte */
     case 70:		/* Vector Compare Equal To Unsigned Halfword */
     case 134:		/* Vector Compare Equal To Unsigned Word */
@@ -4244,13 +4336,16 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     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 903:		/* Vector Compare Greater Than Signed Quadword */
     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 647:		/* Vector Compare Greater Than Unsigned Quadword */
     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 455:		/* Vector Compare Equal Quadword */
     case 710:		/* Vector Compare Greater Than Single-Precision */
     case 7:		/* Vector Compare Not Equal Byte */
     case 71:		/* Vector Compare Not Equal Halfword */
@@ -4263,6 +4358,21 @@ 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 13:
+      switch (vra)    /* Bit-21 is used for RC */
+	{
+	case 0:       /* Vector String Isolate Byte Left-justified */
+	case 1:       /* Vector String Isolate Byte Right-justified */
+	case 2:       /* Vector String Isolate Halfword Left-justified */
+	case 3:       /* Vector String Isolate Halfword Right-justified */
+	  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;
+	}
     }
 
   if (ext  == 1538)
@@ -4287,6 +4397,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
 	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 27:	/* Vector Extend Sign Doubleword To Quadword */
 	case 28:	/* Vector Count Trailing Zeros Byte */
 	case 29:	/* Vector Count Trailing Zeros Halfword */
 	case 30:	/* Vector Count Trailing Zeros Word */
@@ -4297,8 +4408,58 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
 	}
     }
 
+  if (ext == 1602)
+    {
+      switch (vra)
+	{
+	case 0: 	/* Vector Expand Byte Mask */
+	case 1: 	/* Vector Expand Halfword Mask */
+	case 2: 	/* Vector Expand Word Mask */
+	case 3: 	/* Vector Expand Doubleword Mask */
+	case 4: 	/* Vector Expand Quadword Mask */
+	case 16:	/* Move to VSR Byte Mask */
+	case 17:	/* Move to VSR Halfword Mask */
+	case 18:	/* Move to VSR Word Mask */
+	case 19:	/* Move to VSR Doubleword Mask */
+	case 20:	/* Move to VSR Quadword Mask */
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+	  return 0;
+
+	case 8: 	/* Vector Extract Byte Mask */
+	case 9: 	/* Vector Extract Halfword Mask */
+	case 10: 	/* Vector Extract Word Mask */
+	case 11: 	/* Vector Extract Doubleword Mask */
+	case 12: 	/* Vector Extract Quadword Mask */
+
+	/* vra field is used as additional opcode field.  Ignore the MP bit in
+	   the LSB position. */
+	case 24:	/* Vector Count Mask Bits Byte */
+	case 25:	/* Vector Count Mask Bits Byte */
+	case 26:	/* Vector Count Mask Bits Halfword */
+	case 27:	/* Vector Count Mask Bits Halfword */
+	case 28:	/* Vector Count Mask Bits Word */
+	case 29:	/* Vector Count Mask Bits Word */
+	case 30:	/* Vector Count Mask Bits Doubleword */
+	case 31:	/* Vector Count Mask Bits Doubleword */
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_gp0_regnum + PPC_RT (insn));
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_gp0_regnum + PPC_RT (insn));
+	  return 0;
+	}
+    }
+
   switch (ext)
     {
+
+    case 257:		/* Vector Compare Unsigned Quadword */
+    case 321:		/* Vector Compare Signed Quadword */
+      /* Comparison tests that always set CR field BF */
+      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;
+
     case 142:		/* Vector Pack Unsigned Halfword Unsigned Saturate */
     case 206:		/* Vector Pack Unsigned Word Unsigned Saturate */
     case 270:		/* Vector Pack Signed Halfword Unsigned Saturate */
@@ -4338,6 +4499,8 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 268:		/* Vector Merge Low Byte */
     case 332:		/* Vector Merge Low Halfword */
     case 396:		/* Vector Merge Low Word */
+    case 397:		/* Vector Clear Leftmost Bytes */
+    case 461:		/* Vector Clear Rightmost Bytes */
     case 526:		/* Vector Unpack High Signed Byte */
     case 590:		/* Vector Unpack High Signed Halfword */
     case 654:		/* Vector Unpack Low Signed Byte */
@@ -4356,8 +4519,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 780:		/* Vector Splat Immediate Signed Byte */
     case 844:		/* Vector Splat Immediate Signed Halfword */
     case 908:		/* Vector Splat Immediate Signed Word */
+    case 261:		/* Vector Shift Left Quadword */
     case 452:		/* Vector Shift Left */
+    case 517:		/* Vector Shift Right Quadword */
     case 708:		/* Vector Shift Right */
+    case 773:		/* Vector Shift Right Algebraic Quadword */
     case 1036:		/* Vector Shift Left by Octet */
     case 1100:		/* Vector Shift Right by Octet */
     case 0:		/* Vector Add Unsigned Byte Modulo */
@@ -4370,15 +4536,43 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 8:		/* Vector Multiply Odd Unsigned Byte */
     case 72:		/* Vector Multiply Odd Unsigned Halfword */
     case 136:		/* Vector Multiply Odd Unsigned Word */
+    case 200:		/* Vector Multiply Odd Unsigned Doubleword */
     case 264:		/* Vector Multiply Odd Signed Byte */
     case 328:		/* Vector Multiply Odd Signed Halfword */
     case 392:		/* Vector Multiply Odd Signed Word */
+    case 456:		/* Vector Multiply Odd Signed Doubleword */
     case 520:		/* Vector Multiply Even Unsigned Byte */
     case 584:		/* Vector Multiply Even Unsigned Halfword */
     case 648:		/* Vector Multiply Even Unsigned Word */
+    case 712:		/* Vector Multiply Even Unsigned Doubleword */
     case 776:		/* Vector Multiply Even Signed Byte */
     case 840:		/* Vector Multiply Even Signed Halfword */
     case 904:		/* Vector Multiply Even Signed Word */
+    case 968:		/* Vector Multiply Even Signed Doubleword */
+    case 457:		/* Vector Multiply Low Doubleword */
+    case 649:		/* Vector Multiply High Unsigned Word */
+    case 713:		/* Vector Multiply High Unsigned Doubleword */
+    case 905:		/* Vector Multiply High Signed Word */
+    case 969:		/* Vector Multiply High Signed Doubleword */
+    case 11:		/* Vector Divide Unsigned Quadword */
+    case 203:		/* Vector Divide Unsigned Doubleword */
+    case 139:		/* Vector Divide Unsigned Word */
+    case 267:		/* Vector Divide Signed Quadword */
+    case 459:		/* Vector Divide Signed Doubleword */
+    case 395:		/* Vector Divide Signed Word */
+    case 523:		/* Vector Divide Extended Unsigned Quadword */
+    case 715:		/* Vector Divide Extended Unsigned Doubleword */
+    case 651:		/* Vector Divide Extended Unsigned Word */
+    case 779:		/* Vector Divide Extended Signed Quadword */
+    case 971:		/* Vector Divide Extended Signed Doubleword */
+    case 907:		/* Vector Divide Extended Unsigned Word */
+    case 1547:		/* Vector Modulo Unsigned Quadword */
+    case 1675:		/* Vector Modulo Unsigned Word */
+    case 1739:		/* Vector Modulo Unsigned Doubleword */
+    case 1803:		/* Vector Modulo Signed Quadword */
+    case 1931:		/* Vector Modulo Signed Word */
+    case 1995:		/* Vector Modulo Signed Doubleword */
+
     case 137:		/* Vector Multiply Unsigned Word Modulo */
     case 1024:		/* Vector Subtract Unsigned Byte Modulo */
     case 1088:		/* Vector Subtract Unsigned Halfword Modulo */
@@ -4462,7 +4656,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 1794:		/* Vector Count Leading Zeros Byte */
     case 1858:		/* Vector Count Leading Zeros Halfword */
     case 1922:		/* Vector Count Leading Zeros Word */
+    case 1924:		/* Vector Count Leading Zeros Doubleword under
+			   bit Mask*/
     case 1986:		/* Vector Count Leading Zeros Doubleword */
+    case 1988:		/* Vector Count Trailing Zeros Doubleword under bit
+			   Mask */
     case 1795:		/* Vector Population Count Byte */
     case 1859:		/* Vector Population Count Halfword */
     case 1923:		/* Vector Population Count Word */
@@ -4488,14 +4686,50 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 589:		/* Vector Extract Unsigned Halfword */
     case 653:		/* Vector Extract Unsigned Word */
     case 717:		/* Vector Extract Doubleword */
+    case 15:		/* Vector Insert Byte from VSR using GPR-specified
+			   Left-Index */
+    case 79:		/* Vector Insert Halfword from VSR using GPR-specified
+			   Left-Index */
+    case 143:		/* Vector Insert Word from VSR using GPR-specified
+			   Left-Index */
+    case 207:		/* Vector Insert Word from GPR using
+			   immediate-specified index */
+    case 463:		/* Vector Insert Doubleword from GPR using
+			   immediate-specified index */
+    case 271:		/* Vector Insert Byte from VSR using GPR-specified
+			   Right-Index */
+    case 335:		/* Vector Insert Halfword from VSR using GPR-specified
+			   Right-Index */
+    case 399:		/* Vector Insert Word from VSR using GPR-specified
+			   Right-Index */
+    case 527:		/* Vector Insert Byte from GPR using GPR-specified
+			   Left-Index */
+    case 591:		/* Vector Insert Halfword from GPR using GPR-specified
+			   Left-Index */
+    case 655:		/* Vector Insert Word from GPR using GPR-specified
+			   Left-Index */
+    case 719:		/* Vector Insert Doubleword from GPR using
+			    GPR-specified Left-Index */
+    case 783:		/* Vector Insert Byte from GPR using GPR-specified
+			   Right-Index */
+    case 847:		/* Vector Insert Halfword from GPR using GPR-specified
+			   Left-Index */
+    case 911:		/* Vector Insert Word from GPR using GPR-specified
+			   Left-Index */
+    case 975:		/* Vector Insert Doubleword from GPR using
+			    GPR-specified Right-Index */
     case 781:		/* Vector Insert Byte */
     case 845:		/* Vector Insert Halfword */
     case 909:		/* Vector Insert Word */
     case 973:		/* Vector Insert Doubleword */
+    case 1357:		/* Vector Centrifuge Doubleword */
+    case 1421:		/* Vector Parallel Bits Extract Doubleword */
+    case 1485:		/* Vector Parallel Bits Deposit Doubleword */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
       return 0;
 
+    case 1228:		/* Vector Gather every Nth Bit */
     case 1549:		/* Vector Extract Unsigned Byte Left-Indexed */
     case 1613:		/* Vector Extract Unsigned Halfword Left-Indexed */
     case 1677:		/* Vector Extract Unsigned Word Left-Indexed */
@@ -4528,6 +4762,31 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
 /* Parse and record instructions of primary opcode-19 at ADDR.
    Return 0 if successful.  */
 
+static int
+ppc_process_record_op6 (struct gdbarch *gdbarch, struct regcache *regcache,
+			CORE_ADDR addr, uint32_t insn)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int subtype = PPC_FIELD (insn, 28, 4);
+  CORE_ADDR ea = 0;
+
+  switch (subtype)
+    {
+    case 0:    /* Load VSX Vector Paired */
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
+      return 0;
+    case 1:    /* Store VSX Vector Paired */
+      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, 32);
+      return 0;
+    }
+  return -1;
+}
+
 static int
 ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
 			   CORE_ADDR addr, uint32_t insn)
@@ -4580,13 +4839,33 @@ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
 /* Parse and record instructions of primary opcode-31 at ADDR.
    Return 0 if successful.  */
 
+static int
+ppc_process_record_op31_177 (struct gdbarch *gdbarch,
+			     struct regcache *regcache,
+			     uint32_t insn)
+{
+  int RA_opcode = PPC_RA(insn);
+  int as = PPC_FIELD (insn, 6, 3);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  switch (RA_opcode)
+    {
+    case 0: 		/* VSX Move From Accumulator, xxmfacc */
+    case 1: 		/* VSX Move To Accumulator, xxmtacc */
+    case 3: 		/* VSX Set Accumulator to Zero, xxsetaccz */
+      ppc_record_ACC_fpscr (regcache, tdep, as, DO_NOT_RECORD_FPSCR);
+      return 0;
+    }
+  return -1;
+}
+
 static int
 ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 			   CORE_ADDR addr, uint32_t insn)
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
-  int tmp, nr, nb, i;
+  int tmp, nr, nb = 0, i;
   CORE_ADDR at_dcsz, ea = 0;
   ULONGEST rb, ra, xer;
   int size = 0;
@@ -4677,6 +4956,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 371:		/* Move From Time Base [Phased-Out]  */
     case 309:		/* Load Doubleword Monitored Indexed  */
     case 128:		/* Set Boolean */
+    case 384:		/* Set Boolean Condition */
+    case 416:		/* Set Boolean Condition Reverse */
+    case 448:		/* Set Negative Boolean Condition */
+    case 480:		/* Set Negative Boolean Condition Reverse */
     case 755:		/* Deliver A Random Number */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_gp0_regnum + PPC_RT (insn));
@@ -4684,8 +4967,15 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 
     /* These only write to RA.  */
     case 51:		/* Move From VSR Doubleword */
+    case 59:		/* Count Leading Zeros Doubleword under bit Mask */
     case 115:		/* Move From VSR Word and Zero */
     case 122:		/* Population count bytes */
+    case 155:		/* Byte-Reverse Word */
+    case 156:		/* Parallel Bits Deposit Doubleword */
+    case 187:		/* Byte-Reverse Doubleword */
+    case 188:		/* Parallel Bits Extract Doubleword */
+    case 219:		/* Byte-Reverse Halfword */
+    case 220:		/* Centrifuge Doubleword */
     case 378:		/* Population count words */
     case 506:		/* Population count doublewords */
     case 154:		/* Parity Word */
@@ -4695,6 +4985,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 314:		/* Convert Binary Coded Decimal To Declets */
     case 508:		/* Compare bytes */
     case 307:		/* Move From VSR Lower Doubleword */
+    case 571:		/* Count Trailing Zeros Doubleword under bit Mask */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_gp0_regnum + PPC_RA (insn));
       return 0;
@@ -4819,6 +5110,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache, tmp + 1);
       return 0;
 
+    /* These write RT. */
     case 179:		/* Move To VSR Doubleword */
     case 211:		/* Move To VSR Word Algebraic */
     case 243:		/* Move To VSR Word and Zero */
@@ -4826,6 +5118,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     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 13:		/* Load VSX Vector Rightmost Byte Indexed */
+    case 45:		/* Load VSX Vector Rightmost Halfword Indexed */
+    case 77:		/* Load VSX Vector Rightmost Word Indexed */
+    case 109:		/* Load VSX Vector Rightmost Doubleword 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 */
@@ -4842,6 +5138,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
 
+    case 333:		/* Load VSX Vector Paired Indexed */
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
+      return 0;
+
     /* These write RA.  Update CR if RC is set.  */
     case 24:		/* Shift Left Word */
     case 26:		/* Count Leading Zeros Word */
@@ -5006,6 +5307,31 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_mem (ea, size);
       return 0;
 
+    case 141:		/* Store VSX Vector Rightmost Byte Indexed */
+    case 173:		/* Store VSX Vector Rightmost Halfword Indexed */
+    case 205:		/* Store VSX Vector Rightmost Word Indexed */
+    case 237:		/* Store VSX Vector Rightmost Doubleword Indexed */
+      switch(ext)
+	{
+	  case 141: nb = 1;
+	  break;
+	  case 173: nb = 2;
+	  break;
+	  case 205: nb = 4;
+	  break;
+	  case 237: nb = 8;
+	  break;
+	}
+      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;
+      record_full_arch_list_add_mem (ea, nb);
+      return 0;
+
     case 397:		/* Store VSX Vector with Length */
     case 429:		/* Store VSX Vector Left-justified with Length */
       ra = 0;
@@ -5021,6 +5347,19 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 	record_full_arch_list_add_mem (ea, nb);
       return 0;
 
+    case 461:		/* Store VSX Vector Paired Indexed */
+      {
+	if (PPC_RA (insn) != 0)
+	  regcache_raw_read_unsigned (regcache,
+				      tdep->ppc_gp0_regnum
+				      + PPC_RA (insn), &ea);
+	regcache_raw_read_unsigned (regcache,
+				    tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
+	ea += rb;
+	record_full_arch_list_add_mem (ea, 32);
+	return 0;
+      }
+
     case 710:		/* Store Word Atomic */
     case 742:		/* Store Doubleword Atomic */
       ra = 0;
@@ -5166,6 +5505,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       ea = (ra + rb) & ~((ULONGEST) (at_dcsz - 1));
       record_full_arch_list_add_mem (ea, at_dcsz);
       return 0;
+
+    case 177:
+      if (ppc_process_record_op31_177 (gdbarch, regcache, insn) == 0)
+	return 0;
     }
 
 UNKNOWN_OP:
@@ -5174,15 +5517,13 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
-/* Parse and record instructions of primary opcode-59 at ADDR.
-   Return 0 if successful.  */
-
 static int
 ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
 			   CORE_ADDR addr, uint32_t insn)
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
+  int at = PPC_FIELD (insn, 6, 3);
 
   switch (ext & 0x1f)
     {
@@ -5206,6 +5547,75 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
+  /* MMA instructions, if no match keep looking.  */
+  switch (ext >> 2)    /* Additioanl opcode field is upper 8-bits of ext */
+    {
+    case 3:	/* VSX Vector 8-bit Signed/Unsigned Integer GER, xvi8ger4 */
+    case 2:	/* VSX Vector 8-bit Signed/Unsigned Integer GER Positive
+		   multiply, Positive accumulate, xvi8ger4pp */
+
+    case 99:	/* VSX Vector 8-bit Signed/Unsigned Integer GER with
+		   Saturate Positive multiply, Positive accumulate,
+		   xvi8ger4spp */
+
+    case 35:	/* VSX Vector 4-bit Signed Integer GER, xvi4ger8 */
+    case 34:	/* VSX Vector 4-bit Signed Integer GER Positive multiply,
+		   Positive accumulate, xvi4ger8pp */
+
+    case 75:	/* VSX Vector 16-bit Signed Integer GER, xvi16ger2 */
+    case 107:	/* VSX Vector 16-bit Signed Integer GER  Positive multiply,
+		   Positive accumulate, xvi16ger2pp */
+
+    case 43:	/* VSX Vector 16-bit Signed Integer GER with Saturation,
+		   xvi16ger2s */
+    case 42:	/* VSX Vector 16-bit Signed Integer GER with Saturation
+		   Positive multiply, Positive accumulate, xvi16ger2spp */
+      ppc_record_ACC_fpscr (regcache, tdep, at, DO_NOT_RECORD_FPSCR);
+      return 0;
+
+    case 19:	/* VSX Vector 16-bit Floating-Point GER, xvf16ger2 */
+    case 18:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf16ger2pp */
+    case 146:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf16ger2pn */
+    case 82:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf16ger2np */
+    case 210:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
+		   Negative accumulate, xvf16ger2nn */
+
+    case 27:	/* VSX Vector 32-bit Floating-Point GER, xvf32ger */
+    case 26:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf32gerpp */
+    case 154:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf32gerpn */
+    case 90:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf32gernp */
+    case 218:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
+		   Negative accumulate, xvf32gernn */
+
+    case 59:	/* VSX Vector 64-bit Floating-Point GER */
+    case 58:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf64gerpp */
+    case 186:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf64gerpn */
+    case 122:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf64gernp */
+    case 250:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
+		   Negative accumulate */
+
+    case 51:	/* VSX Vector bfloat16 GER, xvbf16ger2 */
+    case 50:	/* VSX Vector bfloat16 GER Positive multiply,
+		   Positive accumulate, xvbf16ger2pp */
+    case 178:	/* VSX Vector bfloat16 GER Positive multiply,
+		   Negative accumulate, xvbf16ger2pn */
+    case 114:	/* VSX Vector bfloat16 GER Negative multiply,
+		   Positive accumulate, xvbf16ger2np */
+    case 242:	/* VSX Vector bfloat16 GER Negative multiply,
+		   Negative accumulate, xvbf16ger2nn */
+      ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
+      return 0;
+    }
+
   switch (ext)
     {
     case 2:		/* DFP Add */
@@ -5271,6 +5681,45 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
 /* Parse and record instructions of primary opcode-60 at ADDR.
    Return 0 if successful.  */
 
+static int
+ppc_process_record_op60_XX2 (struct gdbarch *gdbarch,
+			     struct regcache *regcache,
+			     CORE_ADDR addr, uint32_t insn)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int RA_opcode = PPC_RA(insn);
+
+  switch (RA_opcode)
+    {
+    case 2:	/* VSX Vector Test Least-Significant Bit by Byte */
+    case 25:	/* VSX Vector round and Convert Single-Precision format
+		   to Half-Precision format.  Only changes the CR
+		   field.  */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+    case 17:	/* VSX Vector Convert with round Single-Precision
+		   to bfloat16 format */
+    case 24:	/* VSX Vector Convert Half-Precision format to
+		   Single-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 16:	/* VSX Vector Convert bfloat16 to Single-Precision
+		   format Non-signaling */
+    case 23:	/* VSX Vector Byte-Reverse Doubleword */
+    case 31:	/* VSX Vector Byte-Reverse Quadword */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
+    }
+
+  return -1;
+}
+
 static int
 ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
 			   CORE_ADDR addr, uint32_t insn)
@@ -5583,37 +6032,30 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
       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;
+      if (ppc_process_record_op60_XX2 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      return 0;
     }
 
   switch (ext)
     {
-    case 360:		/* VSX Vector Splat Immediate Byte */
-      if (PPC_FIELD (insn, 11, 2) == 0)
+    case 360:
+      if (PPC_FIELD (insn, 11, 2) == 0)  /* VSX Vector Splat Immediate Byte */
+	{
+	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+	  return 0;
+	}
+      if (PPC_FIELD (insn, 11, 5) == 31)  /* Load VSX Vector Special Value
+					     Quadword */
 	{
 	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
 	  return 0;
 	}
       break;
+    case 916:		/* VSX Vector Generate PCV from Byte Mask */
+    case 917:		/* VSX Vector Generate PCV from Halfword Mask */
+    case 948:		/* VSX Vector Generate PCV from Word Mask */
+    case 949:		/* VSX Vector Generate PCV from Word Mask */
     case 918:		/* VSX Scalar Insert Exponent Double-Precision */
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
@@ -5894,6 +6336,35 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
 			   Quad-Precision */
     case 516:		/* VSX Scalar Subtract Quad-Precision */
     case 548:		/* VSX Scalar Divide Quad-Precision */
+    case 994:
+      {
+      switch (PPC_FIELD (insn, 11, 5))
+	{
+	case 0:	/* DFP Convert From Fixed Quadword Quad */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_fp0_regnum
+					 + PPC_FRT (insn));
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_fp0_regnum
+					 + PPC_FRT (insn) + 1);
+	  return 0;
+	case 1:	/* DFP Convert To Fixed Quadword Quad */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+	  return 0;
+	}
+      }
+
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
+    case 68:		/* VSX Scalar Compare Equal Quad-Precision */
+    case 196:		/* VSX Scalar Compare Greater Than or Equal
+			   Quad-Precision */
+    case 228:		/* VSX Scalar Compare Greater Than Quad-Precision */
+    case 676:		/* VSX Scalar Maximum Type-C Quad-Precision */
+    case 740:		/* VSX Scalar Minimum Type-C Quad-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       /* FALL-THROUGH */
     case 100:		/* VSX Scalar Copy Sign Quad-Precision */
@@ -5920,14 +6391,22 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 836:
       switch (PPC_FIELD (insn, 11, 5))
 	{
+	case 0:		/* VSX Scalar Convert with round to zero
+			   Quad-Precision to Unsigned Quadword  */
 	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 3:		/* VSX Scalar Convert with round
+			   Unsigned Quadword to Quad-Precision  */
+	case 8:		/* VSX Scalar Convert with round to zero
+			   Quad-Precision to Signed Quadword  */
 	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 11:	/* VSX Scalar Convert with round
+			   Signed Quadword to Quad-Precision */
 	case 17:	/* VSX Scalar truncate & Convert Quad-Precision format
 			   to Unsigned Doubleword format */
 	case 20:	/* VSX Scalar round & Convert Quad-Precision format to
@@ -5947,24 +6426,594 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+static int
+ppc_process_record_prefix_op42 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				CORE_ADDR addr, uint32_t insn_prefix,
+				uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if (ST1 != 0)
+    return -1;
+
+  switch (type)
+    {
+    case 0:  /* Prefixed Load VSX Scalar Doubleword, plxsd */
+      ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
+      break;
+    case 2:  /* Prefixed Load Halfword Algebraic, plha */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum
+				     + PPC_RT (insn_suffix));
+      break;
+    default:
+      return -1;
+    }
+  return 0;
+}
+
+static int
+ppc_process_record_prefix_op59_XX3 (struct gdbarch *gdbarch,
+				    struct regcache *regcache,
+				    uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int opcode = PPC_FIELD (insn_suffix, 21, 8);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  int at = PPC_FIELD (insn_suffix, 6, 3);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 3) {
+    if (ST4 == 9)
+      switch (opcode)
+	{
+	case 35:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
+			   MMIRR, pmxvi4ger8 */
+	case 34:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
+			   MMIRR, pmxvi4ger8pp */
+
+	case 99:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER with Saturate Positive multiply,
+			   Positive accumulate, xvi8ger4spp */
+
+	case 3:		/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER MMIRR, pmxvi8ger4 */
+	case 2:		/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER Positive multiply, Positive accumulate
+			   MMIRR, pmxvi8ger4pp */
+
+	case 75:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER MMIRR, pmxvi16ger2 */
+	case 107:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER  Positive multiply, Positive accumulate,
+			   pmxvi16ger2pp */
+
+	case 43:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER with Saturation MMIRR, pmxvi16ger2s */
+	case 42:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER with Saturation Positive multiply, Positive
+			   accumulate MMIRR, pmxvi16ger2spp */
+	  ppc_record_ACC_fpscr (regcache, tdep, at, DO_NOT_RECORD_FPSCR);
+	  return 0;
+
+	case 19:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER MMIRR, pmxvf16ger2 */
+	case 18:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Positive multiply, Positive accumulate MMIRR,
+			   pmxvf16ger2pp */
+	case 146:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf16ger2pn */
+	case 82:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf16ger2np */
+	case 210:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf16ger2nn */
+
+	case 27:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER MMIRR, pmxvf32ger */
+	case 26:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Positive multiply, Positive accumulate MMIRR,
+			   pmxvf32gerpp */
+	case 154:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf32gerpn */
+	case 90:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf32gernp */
+	case 218:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf32gernn */
+
+	case 59:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER MMIRR, pmxvf64ger */
+	case 58:	/* Floating-Point GER Positive multiply, Positive
+			   accumulate MMIRR, pmxvf64gerpp */
+	case 186:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf64gerpn */
+	case 122:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf64gernp */
+	case 250:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf64gernn */
+
+	case 51:	/* Prefixed Masked VSX Vector bfloat16 GER MMIRR,
+			   pmxvbf16ger2 */
+	case 50:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
+			   multiply, Positive accumulate MMIRR,
+			   pmxvbf16ger2pp */
+	case 178:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
+			   multiply, Negative accumulate MMIRR,
+			   pmxvbf16ger2pn */
+	case 114:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
+			   multiply, Positive accumulate MMIRR,
+			   pmxvbf16ger2np */
+	case 242:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
+			   multiply, Negative accumulate MMIRR,
+			   pmxvbf16ger2nn */
+	  ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
+	  return 0;
+	}
+  } else
+    return -1;
+
+  return 0;
+}
+
+static int
+ppc_process_record_prefix_store (struct gdbarch *gdbarch,
+				 struct regcache *regcache,
+				 CORE_ADDR addr, uint32_t insn_prefix,
+				 uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST iaddr = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int op6 = PPC_OP6 (insn_suffix);
+
+  if (R == 0) {
+    if (PPC_RA (insn_suffix) != 0)
+      regcache_raw_read_unsigned (regcache, tdep->ppc_gp0_regnum
+				  + PPC_RA (insn_suffix), &iaddr);
+  } else {
+    iaddr = addr;     /* PC relative */
+  }
+
+  switch (op6)
+    {
+    case 38:
+      size =  1;    /* store byte, pstb */
+      break;
+    case 44:
+      size =  2;    /* store halfword, psth */
+      break;
+    case 36:
+    case 52:
+      size =  4;    /* store word, pstw, pstfs */
+      break;
+    case 54:
+    case 61:
+      size =  8;    /* store double word, pstd, pstfd */
+      break;
+    case 60:
+      size = 16;    /* store quadword, pstq */
+      break;
+    default: return -1;
+    }
+
+  iaddr += P_PPC_D (insn_prefix, insn_suffix);
+  record_full_arch_list_add_mem (iaddr, size);
+  return 0;
+}
+
+static int
+ppc_process_record_prefix_op32 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				CORE_ADDR addr, uint32_t insn_prefix,
+				uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1) {
+    if (ST4 == 0) {
+      switch (PPC_FIELD (insn_suffix, 11, 3))
+	{
+	case 0:  	/* VSX Vector Splat Immediate Word 8RR, xxsplti32dx */
+	  ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
+	  return 0;
+	}
+
+      switch (PPC_FIELD (insn_suffix, 11, 4))
+	{
+	case 2:  	/* VSX Vector Splat Immediate Double-Precision
+			   8RR, xxspltidp */
+	case 3:  	/* VSX Vector Splat Immediate Word 8RR, xxspltiw */
+	  ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
+	  return 0;
+	default:
+	  return -1;
+	}
+    } else
+      return -1;
+
+  } else if (type == 2) {
+    if (ST1 == 0)  		/* Prefixed Load Word and Zero, plwz */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum
+				     + PPC_RT (insn_suffix));
+    else
+      return -1;
+
+  } else
+    return -1;
+  return 0;
+}
+
+static int
+ppc_process_record_prefix_op33 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				CORE_ADDR addr, uint32_t insn_prefix,
+				uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1) {
+    if (ST4 == 0)
+      switch (PPC_FIELD (insn_suffix, 26, 2))
+	{
+	case 0:  	/* VSX Vector Blend Variable Byte 8RR, xxblendvb */
+	case 1:  	/* VSX Vector Blend Variable Halfword, xxblendvh */
+	case 2:  	/* VSX Vector Blend Variable Word, xxblendvw */
+	case 3:  	/* VSX Vector Blend Variable Doubleword, xxblendvd */
+	  ppc_record_vsr (regcache, tdep, PPC_XT (insn_suffix));
+	  break;
+	default:
+	    return -1;
+	}
+    else
+      return -1;
+
+  } else
+    return -1;
+
+  return 0;
+}
+
+static int
+ppc_process_record_prefix_op34 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				CORE_ADDR addr, uint32_t insn_prefix,
+				uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1) {
+    if (ST4 == 0)
+      switch (PPC_FIELD (insn_suffix, 26, 2))
+	{
+	case 0:  	/* VSX Vector Permute Extended 8RR, xxpermx */
+	case 1:  	/* VSX Vector Evaluate 8RR, xxeval */
+	  ppc_record_vsr (regcache, tdep, P_PPC_XT (insn_suffix));
+	  break;
+	default:
+	    return -1;
+	}
+    else
+      return -1;
+
+  } else if (type == 2) {
+    if (ST1 == 0)  		/* Prefixed Load Word and Zero, plbz */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum
+				     + PPC_RT (insn_suffix));
+    else
+      return -1;
+
+  } else
+    return -1;
+  return 0;
+}
+
+static int
+ppc_process_record_prefix_store_vsx_ds_form (struct gdbarch *gdbarch,
+					     struct regcache *regcache,
+					     CORE_ADDR addr,
+					     uint32_t insn_prefix,
+					     uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST ea = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if ((type == 0) && (ST1 == 0)) {
+    if (R == 0) {
+      if (PPC_RA (insn_suffix) != 0)
+	regcache_raw_read_unsigned (regcache,
+				    tdep->ppc_gp0_regnum
+				    + PPC_RA (insn_suffix),
+				    &ea);
+    } else {
+      ea = addr;     /* PC relative */
+    }
+
+    ea += P_PPC_D (insn_prefix, insn_suffix);
+    switch (PPC_FIELD (insn_suffix, 0, 6))
+      {
+      case 46:    /* Prefixed Store VSX Scalar Doubleword, pstxsd */
+	size = 8;
+	break;
+      case 47:    /* Prefixed,Store VSX Scalar Single-Precision, pstxssp */
+	size = 4;
+	break;
+      default:
+	return -1;
+      }
+    record_full_arch_list_add_mem (ea, size);
+    return 0;
+
+  } else
+    return -1;
+}
+
+static int
+ppc_process_record_prefix_vsx_d_form (struct gdbarch *gdbarch,
+				      struct regcache *regcache,
+				      CORE_ADDR addr,
+				      uint32_t insn_prefix,
+				      uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST ea = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if ((type == 0) && (ST1 == 0)) {
+    switch (PPC_FIELD (insn_suffix, 0, 5))
+      {
+      case 25:	/* Prefixed Load VSX Vector, plxv */
+	ppc_record_vsr (regcache, tdep, P_PPC_XT5 (insn_prefix));
+	return 0;
+      case 27:	/* Prefixed Store VSX Vector 8LS, pstxv */
+	{
+	  size = 16;
+	  if (R == 0) {
+	    if (PPC_RA (insn_suffix) != 0)
+	      regcache_raw_read_unsigned (regcache,
+					  tdep->ppc_gp0_regnum
+					  + PPC_RA (insn_suffix),
+					  &ea);
+	  } else {
+	    ea = addr;     /* PC relative */
+	  }
+
+	  ea += P_PPC_D (insn_prefix, insn_suffix);
+	  record_full_arch_list_add_mem (ea, size);
+	  return 0;
+	}
+      }
+    return -1;
+  } else
+    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.  */
 
+static int
+ppc_process_prefix_instruction (int insn_prefix, int insn_suffix,
+				CORE_ADDR addr,	struct gdbarch *gdbarch,
+				struct regcache *regcache)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int op6;
+
+  /* D-form has uses a 5-bit opcode in the instruction suffix */
+  if (ppc_process_record_prefix_vsx_d_form ( gdbarch, regcache, addr,
+					     insn_prefix, insn_suffix) == 0)
+    goto SUCCESS;
+
+  op6 = PPC_OP6 (insn_suffix);  /* 6-bit opcode in the instruction suffix */
+
+  switch (op6)
+    {
+    case 14:		/* Prefixed Add Immediate, paddi */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 32:
+      if (ppc_process_record_prefix_op32 (gdbarch, regcache, addr,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 33:
+      if (ppc_process_record_prefix_op33 (gdbarch, regcache, addr,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 34:		/* Prefixed Load Byte and Zero, plbz */
+      if (ppc_process_record_prefix_op34 (gdbarch, regcache, addr,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+    case 40:		/* Prefixed Load Halfword and Zero, plhz */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+      break;
+
+    case 36:		/* Prefixed Store Word, pstw */
+    case 38:		/* Prefixed Store Byte, pstb */
+    case 44:		/* Prefixed Store Halfword, psth */
+    case 52:		/* Prefixed Store Floating-Point Single, pstfs */
+    case 54:		/* Prefixed Store Floating-Point Double, pstfd */
+    case 60:		/* Prefixed Store Quadword, pstq */
+    case 61:		/* Prefixed Store Doubleword, pstd */
+      if (ppc_process_record_prefix_store (gdbarch, regcache, addr,
+					   insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 42:
+      if (ppc_process_record_prefix_op42 (gdbarch, regcache, addr,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 43:          /* Prefixed Load VSX Scalar Single-Precision, plxssp */
+      if ((type == 0) && (ST1 == 0))
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
+      else
+	  goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 46:
+    case 47:
+      if (ppc_process_record_prefix_store_vsx_ds_form (gdbarch, regcache, addr,
+					       insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 56:		/* Prefixed Load Quadword, plq */
+      {
+	if ((type == 0) && (ST1 == 0)) {
+	  int tmp;
+	  tmp = tdep->ppc_gp0_regnum + (PPC_RT (insn_suffix) & ~1);
+	  record_full_arch_list_add_reg (regcache, tmp);
+	  record_full_arch_list_add_reg (regcache, tmp + 1);
+	} else
+	    goto UNKNOWN_PREFIX_OP;
+	break;
+      }
+
+    case 41:		/* Prefixed Load Word Algebraic, plwa */
+    case 57:  		/* Prefixed Load Doubleword, pld */
+      if ((type == 0) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	    goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 48:		/* Prefixed Load Floating-Point Single, plfs */
+    case 50:		/* Prefixed Load Floating-Point Double, plfd */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_fp0_regnum
+				       + PPC_FRT (insn_suffix));
+      else
+	    goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 58:		/* Prefixed Load VSX Vector Paired, plxvp */
+      if ((type == 0) && (ST1 == 0)) {
+	ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix));
+	ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix) + 1);
+      } else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 59:
+      if (ppc_process_record_prefix_op59_XX3 (gdbarch, regcache, insn_prefix,
+					      insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 62:	    /* Prefixed Store VSX Vector Paired 8LS, pstxvp */
+      if ((type == 0) && (ST1 == 0)) {
+	int R = PPC_BIT (insn_prefix, 11);
+	CORE_ADDR ea = 0;
+
+	if (R == 0) {
+	  if (PPC_RA (insn_suffix) != 0)
+	    regcache_raw_read_unsigned (regcache,
+					tdep->ppc_gp0_regnum
+					+ PPC_RA (insn_suffix), &ea);
+	} else {
+	  ea = addr;     /* PC relative */
+	}
+
+	ea += P_PPC_D (insn_prefix, insn_suffix) << 4;
+	record_full_arch_list_add_mem (ea, 32);
+      } else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    default:
+    UNKNOWN_PREFIX_OP:
+      fprintf_unfiltered (gdb_stdlog,
+			  "Warning: Don't know how to record prefix inst "
+			  "%08x %08x at %s, %d.\n",
+			  insn_prefix, insn_suffix, paddress (gdbarch, addr),
+			  op6);
+      return -1;
+    }
+
+ SUCCESS:
+  if (record_full_arch_list_add_reg (regcache, PPC_PC_REGNUM))
+    return -1;
+
+  if (record_full_arch_list_add_end ())
+    return -1;
+  return 0;
+}
+
 int
 ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 		      CORE_ADDR addr)
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  uint32_t insn;
+  uint32_t insn, insn_suffix;
   int op6, tmp, i;
 
   insn = read_memory_unsigned_integer (addr, 4, byte_order);
+
   op6 = PPC_OP6 (insn);
 
   switch (op6)
     {
+    case 1:		/* prefixed instruction */
+      {
+	/* Get the lower 32-bits of the prefixed instruction. */
+	insn_suffix = read_memory_unsigned_integer (addr+4, 4, byte_order);
+	return ppc_process_prefix_instruction (insn, insn_suffix, addr,
+					       gdbarch, regcache);
+      }
     case 2:		/* Trap Doubleword Immediate */
     case 3:		/* Trap Word Immediate */
       /* Do nothing.  */
@@ -5975,6 +7024,11 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 	return -1;
       break;
 
+    case 6:
+      if (ppc_process_record_op6 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      break;
+
     case 17:		/* System call */
       if (PPC_LEV (insn) != 0)
 	goto UNKNOWN_OP;
-- 
2.32.0



^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 2/2] Add recording support for the ISA 3.1 Powerpc instructions
  2022-03-04 19:46 [PATCH 0/2] Add recording support for the ISA 3.1 Powerpc instructions Carl Love
  2022-03-04 19:52 ` [PATCH 1/2] " Carl Love
@ 2022-03-04 19:53 ` Carl Love
  2022-03-06 12:42   ` Joel Brobecker
  2022-04-12 17:09 ` [PATCH 0/2 Version 2] " Carl Love
  2 siblings, 1 reply; 25+ messages in thread
From: Carl Love @ 2022-03-04 19:53 UTC (permalink / raw)
  To: gdb-patches, Ulrich Weigand; +Cc: Will Schmidt, Tulio Magno, Rogerio Alves, cel


GDB maintainers:

The patch adds the gdb recording test cases for the Powerpc ISA 2.06
and ISA 3.1 instruction sets.

The patch has been run on both Power 10 and Power 9 to verify the ISA
2.06 test case runs on both platforms without errors.  The ISA 3.1 test
runs without errors on Power 10 and is skipped as expected on Power 9.

Please let me know if this patch is acceptable for gdb mainline. 
Thanks.

                       Carl Love


---------------------------------------------------------------

GDB Powerpc record test cases for ISA 2.06 and ISA 3.1

This patch adds Powerpc specific tests to verify recording of various
instructions.  The first test case checks a couple of ISA 2.06
instructions.
The second test case tests several of the ISA 3.01
instructions.  Specifically,
it checks the word and prefixed instructions and some of the Matrix
Multiply Assist (MMA) instructions.
---
 .../gdb.reverse/ppc_record_test_isa_2_06.c    |  49 ++
 .../gdb.reverse/ppc_record_test_isa_2_06.exp  | 137 +++++
 .../gdb.reverse/ppc_record_test_isa_3_1.c     |  83 +++
 .../gdb.reverse/ppc_record_test_isa_3_1.exp   | 497 ++++++++++++++++++
 4 files changed, 766 insertions(+)
 create mode 100644
gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
 create mode 100644
gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
 create mode 100644
gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp

diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
new file mode 100644
index 00000000000..a5df3d13056
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
@@ -0,0 +1,49 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or
modify
+   it under the terms of the GNU General Public License as published
by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <
http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <ctype.h>     // isspace
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>    // getopt
+#include <altivec.h> // vector
+
+
+/* globals used for vector tests */
+static vector unsigned long vec_xa, vec_xb, vec_xt;
+static unsigned long ra, rb, rs;
+
+int main () {
+
+  ra = 0xABCDEF012;
+  rb = 0;
+  rs = 0x012345678;
+
+  /* 9.0, 16.0, 25.0, 36.0 */
+  vec_xb = (vector unsigned long){0x4110000041800000,
0x41c8000042100000};
+
+  vec_xt = (vector unsigned long){0xFF00FF00FF00FF00,
0xAA00AA00AA00AA00};
+
+  /* Test 1 ISA 2.06 instructions.  Load source into vs1, result of
sqrt
+     put into vs0.  */
+  ra = (unsigned long) & vec_xb;        /* stop 1 */
+  __asm__ __volatile__ ("lxvd2x 1, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("xvsqrtsp 0, 1");
+  ra = 0;                               /* stop 2 */
+}
+
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
new file mode 100644
index 00000000000..596e8b502d8
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
@@ -0,0 +1,137 @@
+# Copyright 2008-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>
.
+# This file is part of the GDB testsuite.  It tests reverse stepping.
+# Lots of code borrowed from "step-reverse.exp".
+#
+# Test instruction record for Powerpc, ISA 2.06.
+#
+
+# The basic flow of the record tests are:
+#    1) Stop before executing the instructions of interest. Record
+#       the initial value of the registers that the instruction will
+#       change, i.e. the destination register.
+#    2) Execute the instructions.  Record the new value of the
+#       registers that changed.
+#    3) Reverse the direction of the execution and execute back to
+#       just before the instructions of interest.  Record the final
+#       value of the registers of interest.
+#    4) Check that the initial and new values of the registers are
+#       different, i.e. the instruction changed the registers as
expected.
+#    5) Check that the initial and final values of the registers are
+#       the same, i.e. gdb record restored the registers to their
+#       original values.
+
+standard_testfile ppc_record_test_isa_2_06.c
+
+set gen_src record_test_isa_2_06.c
+set executable record_test_isa_2_06
+set options [list debug]
+
+if {![istarget "powerpc*"]} then  {
+    verbose "Skipping Powerpc ISA 2.06 instruction record_test_2_06."
+    return
+}
+
+if {[build_executable "failed to prepare" $executable $srcfile
$options] == -1} {
+    return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint"
+    continue
+}
+
+gdb_test_no_output "record"
+
+###### Test 1:  Test an ISA 2.06 load (lxvd2x) and square root
instructiion
+###### (xvsqrtsp).  The load instruction will load vs1.  The sqrt
instruction
+###### will put its result into vs0.
+
+set stop1  [gdb_get_line_number "stop 1"]
+set stop2  [gdb_get_line_number "stop 2"]
+
+gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test 1"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 1"
+
+# Record the initial values in vs0, vs1
+# Load the argument into vs1, result of sqrt is put into vs0.
+set vs0_initial [capture_command_output "info register vs0" ""]
+set vs1_initial [capture_command_output "info register vs1" ""]
+
+gdb_test "break $stop2" ".*Breakpoint .*" "executed lxvd2x, xvsqrtsp"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 2"
+
+# The lxvd2x, xvsqrtsp and has been executed loading the argument into
vs1
+# Record the new values of vs0 and vs1
+set vs0_new [capture_command_output "info register vs0" ""]
+set vs1_new [capture_command_output "info register vs1" ""]
+
+# Execute in reverse to before the lxvd2x instruction
+gdb_test_no_output "set exec-direction reverse"
+
+gdb_test "break $stop1" ".*Breakpoint .*" "un executed lxvd2x,
xvsqrtsp"
+gdb_test "continue"  ".*Breakpoint.*" "At stop 1 in reverse"
+
+# Record the final values of vs0, vs1
+set vs0_final [capture_command_output "info register vs0" ""]
+set vs1_final [capture_command_output "info register vs1" ""]
+
+#check initial and new of vs0 are different
+set test_vs0_init_new "check vs0 initial versus vs0 new"
+if {[string compare $vs0_initial  $vs0_new ] == 0} {
+ fail $test_vs0_init_new
+} else {
+ pass $test_vs0_init_new
+}
+
+#check initial and new of vs1 are different
+set test_vs1_init_new "check vs0 initial versus vs1 new"
+if {[string compare $vs1_initial  $vs1_new ] == 0} {
+ fail $test_vs1_init_new
+} else {
+ pass $test_vs1_init_new
+}
+
+#check initial and final are the same
+set test_vs0_init_final "check vs0 initial versus vs0 final"
+if {[string compare $vs0_initial  $vs0_final ] == 0} {
+ pass $test_vs0_init_final
+} else {
+ fail $test_vs0_init_final
+}
+
+#check initial and final are the same
+set test_vs1_init_final "check vs1 initial versus vs1 final"
+if {[string compare $vs1_initial  $vs1_final ] == 0} {
+ pass $test_vs1_init_final
+} else {
+ fail $test_vs1_init_final
+}
+
+# Change execution direction to forward for next test
+gdb_test "set exec-direction forward" "" "Start forward test2"
+#gdb_test_no_output "set exec-direction forward"
+gdb_test "record stop" ".*Process record is stopped.*" "Stopped
recording"
+set test_del_bkpts "delete breakpoints, answer prompt"
+gdb_test_multiple "delete breakpoints" $test_del_bkpts {
+    -re "Delete all breakpoints.*y or n.*$" {
+	send_gdb "y\n"
+    }
+}
+
+gdb_test "record" "" "Start recording test2"
+
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
new file mode 100644
index 00000000000..87e45a7e85b
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
@@ -0,0 +1,83 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <ctype.h>     // isspace
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>    // getopt
+#include <altivec.h> // vector
+
+
+/* globals used for vector tests */
+static vector unsigned long vec_xa, vec_xb, vec_xt;
+static unsigned long ra, rb, rs;
+
+int main () {
+
+  ra = 0xABCDEF012;
+  rb = 0;
+  rs = 0x012345678;
+
+  /* 9.0, 16.0, 25.0, 36.0 */
+  vec_xb = (vector unsigned long){0x4110000041800000,
0x41c8000042100000};
+
+  vec_xt = (vector unsigned long){0xFF00FF00FF00FF00,
0xAA00AA00AA00AA00};
+
+  /* Test 1, ISA 3.1 word instructions. Load source into r1, result of
brh
+     put in r0. */
+  ra = 0xABCDEF012;                     /* stop 1 */
+  __asm__ __volatile__ ("pld 1, %0" :: "r" (ra ));
+  __asm__ __volatile__ ("brh 0, 1" );
+  ra = 0;                               /* stop 2 */
+
+  /* Test 2, ISA 3.1 MMA instructions with results in various ACC
entries
+     xxsetaccz    - ACC[3]
+     xvi4ger8     - ACC[4]
+     xvf16ger2pn  - ACC[5]
+     pmxvi8ger4   - ACC[6]
+     pmxvf32gerpp - ACC[7] and fpscr
+  */
+  /* Need to initialize the vs registers to a non zero value */
+  ra = (unsigned long) & vec_xb;
+  __asm__ __volatile__ ("lxvd2x 12, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 13, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 14, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 15, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xa = (vector unsigned long){0x333134343987601,
0x9994bbbc9983307};
+  vec_xb = (vector unsigned long){0x411234041898760,
0x41c833042103400};
+  __asm__ __volatile__ ("lxvd2x 16, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x123456789987650,
0x235676546989807};
+  __asm__ __volatile__ ("lxvd2x 17, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x878363439823470,
0x413434c99839870};
+  __asm__ __volatile__ ("lxvd2x 18, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x043765434398760,
0x419876555558850};
+  __asm__ __volatile__ ("lxvd2x 19, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x33313434398760,
0x9994bbbc99899330};
+  __asm__ __volatile__ ("lxvd2x 20, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 21, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 22, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 23, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 24, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 25, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 26, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 27, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xa = (vector unsigned long){0x33313434398760, 0x9994bbbc998330};
+  vec_xb = (vector unsigned long){0x4110000041800000,
0x41c8000042100000};
+  __asm__ __volatile__ ("lxvd2x 28, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x4567000046800000,
0x4458000048700000};
+  __asm__ __volatile__ ("lxvd2x 29, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x41dd000041e00000,
0x41c8000046544400};
+  __asm__ __volatile__ ("lxvd2x 30, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x7F8F00007F8F0000,
0x7F8F00007F8F0000}; /* SNAN */
+  __asm__ __volatile__ ("lxvd2x 31, %0, %1" :: "r" (ra ), "r" (rb));
+
+  ra = 0xAB;                            /* stop 3 */
+  __asm__ __volatile__ ("xxsetaccz 3");
+  __asm__ __volatile__ ("xvi4ger8 4, %x0, %x1" :: "wa" (vec_xa), "wa"
(vec_xb) );
+  __asm__ __volatile__ ("xvf16ger2pn 5, %x0, %x1" :: "wa" (vec_xa),
"wa" (vec_xb) );
+  __asm__ __volatile__ ("pmxvi8ger4spp  6, %x0, %x1, 11, 13, 5"
+                                :: "wa" (vec_xa), "wa" (vec_xb) );
+  __asm__ __volatile__ ("pmxvf32gerpp  7, %x0, %x1, 11, 13"
+                                :: "wa" (vec_xa), "wa" (vec_xb) );
+  ra = 0;                               /* stop 4 */
+
+}
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
new file mode 100644
index 00000000000..4ed9e7da2e7
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
@@ -0,0 +1,497 @@
+# Copyright 2008-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>
.
+# This file is part of the GDB testsuite.  It tests reverse stepping.
+# Lots of code borrowed from "step-reverse.exp".
+#
+# Test instruction record for Powerpc, ISA 3.1.
+#
+
+# The basic flow of the record tests are:
+#    1) Stop before executing the instructions of interest. Record
+#       the initial value of the registers that the instruction will
+#       change, i.e. the destination register.
+#    2) Execute the instructions.  Record the new value of the
+#       registers that changed.
+#    3) Reverse the direction of the execution and execute back to
+#       just before the instructions of interest.  Record the final
+#       value of the registers of interest.
+#    4) Check that the initial and new values of the registers are
+#       different, i.e. the instruction changed the registers as
expected.
+#    5) Check that the initial and final values of the registers are
+#       the same, i.e. gdb record restored the registers to their
+#       original values.
+
+
+standard_testfile ppc_record_test_isa_3_1.c
+
+set gen_src record_test_isa_3_1.c
+set executable record_test_isa_3_1
+
+if {![istarget "powerpc*"] || [skip_power_isa_3_1_tests] } then  {
+    verbose "Skipping Powerpc ISA 3.1 instruction record_test."
+    return
+}
+
+set options [list additional_flags=-mcpu=power10  debug]
+if {[build_executable "failed to prepare" $executable $srcfile
$options] == -1} {
+    return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint"
+    continue
+}
+
+gdb_test_no_output "record"
+
+######  Test 1:  Test an ISA 3.1 byte reverse word instruction (brd)
and a
+######   prefixed load double (pld) instruction.
+set stop1  [gdb_get_line_number "stop 1"]
+set stop2  [gdb_get_line_number "stop 2"]
+
+gdb_test "break $stop1" ".*Breakpoint .*" "about to execute Test 1"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 1"
+
+# Record the initial values in r0, r1
+# Load the argument into r1, result of byte reverse is put into r0.
+set r0_initial [capture_command_output "info register r0" ""]
+set r1_initial [capture_command_output "info register r1" ""]
+
+gdb_test "break $stop2" ".*Breakpoint .*" "executed test 1"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 2"
+
+# Record the new values of r0 and r1
+set r0_new [capture_command_output "info register r0" ""]
+set r1_new [capture_command_output "info register r1" ""]
+
+# Execute in reverse to before test 1
+gdb_test "set exec-direction reverse" "" "Reverse to start of Test 1"
+#gdb_test_no_output "set exec-direction reverse"
+
+gdb_test "break $stop1" ".*Breakpoint .*" "reverse stop at test 1
start"
+gdb_test "continue"  ".*Breakpoint.*" "At stop 1 in reverse"
+
+# Record the final values of r0, r1
+set r0_final [capture_command_output "info register r0" ""]
+set r1_final [capture_command_output "info register r1" ""]
+
+#check initial and new of r0 are different
+set test_r0_init_new "check r0 initial versus r0 new"
+if {[string compare $r0_initial  $r0_new ] == 0} {
+ fail $test_r0_init_new
+} else {
+ pass $test_r0_init_new
+}
+
+#check initial and new of r1 are different
+set test_r1_init_new "check r0 initial versus r1 new"
+if {[string compare $r1_initial  $r1_new ] == 0} {
+ fail $test_r1_init_new
+} else {
+ pass $test_r1_init_new
+}
+
+#check initial and final are the same
+set test_r0_init_final "check r0 initial versus r0 final"
+if {[string compare $r0_initial  $r0_final ] == 0} {
+ pass $test_r0_init_final
+} else {
+ fail $test_r0_init_final
+}
+
+#check initial and final are the same
+set test_r1_init_final "check r1 initial versus r1 final"
+if {[string compare $r1_initial  $r1_final ] == 0} {
+ pass $test_r1_init_final
+} else {
+ fail $test_r1_init_final
+}
+
+
+# Change execution direction to forward for next test
+gdb_test "set exec-direction forward" "" "Start forward test3"
+#gdb_test_no_output "set exec-direction forward"
+gdb_test "record stop" ".*Process record is stopped.*" "Stopped
recording 2"
+set test_del_bkpts "delete breakpoints, answer prompt 2"
+gdb_test_multiple "delete breakpoints" $test_del_bkpts {
+    -re "Delete all breakpoints.*y or n.*$" {
+	send_gdb "y\n"
+    }
+}
+
+gdb_test "record" "" "Start recording test3"
+
+
+######  Test 2:  Test the ISA 3.1 MMA instructions xxsetaccz,
xvi4ger8,
+######  xvf16ger2pn, pmxvi8ger4, and pmxvf32gerpp.  Goal here is to
hit all
+######  the places where ppc_record_ACC_fpscr() gets called.
+##
+##       xxsetaccz    - ACC[3], vs[12] to vs[15]
+##       xvi4ger8     - ACC[4], vs[16] to vs[19]
+##       xvf16ger2pn  - ACC[5], vs[20] to vs[23]
+##       pmxvi8ger4   - ACC[6], vs[21] to vs[27]
+##       pmxvf32gerpp - ACC[7], vs[28] to vs[31] and fpscr
+
+set stop3  [gdb_get_line_number "stop 3"]
+set stop4  [gdb_get_line_number "stop 4"]
+
+gdb_test "break $stop3" ".*Breakpoint .*" "about to execute Test 2"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 3"
+
+# Record the initial values of vs's that correspond to the ACC
entries,
+# and fpscr
+set acc_3_0_initial [capture_command_output "info register vs12" ""]
+set acc_3_1_initial [capture_command_output "info register vs13" ""]
+set acc_3_2_initial [capture_command_output "info register vs14" ""]
+set acc_3_3_initial [capture_command_output "info register vs15" ""]
+set acc_4_0_initial [capture_command_output "info register vs16" ""]
+set acc_4_1_initial [capture_command_output "info register vs17" ""]
+set acc_4_2_initial [capture_command_output "info register vs18" ""]
+set acc_4_3_initial [capture_command_output "info register vs19" ""]
+set acc_5_0_initial [capture_command_output "info register vs20" ""]
+set acc_5_1_initial [capture_command_output "info register vs21" ""]
+set acc_5_2_initial [capture_command_output "info register vs22" ""]
+set acc_5_3_initial [capture_command_output "info register vs23" ""]
+set acc_6_0_initial [capture_command_output "info register vs24" ""]
+set acc_6_1_initial [capture_command_output "info register vs25" ""]
+set acc_6_2_initial [capture_command_output "info register vs26" ""]
+set acc_6_3_initial [capture_command_output "info register vs27" ""]
+set acc_7_0_initial [capture_command_output "info register vs28" ""]
+set acc_7_1_initial [capture_command_output "info register vs29" ""]
+set acc_7_2_initial [capture_command_output "info register vs30" ""]
+set acc_7_3_initial [capture_command_output "info register vs31" ""]
+set fpscr_initial [capture_command_output "info register fpscr" ""]
+
+gdb_test "break $stop4" ".*Breakpoint .*" "executed test 2"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 4"
+
+# Record the new values of the ACC entries and fpscr
+set acc_3_0_new [capture_command_output "info register vs12" ""]
+set acc_3_1_new [capture_command_output "info register vs13" ""]
+set acc_3_2_new [capture_command_output "info register vs14" ""]
+set acc_3_3_new [capture_command_output "info register vs15" ""]
+set acc_4_0_new [capture_command_output "info register vs16" ""]
+set acc_4_1_new [capture_command_output "info register vs17" ""]
+set acc_4_2_new [capture_command_output "info register vs18" ""]
+set acc_4_3_new [capture_command_output "info register vs19" ""]
+set acc_5_0_new [capture_command_output "info register vs20" ""]
+set acc_5_1_new [capture_command_output "info register vs21" ""]
+set acc_5_2_new [capture_command_output "info register vs22" ""]
+set acc_5_3_new [capture_command_output "info register vs23" ""]
+set acc_6_0_new [capture_command_output "info register vs24" ""]
+set acc_6_1_new [capture_command_output "info register vs25" ""]
+set acc_6_2_new [capture_command_output "info register vs26" ""]
+set acc_6_3_new [capture_command_output "info register vs27" ""]
+set acc_7_0_new [capture_command_output "info register vs28" ""]
+set acc_7_1_new [capture_command_output "info register vs29" ""]
+set acc_7_2_new [capture_command_output "info register vs30" ""]
+set acc_7_3_new [capture_command_output "info register vs31" ""]
+set fpscr_new [capture_command_output "info register fpscr" ""]
+
+# Execute in reverse to before test 2
+gdb_test "set exec-direction reverse" "" "Reverse to start of Test 2"
+
+gdb_test "break $stop3" ".*Breakpoint .*" "reverse stop at test 2
start"
+gdb_test "continue"  ".*Breakpoint.*" "At stop 3 in reverse"
+
+# Record the final values of the ACC entries and fpscr
+set acc_3_0_final [capture_command_output "info register vs12" ""]
+set acc_3_1_final [capture_command_output "info register vs13" ""]
+set acc_3_2_final [capture_command_output "info register vs14" ""]
+set acc_3_3_final [capture_command_output "info register vs15" ""]
+set acc_4_0_final [capture_command_output "info register vs16" ""]
+set acc_4_1_final [capture_command_output "info register vs17" ""]
+set acc_4_2_final [capture_command_output "info register vs18" ""]
+set acc_4_3_final [capture_command_output "info register vs19" ""]
+set acc_5_0_final [capture_command_output "info register vs20" ""]
+set acc_5_1_final [capture_command_output "info register vs21" ""]
+set acc_5_2_final [capture_command_output "info register vs22" ""]
+set acc_5_3_final [capture_command_output "info register vs23" ""]
+set acc_6_0_final [capture_command_output "info register vs24" ""]
+set acc_6_1_final [capture_command_output "info register vs25" ""]
+set acc_6_2_final [capture_command_output "info register vs26" ""]
+set acc_6_3_final [capture_command_output "info register vs27" ""]
+set acc_7_0_final [capture_command_output "info register vs28" ""]
+set acc_7_1_final [capture_command_output "info register vs29" ""]
+set acc_7_2_final [capture_command_output "info register vs30" ""]
+set acc_7_3_final [capture_command_output "info register vs31" ""]
+set fpscr_final [capture_command_output "info register fpscr" ""]
+
+#check initial and new ACC entries
+set test_acc_3_0_init_new "check vs12 initial versus new"
+if {[string compare $acc_3_0_initial  $acc_3_0_new ] == 0} {
+ fail $test_acc_3_0_init_new
+} else {
+ pass $test_acc_3_0_init_new
+}
+set test_acc_3_1_init_new "check vs13 initial versus new"
+if {[string compare $acc_3_1_initial  $acc_3_1_new ] == 0} {
+ fail $test_acc_3_1_init_new
+} else {
+ pass $test_acc_3_1_init_new
+}
+set test_acc_3_2_init_new "check vs14 initial versus new"
+if {[string compare $acc_3_2_initial  $acc_3_2_new ] == 0} {
+ fail $test_acc_3_2_init_new
+} else {
+ pass $test_acc_3_2_init_new
+}
+set test_acc_3_3_init_new "check vs15 initial versus new"
+if {[string compare $acc_3_3_initial  $acc_3_3_new ] == 0} {
+ fail $test_acc_3_3_init_new
+} else {
+ pass $test_acc_3_3_init_new
+}
+
+set test_acc_4_0_init_new "check vs16 initial versus new"
+if {[string compare $acc_4_0_initial  $acc_4_0_new ] == 0} {
+ fail $test_acc_4_0_init_new
+} else {
+ pass $test_acc_4_0_init_new
+}
+set test_acc_4_1_init_new "check vs17 initial versus new"
+if {[string compare $acc_4_1_initial  $acc_4_1_new ] == 0} {
+ fail $test_acc_4_1_init_new
+} else {
+ pass $test_acc_4_1_init_new
+}
+set test_acc_4_2_init_new "check vs18 initial versus new"
+if {[string compare $acc_4_2_initial  $acc_4_2_new ] == 0} {
+ fail $test_acc_4_2_init_new
+} else {
+ pass $test_acc_4_2_init_new
+}
+set test_acc_4_3_init_new "check vs19 initial versus new"
+if {[string compare $acc_4_3_initial  $acc_4_3_new ] == 0} {
+ fail $test_acc_4_3_init_new
+} else {
+ pass $test_acc_4_3_init_new
+}
+
+set test_acc_5_0_init_new "check vs20 initial versus new"
+if {[string compare $acc_5_0_initial  $acc_5_0_new ] == 0} {
+ fail $test_acc_5_0_init_new
+} else {
+ pass $test_acc_5_0_init_new
+}
+set test_acc_5_1_init_new "check vs21 initial versus new"
+if {[string compare $acc_5_1_initial  $acc_5_1_new ] == 0} {
+ fail $test_acc_5_1_init_new
+} else {
+ pass $test_acc_5_1_init_new
+}
+set test_acc_5_2_init_new "check vs22 initial versus new"
+if {[string compare $acc_5_2_initial  $acc_5_2_new ] == 0} {
+ fail $test_acc_5_2_init_new
+} else {
+ pass $test_acc_5_2_init_new
+}
+set test_acc_5_3_init_new "check vs23 initial versus new"
+if {[string compare $acc_5_3_initial  $acc_5_3_new ] == 0} {
+ fail $test_acc_5_3_init_new
+} else {
+ pass $test_acc_5_3_init_new
+}
+
+set test_acc_6_0_init_new "check vs24 initial versus new"
+if {[string compare $acc_6_0_initial  $acc_6_0_new ] == 0} {
+ fail $test_acc_6_0_init_new
+} else {
+ pass $test_acc_6_0_init_new
+}
+set test_acc_6_1_init_new "check vs25 initial versus new"
+if {[string compare $acc_6_1_initial  $acc_6_1_new ] == 0} {
+ fail $test_acc_6_1_init_new
+} else {
+ pass $test_acc_6_1_init_new
+}
+set test_acc_6_2_init_new "check vs26 initial versus new"
+if {[string compare $acc_6_2_initial  $acc_6_2_new ] == 0} {
+ fail $test_acc_6_2_init_new
+} else {
+ pass $test_acc_6_2_init_new
+}
+set test_acc_6_3_init_new "check vs27 initial versus new"
+if {[string compare $acc_6_3_initial  $acc_6_3_new ] == 0} {
+ fail $test_acc_6_3_init_new
+} else {
+ pass $test_acc_6_3_init_new
+}
+
+set test_acc_7_0_init_new "check vs28 initial versus new"
+if {[string compare $acc_7_0_initial  $acc_7_0_new ] == 0} {
+ fail $test_acc_7_0_init_new
+} else {
+ pass $test_acc_7_0_init_new
+}
+set test_acc_7_1_init_new "check vs29 initial versus new"
+if {[string compare $acc_7_1_initial  $acc_7_1_new ] == 0} {
+ fail $test_acc_7_1_init_new
+} else {
+ pass $test_acc_7_1_init_new
+}
+set test_acc_7_2_init_new "check vs30 initial versus new"
+if {[string compare $acc_7_2_initial  $acc_7_2_new ] == 0} {
+ fail $test_acc_7_2_init_new
+} else {
+ pass $test_acc_7_2_init_new
+}
+set test_acc_7_3_init_new "check vs31 initial versus new"
+if {[string compare $acc_7_3_initial  $acc_7_3_new ] == 0} {
+ fail $test_acc_7_3_init_new
+} else {
+ pass $test_acc_7_3_init_new
+}
+set test_fpscr_init_new "check fpscr initial versus new"
+if {[string compare $fpscr_initial  $fpscr_new ] == 0} {
+ fail $test_fpscr_init_new
+} else {
+ pass $test_fpscr_init_new
+}
+
+#check initial and new ACC entries are different
+set test_acc_3_0_init_final "check vs12 initial versus final"
+if {[string compare $acc_3_0_initial  $acc_3_0_final ] == 0} {
+ pass $test_acc_3_0_init_final
+} else {
+ fail $test_acc_3_0_init_final
+}
+set test_acc_3_1_init_final "check vs13 initial versus final"
+if {[string compare $acc_3_1_initial  $acc_3_1_final ] == 0} {
+ pass $test_acc_3_1_init_final
+} else {
+ fail $test_acc_3_0_init_final
+}
+set test_acc_3_2_init_final "check vs14 initial versus final"
+if {[string compare $acc_3_2_initial  $acc_3_2_final ] == 0} {
+ pass $test_acc_3_2_init_final
+} else {
+ fail $test_acc_3_2_init_final
+}
+set test_acc_3_3_init_final "check vs15 initial versus final"
+if {[string compare $acc_3_3_initial  $acc_3_3_final ] == 0} {
+ pass $test_acc_3_3_init_final
+} else {
+ new $test_acc_3_3_init_final
+}
+
+set test_acc_4_0_init_final "check vs16 initial versus final"
+if {[string compare $acc_4_0_initial  $acc_4_0_final ] == 0} {
+ pass $test_acc_4_0_init_final
+} else {
+ new $test_acc_4_0_init_final
+}
+set test_acc_4_1_init_final "check vs17 initial versus final"
+if {[string compare $acc_4_1_initial  $acc_4_1_final ] == 0} {
+ pass $test_acc_4_1_init_final
+} else {
+ new $test_acc_4_0_init_final
+}
+set test_acc_4_2_init_final "check vs18 initial versus final"
+if {[string compare $acc_4_2_initial  $acc_4_2_final ] == 0} {
+ pass $test_acc_4_2_init_final
+} else {
+ new $test_acc_4_2_init_final
+}
+set test_acc_4_3_init_final "check vs19 initial versus final"
+if {[string compare $acc_4_3_initial  $acc_4_3_final ] == 0} {
+ pass $test_acc_4_3_init_final
+} else {
+ fail $test_acc_4_3_init_final
+}
+
+set test_acc_5_0_init_final "check vs20 initial versus final"
+if {[string compare $acc_5_0_initial  $acc_5_0_final ] == 0} {
+ pass $test_acc_5_0_init_final
+} else {
+ fail $test_acc_5_0_init_final
+}
+set test_acc_5_1_init_final "check vs21 initial versus final"
+if {[string compare $acc_5_1_initial  $acc_5_1_final ] == 0} {
+ pass $test_acc_5_1_init_final
+} else {
+ fail $test_acc_5_0_init_final
+}
+set test_acc_5_2_init_final "check vs22 initial versus final"
+if {[string compare $acc_5_2_initial  $acc_5_2_final ] == 0} {
+ pass $test_acc_5_2_init_final
+} else {
+ fail $test_acc_5_2_init_final
+}
+set test_acc_5_3_init_final "check vs23 initial versus final"
+if {[string compare $acc_5_3_initial  $acc_5_3_final ] == 0} {
+ pass $test_acc_5_3_init_final
+} else {
+ fail $test_acc_5_3_init_final
+}
+
+set test_acc_6_0_init_final "check vs24 initial versus final"
+if {[string compare $acc_6_0_initial  $acc_6_0_final ] == 0} {
+ pass $test_acc_6_0_init_final
+} else {
+ fail $test_acc_6_0_init_final
+}
+set test_acc_6_1_init_final "check vs25 initial versus final"
+if {[string compare $acc_6_1_initial  $acc_6_1_final ] == 0} {
+ pass $test_acc_6_1_init_final
+} else {
+ fail $test_acc_6_0_init_final
+}
+set test_acc_6_2_init_final "check vs26 initial versus final"
+if {[string compare $acc_6_2_initial  $acc_6_2_final ] == 0} {
+ pass $test_acc_6_2_init_final
+} else {
+ fail $test_acc_6_2_init_final
+}
+set test_acc_6_3_init_final "check vs27 initial versus final"
+if {[string compare $acc_6_3_initial  $acc_6_3_final ] == 0} {
+ pass $test_acc_6_3_init_final
+} else {
+ fail $test_acc_6_3_init_final
+}
+
+set test_acc_7_0_init_final "check vs28 initial versus final"
+if {[string compare $acc_7_0_initial  $acc_7_0_final ] == 0} {
+ pass $test_acc_7_0_init_final
+} else {
+ fail $test_acc_7_0_init_final
+}
+set test_acc_7_1_init_final "check vs29 initial versus final"
+if {[string compare $acc_7_1_initial  $acc_7_1_final ] == 0} {
+ pass $test_acc_7_1_init_final
+} else {
+ fail $test_acc_7_0_init_final
+}
+set test_acc_7_2_init_final "check vs30 initial versus final"
+if {[string compare $acc_7_2_initial  $acc_7_2_final ] == 0} {
+ pass $test_acc_7_2_init_final
+} else {
+ fail $test_acc_7_2_init_final
+}
+set test_acc_7_3_init_final "check vs31 initial versus final"
+if {[string compare $acc_7_3_initial  $acc_7_3_final ] == 0} {
+ pass $test_acc_7_3_init_final
+} else {
+ fail $test_acc_7_3_init_final
+}
+set test_fpscr_init_final "check fpscr initial versus final"
+if {[string compare $fpscr_initial  $fpscr_final ] == 0} {
+ pass $test_fpscr_init_final
+} else {
+ fail $test_fpscr_init_final
+}
+
-- 
2.32.0



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/2] Add recording support for the ISA 3.1 Powerpc instructions
  2022-03-04 19:52 ` [PATCH 1/2] " Carl Love
@ 2022-03-06 11:53   ` Joel Brobecker
  2022-04-12 17:09     ` [PATCH 1/2 Version 2] " Carl Love
  0 siblings, 1 reply; 25+ messages in thread
From: Joel Brobecker @ 2022-03-06 11:53 UTC (permalink / raw)
  To: Carl Love via Gdb-patches
  Cc: Ulrich Weigand, Rogerio Alves, Tulio Magno, Joel Brobecker

Hello,

On Fri, Mar 04, 2022 at 11:52:43AM -0800, Carl Love via Gdb-patches wrote:
> GDB maintainers:
> 
> The gdb record functionality does not have support for the the
> PowerpcISA 3.1 instructions.  The following patch adds the missing gdb
> record support for power. 
> 
> As mentioned in message [0/2], I have used the Valgrind ISA 3.1
> testsuite to verify that all of the ISA 3.1 instructions are recognized
> by gdb record with this patch applied. Please let me know if this patch
> is accepatble to commit to the gdb mainline repository.   Thanks.
> 
>                          Carl Love
> 
> ------------------------------------------------
> 
> Add recording support for the ISA 3.1 Powerpc  instructions.
> 
> This patch adds support for the Powerpc ISA 3.1 instructions to the Powerpc
> gdb instruction recording routines.  Case statement entries are added to a
> number of the existing routines for recording the 32-bit word instructions.
> A few new functions were added to handle the new word instructions.  The 64-bit
> prefix instructions are all handled by a set of new routines.  The function
> ppc_process_prefix_instruction() is the primary function to handle the
> prefixed instructions. It calls additional functions to handle specific
> sets of prefixed instructions.  These new functions are:
> 
>   ppc_process_record_prefix_vsx_d_form(),
>   ppc_process_record_prefix_store_vsx_ds_form(),
>   ppc_process_record_prefix_op34(),
>   ppc_process_record_prefix_op33(),
>   ppc_process_record_prefix_op32(),
>   ppc_process_record_prefix_store(),
>   ppc_process_record_prefix_op59_XX3(),
>   ppc_process_record_prefix_op42().

Thanks for this patch.

I mostly skimmed through the patch, as I do not know the PowerPC
architecture all that well, especially the newer ISAs.

My general remarks is that the code looks reasonable, and you seem
to have tested it relatively well. So I'll focus on the higher-level
comments. In particular, I think every new function we introduce
deserves an intro comment describing what the function does, and
documenting all the parameters and return value.

> @@ -4152,6 +4170,52 @@ ppc_record_vsr (struct regcache *regcache, ppc_gdbarch_tdep *tdep, int vsr)
>    return 0;
>  }
>  
> +#define RECORD_FPSCR 1
> +#define DO_NOT_RECORD_FPSCR 0

I think these macros deserves documentation as well.

> +     NOTE:
> +     In ISA 3.1 the ACC is mapped on top of VSR[0] thru VSR[31].
> +
> +     In the future, the ACC may be implemented as an independent register file
> +     rather then mapping on top of the VSRs. This will then require the ACC to

Small typo: "then" -> "than".

Also, can you add an extra space after the period (just before
"This will [...]" above)?

> +     be assigned its on register number and the ptrace interface to be able
> +     access the ACC.
> +  */
> +
> +  /* ACC maps over the same VSR space as the fp registers.  */
> +  for (i = 0; i<4; i++) {

GNU Coding style: Can you place the opening curly brace on the next
line, please, indented 2 characters relative to the "for". You'll
probably want to adjust the indentation of the block accordingly,
including the closing curly brace.

> @@ -5174,15 +5517,13 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>    return -1;
>  }
>  
> -/* Parse and record instructions of primary opcode-59 at ADDR.
> -   Return 0 if successful.  */
> -

>  static int
>  ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,

Can you explain why you are removing this function documentation?
Is it now OBE? Either way, can you make sure we either keep the doc,
or replace it with an updated version?
> +
> +  if (type == 1) {
> +    if (ST4 == 0) {

GNU Coding Style: Same as the "for" above. Can you go through
perhaps your patch for me, to see if I might have missed some other
style issues?

Let me give you, JIC, the link to our coding standards:
https://sourceware.org/gdb/wiki/Internals%20Coding-Standards

In particular, the C/C++ CS:
https://sourceware.org/gdb/wiki/Internals%20GDB-C-Coding-Standards

> +    } else

Coding standard: The "else" should be on the next line.


> +      return -1;
> +
> +  } else if (type == 2) {

Same here, please, and also watch out for the training "{" which
should also be moved to the next line.

The following are also other coding style violations I noticed
through skimming your patch:

> +  if (type == 1) {
> +  } else
> +  if (type == 1) {
> +  } else if (type == 2) {
> +  } else
> +  if ((type == 0) && (ST1 == 0)) {
> +    if (R == 0) {
> +    } else {
> +  if ((type == 0) && (ST1 == 0)) {
> +	  if (R == 0) {
> +	  } else {
> +  } else

Hopefully you can do a pass of your own and catch the ones
I didn't see.

Thank you,
-- 
Joel

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/2] Add recording support for the ISA 3.1 Powerpc instructions
  2022-03-04 19:53 ` [PATCH 2/2] " Carl Love
@ 2022-03-06 12:42   ` Joel Brobecker
  2022-04-12 17:09     ` [PATCH 2/2 Version 2] " Carl Love
  0 siblings, 1 reply; 25+ messages in thread
From: Joel Brobecker @ 2022-03-06 12:42 UTC (permalink / raw)
  To: Carl Love via Gdb-patches
  Cc: Ulrich Weigand, Rogerio Alves, Tulio Magno, Joel Brobecker

> The patch adds the gdb recording test cases for the Powerpc ISA 2.06
> and ISA 3.1 instruction sets.
> 
> The patch has been run on both Power 10 and Power 9 to verify the ISA
> 2.06 test case runs on both platforms without errors.  The ISA 3.1 test
> runs without errors on Power 10 and is skipped as expected on Power 9.
> 
> Please let me know if this patch is acceptable for gdb mainline. 
> Thanks.

Thanks for this patch.

I am not a specialist of writing testcases in the GDB testsuite,
anymore, so others may have more comments. In the meantime, here
are the things I saw.

FWIW, the description you provide at the start of this email would
also be useful to have in the commit message as well, to give people
a record of what you did without having to read your email version.

One general note: The formatting seems to have been affected by
the sending, which surprises me a little, as this was sent by
"git send-email", is that right? What makes me say this is because
we see a number of lines where it looks like the text was moved
to the next line. E.g.

> +###### Test 1:  Test an ISA 2.06 load (lxvd2x) and square root
> instructiion
> +###### (xvsqrtsp).  The load instruction will load vs1.  The sqrt
> instruction

I'm going to assume this is correct in your patch, but it would
be nice to figure out where this is coming from.


> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c

Can you please add a copyright header to this file, and more
generally, to all new files?

> +/* globals used for vector tests */
> +static vector unsigned long vec_xa, vec_xb, vec_xt;
> +static unsigned long ra, rb, rs;
> +
> +int main () {

We ask that we try to make a reasonable attempt that our test
programs also follow the GNU Coding Standard. So, can you
move the opening curly brace to the next line, please?

I'll let you scan this commit for other formatting issues as
per my comments to your other commit enhancing GDB itself.

> +# The basic flow of the record tests are:
> +#    1) Stop before executing the instructions of interest. Record

Missing second space after period.

> +standard_testfile ppc_record_test_isa_2_06.c

Just thinking out loud: Wondering if ppc_record_test_isa_2_06.c
is actually needed, here...

> +if ![runto_main] then {
> +    perror "couldn't run to breakpoint"
> +    continue
> +}

For this block, let's follow what our testcase template
recommends:

https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/testsuite/gdb.base/template.exp;h=007a1472fee6866e76c3c6d991251502f278a615;hb=HEAD

    | if { ![runto_main] } {
    |     untested "could not run to main"
    |     return
    | }


> +#check initial and new of vs0 are different

Here and below, can you make sure there is a space between
the "#" and the start of the text. Also, can you start them
with an upper-case letter in this case, and end the sentence
with a period? This is mandated by the GNU Coding Style.

> +# Change execution direction to forward for next test
> +gdb_test "set exec-direction forward" "" "Start forward test2"
> +#gdb_test_no_output "set exec-direction forward"

Can you removed this commented-out line? I don't think we need
to keep it.

> +gdb_test "record stop" ".*Process record is stopped.*" "Stopped
> recording"
> +set test_del_bkpts "delete breakpoints, answer prompt"
> +gdb_test_multiple "delete breakpoints" $test_del_bkpts {
> +    -re "Delete all breakpoints.*y or n.*$" {
> +	send_gdb "y\n"
> +    }
> +}
> +
> +gdb_test "record" "" "Start recording test2"

Is this part needed? There doesn't seem anything done after,
so I'm wondering what the purpose of this test is.

(note: if needed, we should use gdb_test_no_output instead)

> +if ![runto_main] then {
> +    perror "couldn't run to breakpoint"
> +    continue
> +}

Same as above.

> +#check initial and new of r0 are different

Here and below, same as above.
> +# Change execution direction to forward for next test
> +gdb_test "set exec-direction forward" "" "Start forward test3"
> +#gdb_test_no_output "set exec-direction forward"

Same as above, can you remove this commented-out line, please?

> +gdb_test "record stop" ".*Process record is stopped.*" "Stopped
> recording 2"
> +set test_del_bkpts "delete breakpoints, answer prompt 2"
> +gdb_test_multiple "delete breakpoints" $test_del_bkpts {
> +    -re "Delete all breakpoints.*y or n.*$" {
> +	send_gdb "y\n"
> +    }
> +}

I think you can simplify the above using something like:

   with confirm off -- delete breakpoints

-- 
Joel

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 0/2   Version 2] Add recording support for the ISA 3.1 Powerpc instructions
  2022-03-04 19:46 [PATCH 0/2] Add recording support for the ISA 3.1 Powerpc instructions Carl Love
  2022-03-04 19:52 ` [PATCH 1/2] " Carl Love
  2022-03-04 19:53 ` [PATCH 2/2] " Carl Love
@ 2022-04-12 17:09 ` Carl Love
  2 siblings, 0 replies; 25+ messages in thread
From: Carl Love @ 2022-04-12 17:09 UTC (permalink / raw)
  To: gdb-patches, Ulrich Weigand, Joel Brobecker, cel
  Cc: Will Schmidt, Tulio Magno, Rogerio Alves

Joel Brobecker:

On Fri, 2022-03-04 at 11:46 -0800, Carl Love wrote:
> GDB maintainers:
> 
> The gdb record functionality does not have support for the the
> Powerpc
> ISA 3.1 instructions.  
> 
> The first patch in this series will add the missing support to record
> the registers for each of the ISA 3.1 instructions.
> 
> The second patch in the series adds two test cases.  The first test
> case verifies the recording works for a few of the ISA 2.06
> instructions.  The second case verifies recording of a few ISA 3.1
> instructions.
> 
> I have used the Valgrind ISA 3.1 testsuite to verify that all of the
> ISA 3.1 instructions are recognized by gdb record.  Additionally, I
> manually ran gdb stoping at the Valgrind test function for each of
> the
> new instructions.  I then verified that all of the expected registers
> changed and were then restored when the instruction was executed in
> reverse.  Basically, the test process consisted of stopping at the
> isa
> instruction, issue the gdb command record command, info registers all
> saving the output file 1, si,  info registers all saving the output
> file 2, reverse-stepi, info registers all saving the output file
> 3.  I
> then diffed files 1 and 2 to verify the test changed all of the
> registers specified in the ISA. Finally, diff files 1 and 3 to verify
> all of the registers were restored.

Sorry it took so long to get this updated.  I initially missed your
response as it went to my gdb account not cel@us.ibm.com.  I have
addressed your comments with both of the testcase patches.  The
regression tests have been rerun on Power 10 to verify the tests still
run correctly.

                      Carl Love



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/2  Version 2] Add recording support for the ISA 3.1 Powerpc instructions
  2022-03-06 11:53   ` Joel Brobecker
@ 2022-04-12 17:09     ` Carl Love
  2022-04-12 21:50       ` will schmidt
  0 siblings, 1 reply; 25+ messages in thread
From: Carl Love @ 2022-04-12 17:09 UTC (permalink / raw)
  To: Joel Brobecker, gdb-patches, cel
  Cc: Ulrich Weigand, Tulio Magno, Rogerio Alves

Joel, GDB maintainers:

I have addressed the following comments:

On Sun, 2022-03-06 at 15:53 +0400, Joel Brobecker via Gdb-patches
wrote:
> <snip>

> >  
> > +#define RECORD_FPSCR 1
> > +#define DO_NOT_RECORD_FPSCR 0
> 
> I think these macros deserves documentation as well.

Added a header comment for the function and defines.
> 
> > +     NOTE:
> > +     In ISA 3.1 the ACC is mapped on top of VSR[0] thru VSR[31].
> > +
> > +     In the future, the ACC may be implemented as an independent
> > register file
> > +     rather then mapping on top of the VSRs. This will then
> > require the ACC to
> 
> Small typo: "then" -> "than".

Fixed.

> 
> Also, can you add an extra space after the period (just before
> "This will [...]" above)?
Fixed.

> 
> > +     be assigned its on register number and the ptrace interface
> > to be able
> > +     access the ACC.
> > +  */
> > +
> > +  /* ACC maps over the same VSR space as the fp registers.  */
> > +  for (i = 0; i<4; i++) {
> 
> GNU Coding style: Can you place the opening curly brace on the next
> line, please, indented 2 characters relative to the "for". You'll
> probably want to adjust the indentation of the block accordingly,
> including the closing curly brace.

Fixed this coding style throughout the patch.

> 
> > @@ -5174,15 +5517,13 @@ ppc_process_record_op31 (struct gdbarch
> > *gdbarch, struct regcache *regcache,
> >    return -1;
> >  }
> >  
> > -/* Parse and record instructions of primary opcode-59 at ADDR.
> > -   Return 0 if successful.  */
> > -
> >  static int
> >  ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache
> > *regcache,
> 
> Can you explain why you are removing this function documentation?
> Is it now OBE? Either way, can you make sure we either keep the doc,
> or replace it with an updated version?

Should not have been removed, put the comment back in.

> > +
> > +  if (type == 1) {
> > +    if (ST4 == 0) {
> 
Fixed.
<snip>
> 
> > +    } else
> 
> Coding standard: The "else" should be on the next line.
fixed
> 
> 
> > +      return -1;
> > +
> > +  } else if (type == 2) {
> 
> Same here, please, and also watch out for the training "{" which
> should also be moved to the next line.
> 
> The following are also other coding style violations I noticed
> through skimming your patch:
> 
> > +  if (type == 1) {
> > +  } else
> > +  if (type == 1) {
> > +  } else if (type == 2) {
> > +  } else
> > +  if ((type == 0) && (ST1 == 0)) {
> > +    if (R == 0) {
> > +    } else {
> > +  if ((type == 0) && (ST1 == 0)) {
> > +	  if (R == 0) {
> > +	  } else {
> > +  } else
> 
fixed

I do believe I have all of the coding style issues.

Patch has been retested on Power 10 with no regressions.

                             Carl Love

---------------------------------------------------------------------
Add recording support for the ISA 3.1 Powerpc instructions.

This patch adds support for the Powerpc ISA 3.1 instructions to the Powerpc
gdb instruction recording routines.  Case statement entries are added to a
number of the existing routines for recording the 32-bit word instructions.
A few new functions were added to handle the new word instructions.  The 64-bit
prefix instructions are all handled by a set of new routines.  The function
ppc_process_prefix_instruction() is the primary function to handle the
prefixed instructions. It calls additional functions to handle specific
sets of prefixed instructions.  These new functions are:
  ppc_process_record_prefix_vsx_d_form(),
  ppc_process_record_prefix_store_vsx_ds_form(),
  ppc_process_record_prefix_op34(),
  ppc_process_record_prefix_op33(),
  ppc_process_record_prefix_op32(),
  ppc_process_record_prefix_store(),
  ppc_process_record_prefix_op59_XX3(),
  ppc_process_record_prefix_op42().
---
 gdb/rs6000-tdep.c | 1196 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 1171 insertions(+), 25 deletions(-)

diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 44828bcff6d..7b4b4a71746 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -4123,8 +4123,26 @@ bfd_uses_spe_extensions (bfd *abfd)
 #define PPC_LEV(insn)	PPC_FIELD (insn, 20, 7)
 
 #define PPC_XT(insn)	((PPC_TX (insn) << 5) | PPC_T (insn))
+#define PPC_XTp(insn)	((PPC_BIT (insn, 10) << 5)	\
+			 | PPC_FIELD (insn, 6, 4) << 1)
+#define PPC_XSp(insn)	((PPC_BIT (insn, 10) << 5)	\
+			 | PPC_FIELD (insn, 6, 4) << 1)
 #define PPC_XER_NB(xer)	(xer & 0x7f)
 
+/* The following macros are for the prefixed instructions.  */
+#define P_PPC_D(insn_prefix, insn_suffix) \
+  PPC_SEXT (PPC_FIELD (insn_prefix, 14, 18) << 16 \
+	    | PPC_FIELD (insn_suffix, 16, 16), 34)
+#define P_PPC_TX5(insn_sufix)	PPC_BIT (insn_suffix, 5)
+#define P_PPC_TX15(insn_suffix) PPC_BIT (insn_suffix, 15)
+#define P_PPC_XT(insn_suffix)	((PPC_TX (insn_suffix) << 5) \
+				 | PPC_T (insn_suffix))
+#define P_PPC_XT5(insn_suffix) ((P_PPC_TX5 (insn_suffix) << 5) \
+				| PPC_T (insn_suffix))
+#define P_PPC_XT15(insn_suffix) \
+  ((P_PPC_TX15 (insn_suffix) << 5) | PPC_T (insn_suffix))
+
+
 /* Record Vector-Scalar Registers.
    For VSR less than 32, it's represented by an FPR and an VSR-upper register.
    Otherwise, it's just a VR register.  Record them accordingly.  */
@@ -4152,6 +4170,60 @@ ppc_record_vsr (struct regcache *regcache, ppc_gdbarch_tdep *tdep, int vsr)
   return 0;
 }
 
+/* The ppc_record_ACC_fpscr() records te changes to the floating point
+   registers modified by a floating point instruction.  The RECORD_FPSCR
+   or DO_NOT_RECORD_FPSCR argument to the function specifies if the instruction
+   modifies the floating point condition code register which also needs to be
+   recorded.  Return 0 on success.  */
+
+#define RECORD_FPSCR 1
+#define DO_NOT_RECORD_FPSCR 0
+
+static int
+ppc_record_ACC_fpscr (struct regcache *regcache, ppc_gdbarch_tdep *tdep,
+		      int at, int save_fpscr)
+{
+  int i;
+  if (at < 0 || at >= 8)
+    return -1;
+
+  /* The ACC consists of 8 entries, each entries consist of four 128-bit
+     rows.
+
+     The ACC rows map to specific VSR registers.
+         ACC[0][0] -> VSR[0]
+         ACC[0][1] -> VSR[1]
+         ACC[0][2] -> VSR[2]
+         ACC[0][3] -> VSR[3]
+              ...
+         ACC[7][0] -> VSR[28]
+         ACC[7][1] -> VSR[29]
+         ACC[7][2] -> VSR[30]
+         ACC[7][3] -> VSR[31]
+
+     NOTE:
+     In ISA 3.1 the ACC is mapped on top of VSR[0] thru VSR[31].
+
+     In the future, the ACC may be implemented as an independent register file
+     rather than mapping on top of the VSRs.  This will then require the ACC to
+     be assigned its on register number and the ptrace interface to be able
+     access the ACC.  */
+
+  /* ACC maps over the same VSR space as the fp registers.  */
+  for (i = 0; i<4; i++)
+    {
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fp0_regnum
+				     + at*4 + i);
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_vsr0_upper_regnum + at*4 + i);
+    }
+
+  if (save_fpscr)
+    record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+
+  return 0;
+}
+
 /* Parse and record instructions primary opcode-4 at ADDR.
    Return 0 if successful.  */
 
@@ -4171,9 +4243,34 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 41:		/* Vector Multiply-Sum Signed Halfword Saturate */
       record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
       /* FALL-THROUGH */
+    case 20:		/* Move To VSR Byte Mask Immediate opcode, ignore
+			   bit 31 */
+    case 21:		/* Move To VSR Byte Mask Immediate opcode, ignore
+			   bit 31 */
+    case 23:		/* Vector Multiply-Sum & write Carry-out Unsigned
+			   Doubleword */
+    case 24:		/* Vector Extract Double Unsigned Byte to VSR
+			   using GPR-specified Left-Index */
+    case 25:		/* Vector Extract Double Unsigned Byte to VSR
+			   using GPR-specified Right-Index */
+    case 26:		/* Vector Extract Double Unsigned Halfword to VSR
+			   using GPR-specified Left-Index */
+    case 27:		/* Vector Extract Double Unsigned Halfword to VSR
+			   using GPR-specified Right-Index */
+    case 28:		/* Vector Extract Double Unsigned Word to VSR
+			   using GPR-specified Left-Index */
+    case 29:		/* Vector Extract Double Unsigned Word to VSR
+			   using GPR-specified Right-Index */
+    case 30:		/* Vector Extract Double Unsigned Doubleword to VSR
+			   using GPR-specified Left-Index */
+    case 31:		/* Vector Extract Double Unsigned Doubleword to VSR
+			   using GPR-specified Right-Index */
     case 42:		/* Vector Select */
     case 43:		/* Vector Permute */
     case 59:		/* Vector Permute Right-indexed */
+    case 22: 		/* Vector Shift
+			      Left  Double by Bit Immediate if insn[21] = 0
+			      Right Double by Bit Immediate if insn[21] = 1 */
     case 44:		/* Vector Shift Left Double by Octet Immediate */
     case 45:		/* Vector Permute and Exclusive-OR */
     case 60:		/* Vector Add Extended Unsigned Quadword Modulo */
@@ -4236,6 +4333,9 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
   /* Bit-21 is used for RC */
   switch (ext & 0x3ff)
     {
+    case 5:		/* Vector Rotate Left Quadword */
+    case 69:		/* Vector Rotate Left Quadword then Mask Insert */
+    case 325:		/* Vector Rotate Left Quadword then AND with Mask */
     case 6:		/* Vector Compare Equal To Unsigned Byte */
     case 70:		/* Vector Compare Equal To Unsigned Halfword */
     case 134:		/* Vector Compare Equal To Unsigned Word */
@@ -4244,13 +4344,16 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     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 903:		/* Vector Compare Greater Than Signed Quadword */
     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 647:		/* Vector Compare Greater Than Unsigned Quadword */
     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 455:		/* Vector Compare Equal Quadword */
     case 710:		/* Vector Compare Greater Than Single-Precision */
     case 7:		/* Vector Compare Not Equal Byte */
     case 71:		/* Vector Compare Not Equal Halfword */
@@ -4263,6 +4366,21 @@ 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 13:
+      switch (vra)    /* Bit-21 is used for RC */
+	{
+	case 0:       /* Vector String Isolate Byte Left-justified */
+	case 1:       /* Vector String Isolate Byte Right-justified */
+	case 2:       /* Vector String Isolate Halfword Left-justified */
+	case 3:       /* Vector String Isolate Halfword Right-justified */
+	  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;
+	}
     }
 
   if (ext  == 1538)
@@ -4287,6 +4405,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
 	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 27:	/* Vector Extend Sign Doubleword To Quadword */
 	case 28:	/* Vector Count Trailing Zeros Byte */
 	case 29:	/* Vector Count Trailing Zeros Halfword */
 	case 30:	/* Vector Count Trailing Zeros Word */
@@ -4297,8 +4416,58 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
 	}
     }
 
+  if (ext == 1602)
+    {
+      switch (vra)
+	{
+	case 0: 	/* Vector Expand Byte Mask */
+	case 1: 	/* Vector Expand Halfword Mask */
+	case 2: 	/* Vector Expand Word Mask */
+	case 3: 	/* Vector Expand Doubleword Mask */
+	case 4: 	/* Vector Expand Quadword Mask */
+	case 16:	/* Move to VSR Byte Mask */
+	case 17:	/* Move to VSR Halfword Mask */
+	case 18:	/* Move to VSR Word Mask */
+	case 19:	/* Move to VSR Doubleword Mask */
+	case 20:	/* Move to VSR Quadword Mask */
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+	  return 0;
+
+	case 8: 	/* Vector Extract Byte Mask */
+	case 9: 	/* Vector Extract Halfword Mask */
+	case 10: 	/* Vector Extract Word Mask */
+	case 11: 	/* Vector Extract Doubleword Mask */
+	case 12: 	/* Vector Extract Quadword Mask */
+
+	/* vra field is used as additional opcode field.  Ignore the MP bit in
+	   the LSB position. */
+	case 24:	/* Vector Count Mask Bits Byte */
+	case 25:	/* Vector Count Mask Bits Byte */
+	case 26:	/* Vector Count Mask Bits Halfword */
+	case 27:	/* Vector Count Mask Bits Halfword */
+	case 28:	/* Vector Count Mask Bits Word */
+	case 29:	/* Vector Count Mask Bits Word */
+	case 30:	/* Vector Count Mask Bits Doubleword */
+	case 31:	/* Vector Count Mask Bits Doubleword */
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_gp0_regnum + PPC_RT (insn));
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_gp0_regnum + PPC_RT (insn));
+	  return 0;
+	}
+    }
+
   switch (ext)
     {
+
+    case 257:		/* Vector Compare Unsigned Quadword */
+    case 321:		/* Vector Compare Signed Quadword */
+      /* Comparison tests that always set CR field BF */
+      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;
+
     case 142:		/* Vector Pack Unsigned Halfword Unsigned Saturate */
     case 206:		/* Vector Pack Unsigned Word Unsigned Saturate */
     case 270:		/* Vector Pack Signed Halfword Unsigned Saturate */
@@ -4338,6 +4507,8 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 268:		/* Vector Merge Low Byte */
     case 332:		/* Vector Merge Low Halfword */
     case 396:		/* Vector Merge Low Word */
+    case 397:		/* Vector Clear Leftmost Bytes */
+    case 461:		/* Vector Clear Rightmost Bytes */
     case 526:		/* Vector Unpack High Signed Byte */
     case 590:		/* Vector Unpack High Signed Halfword */
     case 654:		/* Vector Unpack Low Signed Byte */
@@ -4356,8 +4527,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 780:		/* Vector Splat Immediate Signed Byte */
     case 844:		/* Vector Splat Immediate Signed Halfword */
     case 908:		/* Vector Splat Immediate Signed Word */
+    case 261:		/* Vector Shift Left Quadword */
     case 452:		/* Vector Shift Left */
+    case 517:		/* Vector Shift Right Quadword */
     case 708:		/* Vector Shift Right */
+    case 773:		/* Vector Shift Right Algebraic Quadword */
     case 1036:		/* Vector Shift Left by Octet */
     case 1100:		/* Vector Shift Right by Octet */
     case 0:		/* Vector Add Unsigned Byte Modulo */
@@ -4370,15 +4544,43 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 8:		/* Vector Multiply Odd Unsigned Byte */
     case 72:		/* Vector Multiply Odd Unsigned Halfword */
     case 136:		/* Vector Multiply Odd Unsigned Word */
+    case 200:		/* Vector Multiply Odd Unsigned Doubleword */
     case 264:		/* Vector Multiply Odd Signed Byte */
     case 328:		/* Vector Multiply Odd Signed Halfword */
     case 392:		/* Vector Multiply Odd Signed Word */
+    case 456:		/* Vector Multiply Odd Signed Doubleword */
     case 520:		/* Vector Multiply Even Unsigned Byte */
     case 584:		/* Vector Multiply Even Unsigned Halfword */
     case 648:		/* Vector Multiply Even Unsigned Word */
+    case 712:		/* Vector Multiply Even Unsigned Doubleword */
     case 776:		/* Vector Multiply Even Signed Byte */
     case 840:		/* Vector Multiply Even Signed Halfword */
     case 904:		/* Vector Multiply Even Signed Word */
+    case 968:		/* Vector Multiply Even Signed Doubleword */
+    case 457:		/* Vector Multiply Low Doubleword */
+    case 649:		/* Vector Multiply High Unsigned Word */
+    case 713:		/* Vector Multiply High Unsigned Doubleword */
+    case 905:		/* Vector Multiply High Signed Word */
+    case 969:		/* Vector Multiply High Signed Doubleword */
+    case 11:		/* Vector Divide Unsigned Quadword */
+    case 203:		/* Vector Divide Unsigned Doubleword */
+    case 139:		/* Vector Divide Unsigned Word */
+    case 267:		/* Vector Divide Signed Quadword */
+    case 459:		/* Vector Divide Signed Doubleword */
+    case 395:		/* Vector Divide Signed Word */
+    case 523:		/* Vector Divide Extended Unsigned Quadword */
+    case 715:		/* Vector Divide Extended Unsigned Doubleword */
+    case 651:		/* Vector Divide Extended Unsigned Word */
+    case 779:		/* Vector Divide Extended Signed Quadword */
+    case 971:		/* Vector Divide Extended Signed Doubleword */
+    case 907:		/* Vector Divide Extended Unsigned Word */
+    case 1547:		/* Vector Modulo Unsigned Quadword */
+    case 1675:		/* Vector Modulo Unsigned Word */
+    case 1739:		/* Vector Modulo Unsigned Doubleword */
+    case 1803:		/* Vector Modulo Signed Quadword */
+    case 1931:		/* Vector Modulo Signed Word */
+    case 1995:		/* Vector Modulo Signed Doubleword */
+
     case 137:		/* Vector Multiply Unsigned Word Modulo */
     case 1024:		/* Vector Subtract Unsigned Byte Modulo */
     case 1088:		/* Vector Subtract Unsigned Halfword Modulo */
@@ -4462,7 +4664,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 1794:		/* Vector Count Leading Zeros Byte */
     case 1858:		/* Vector Count Leading Zeros Halfword */
     case 1922:		/* Vector Count Leading Zeros Word */
+    case 1924:		/* Vector Count Leading Zeros Doubleword under
+			   bit Mask*/
     case 1986:		/* Vector Count Leading Zeros Doubleword */
+    case 1988:		/* Vector Count Trailing Zeros Doubleword under bit
+			   Mask */
     case 1795:		/* Vector Population Count Byte */
     case 1859:		/* Vector Population Count Halfword */
     case 1923:		/* Vector Population Count Word */
@@ -4488,14 +4694,50 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 589:		/* Vector Extract Unsigned Halfword */
     case 653:		/* Vector Extract Unsigned Word */
     case 717:		/* Vector Extract Doubleword */
+    case 15:		/* Vector Insert Byte from VSR using GPR-specified
+			   Left-Index */
+    case 79:		/* Vector Insert Halfword from VSR using GPR-specified
+			   Left-Index */
+    case 143:		/* Vector Insert Word from VSR using GPR-specified
+			   Left-Index */
+    case 207:		/* Vector Insert Word from GPR using
+			   immediate-specified index */
+    case 463:		/* Vector Insert Doubleword from GPR using
+			   immediate-specified index */
+    case 271:		/* Vector Insert Byte from VSR using GPR-specified
+			   Right-Index */
+    case 335:		/* Vector Insert Halfword from VSR using GPR-specified
+			   Right-Index */
+    case 399:		/* Vector Insert Word from VSR using GPR-specified
+			   Right-Index */
+    case 527:		/* Vector Insert Byte from GPR using GPR-specified
+			   Left-Index */
+    case 591:		/* Vector Insert Halfword from GPR using GPR-specified
+			   Left-Index */
+    case 655:		/* Vector Insert Word from GPR using GPR-specified
+			   Left-Index */
+    case 719:		/* Vector Insert Doubleword from GPR using
+			    GPR-specified Left-Index */
+    case 783:		/* Vector Insert Byte from GPR using GPR-specified
+			   Right-Index */
+    case 847:		/* Vector Insert Halfword from GPR using GPR-specified
+			   Left-Index */
+    case 911:		/* Vector Insert Word from GPR using GPR-specified
+			   Left-Index */
+    case 975:		/* Vector Insert Doubleword from GPR using
+			    GPR-specified Right-Index */
     case 781:		/* Vector Insert Byte */
     case 845:		/* Vector Insert Halfword */
     case 909:		/* Vector Insert Word */
     case 973:		/* Vector Insert Doubleword */
+    case 1357:		/* Vector Centrifuge Doubleword */
+    case 1421:		/* Vector Parallel Bits Extract Doubleword */
+    case 1485:		/* Vector Parallel Bits Deposit Doubleword */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
       return 0;
 
+    case 1228:		/* Vector Gather every Nth Bit */
     case 1549:		/* Vector Extract Unsigned Byte Left-Indexed */
     case 1613:		/* Vector Extract Unsigned Halfword Left-Indexed */
     case 1677:		/* Vector Extract Unsigned Word Left-Indexed */
@@ -4525,6 +4767,34 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record instructions of primary opcode 6 at ADDR.
+   Return 0 if successful.  */
+
+static int
+ppc_process_record_op6 (struct gdbarch *gdbarch, struct regcache *regcache,
+			CORE_ADDR addr, uint32_t insn)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int subtype = PPC_FIELD (insn, 28, 4);
+  CORE_ADDR ea = 0;
+
+  switch (subtype)
+    {
+    case 0:    /* Load VSX Vector Paired */
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
+      return 0;
+    case 1:    /* Store VSX Vector Paired */
+      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, 32);
+      return 0;
+    }
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-19 at ADDR.
    Return 0 if successful.  */
 
@@ -4577,6 +4847,30 @@ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record instructions of primary opcode-31 with the extended opcode
+   177.  The argument is the word instruction (insn).  Return 0 if successful.
+*/
+
+static int
+ppc_process_record_op31_177 (struct gdbarch *gdbarch,
+			     struct regcache *regcache,
+			     uint32_t insn)
+{
+  int RA_opcode = PPC_RA(insn);
+  int as = PPC_FIELD (insn, 6, 3);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  switch (RA_opcode)
+    {
+    case 0: 		/* VSX Move From Accumulator, xxmfacc */
+    case 1: 		/* VSX Move To Accumulator, xxmtacc */
+    case 3: 		/* VSX Set Accumulator to Zero, xxsetaccz */
+      ppc_record_ACC_fpscr (regcache, tdep, as, DO_NOT_RECORD_FPSCR);
+      return 0;
+    }
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-31 at ADDR.
    Return 0 if successful.  */
 
@@ -4586,7 +4880,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
-  int tmp, nr, nb, i;
+  int tmp, nr, nb = 0, i;
   CORE_ADDR at_dcsz, ea = 0;
   ULONGEST rb, ra, xer;
   int size = 0;
@@ -4677,6 +4971,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 371:		/* Move From Time Base [Phased-Out]  */
     case 309:		/* Load Doubleword Monitored Indexed  */
     case 128:		/* Set Boolean */
+    case 384:		/* Set Boolean Condition */
+    case 416:		/* Set Boolean Condition Reverse */
+    case 448:		/* Set Negative Boolean Condition */
+    case 480:		/* Set Negative Boolean Condition Reverse */
     case 755:		/* Deliver A Random Number */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_gp0_regnum + PPC_RT (insn));
@@ -4684,8 +4982,15 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 
     /* These only write to RA.  */
     case 51:		/* Move From VSR Doubleword */
+    case 59:		/* Count Leading Zeros Doubleword under bit Mask */
     case 115:		/* Move From VSR Word and Zero */
     case 122:		/* Population count bytes */
+    case 155:		/* Byte-Reverse Word */
+    case 156:		/* Parallel Bits Deposit Doubleword */
+    case 187:		/* Byte-Reverse Doubleword */
+    case 188:		/* Parallel Bits Extract Doubleword */
+    case 219:		/* Byte-Reverse Halfword */
+    case 220:		/* Centrifuge Doubleword */
     case 378:		/* Population count words */
     case 506:		/* Population count doublewords */
     case 154:		/* Parity Word */
@@ -4695,6 +5000,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 314:		/* Convert Binary Coded Decimal To Declets */
     case 508:		/* Compare bytes */
     case 307:		/* Move From VSR Lower Doubleword */
+    case 571:		/* Count Trailing Zeros Doubleword under bit Mask */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_gp0_regnum + PPC_RA (insn));
       return 0;
@@ -4819,6 +5125,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache, tmp + 1);
       return 0;
 
+    /* These write RT. */
     case 179:		/* Move To VSR Doubleword */
     case 211:		/* Move To VSR Word Algebraic */
     case 243:		/* Move To VSR Word and Zero */
@@ -4826,6 +5133,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     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 13:		/* Load VSX Vector Rightmost Byte Indexed */
+    case 45:		/* Load VSX Vector Rightmost Halfword Indexed */
+    case 77:		/* Load VSX Vector Rightmost Word Indexed */
+    case 109:		/* Load VSX Vector Rightmost Doubleword 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 */
@@ -4842,6 +5153,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
 
+    case 333:		/* Load VSX Vector Paired Indexed */
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
+      return 0;
+
     /* These write RA.  Update CR if RC is set.  */
     case 24:		/* Shift Left Word */
     case 26:		/* Count Leading Zeros Word */
@@ -5006,6 +5322,31 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_mem (ea, size);
       return 0;
 
+    case 141:		/* Store VSX Vector Rightmost Byte Indexed */
+    case 173:		/* Store VSX Vector Rightmost Halfword Indexed */
+    case 205:		/* Store VSX Vector Rightmost Word Indexed */
+    case 237:		/* Store VSX Vector Rightmost Doubleword Indexed */
+      switch(ext)
+	{
+	  case 141: nb = 1;
+	  break;
+	  case 173: nb = 2;
+	  break;
+	  case 205: nb = 4;
+	  break;
+	  case 237: nb = 8;
+	  break;
+	}
+      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;
+      record_full_arch_list_add_mem (ea, nb);
+      return 0;
+
     case 397:		/* Store VSX Vector with Length */
     case 429:		/* Store VSX Vector Left-justified with Length */
       ra = 0;
@@ -5021,6 +5362,19 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 	record_full_arch_list_add_mem (ea, nb);
       return 0;
 
+    case 461:		/* Store VSX Vector Paired Indexed */
+      {
+	if (PPC_RA (insn) != 0)
+	  regcache_raw_read_unsigned (regcache,
+				      tdep->ppc_gp0_regnum
+				      + PPC_RA (insn), &ea);
+	regcache_raw_read_unsigned (regcache,
+				    tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
+	ea += rb;
+	record_full_arch_list_add_mem (ea, 32);
+	return 0;
+      }
+
     case 710:		/* Store Word Atomic */
     case 742:		/* Store Doubleword Atomic */
       ra = 0;
@@ -5166,6 +5520,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       ea = (ra + rb) & ~((ULONGEST) (at_dcsz - 1));
       record_full_arch_list_add_mem (ea, at_dcsz);
       return 0;
+
+    case 177:
+      if (ppc_process_record_op31_177 (gdbarch, regcache, insn) == 0)
+	return 0;
     }
 
 UNKNOWN_OP:
@@ -5179,10 +5537,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 
 static int
 ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
-			   CORE_ADDR addr, uint32_t insn)
+			 CORE_ADDR addr, uint32_t insn)
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
+  int at = PPC_FIELD (insn, 6, 3);
 
   switch (ext & 0x1f)
     {
@@ -5206,6 +5565,75 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
+  /* MMA instructions, if no match keep looking.  */
+  switch (ext >> 2)    /* Additioanl opcode field is upper 8-bits of ext */
+    {
+    case 3:	/* VSX Vector 8-bit Signed/Unsigned Integer GER, xvi8ger4 */
+    case 2:	/* VSX Vector 8-bit Signed/Unsigned Integer GER Positive
+		   multiply, Positive accumulate, xvi8ger4pp */
+
+    case 99:	/* VSX Vector 8-bit Signed/Unsigned Integer GER with
+		   Saturate Positive multiply, Positive accumulate,
+		   xvi8ger4spp */
+
+    case 35:	/* VSX Vector 4-bit Signed Integer GER, xvi4ger8 */
+    case 34:	/* VSX Vector 4-bit Signed Integer GER Positive multiply,
+		   Positive accumulate, xvi4ger8pp */
+
+    case 75:	/* VSX Vector 16-bit Signed Integer GER, xvi16ger2 */
+    case 107:	/* VSX Vector 16-bit Signed Integer GER  Positive multiply,
+		   Positive accumulate, xvi16ger2pp */
+
+    case 43:	/* VSX Vector 16-bit Signed Integer GER with Saturation,
+		   xvi16ger2s */
+    case 42:	/* VSX Vector 16-bit Signed Integer GER with Saturation
+		   Positive multiply, Positive accumulate, xvi16ger2spp */
+      ppc_record_ACC_fpscr (regcache, tdep, at, DO_NOT_RECORD_FPSCR);
+      return 0;
+
+    case 19:	/* VSX Vector 16-bit Floating-Point GER, xvf16ger2 */
+    case 18:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf16ger2pp */
+    case 146:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf16ger2pn */
+    case 82:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf16ger2np */
+    case 210:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
+		   Negative accumulate, xvf16ger2nn */
+
+    case 27:	/* VSX Vector 32-bit Floating-Point GER, xvf32ger */
+    case 26:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf32gerpp */
+    case 154:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf32gerpn */
+    case 90:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf32gernp */
+    case 218:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
+		   Negative accumulate, xvf32gernn */
+
+    case 59:	/* VSX Vector 64-bit Floating-Point GER */
+    case 58:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf64gerpp */
+    case 186:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf64gerpn */
+    case 122:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf64gernp */
+    case 250:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
+		   Negative accumulate */
+
+    case 51:	/* VSX Vector bfloat16 GER, xvbf16ger2 */
+    case 50:	/* VSX Vector bfloat16 GER Positive multiply,
+		   Positive accumulate, xvbf16ger2pp */
+    case 178:	/* VSX Vector bfloat16 GER Positive multiply,
+		   Negative accumulate, xvbf16ger2pn */
+    case 114:	/* VSX Vector bfloat16 GER Negative multiply,
+		   Positive accumulate, xvbf16ger2np */
+    case 242:	/* VSX Vector bfloat16 GER Negative multiply,
+		   Negative accumulate, xvbf16ger2nn */
+      ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
+      return 0;
+    }
+
   switch (ext)
     {
     case 2:		/* DFP Add */
@@ -5268,6 +5696,48 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record instructions of primary opcode-60 form XXX at ADDR.  The
+   word instruction is in argument insn.  Return 0 if successful.  */
+
+static int
+ppc_process_record_op60_XX2 (struct gdbarch *gdbarch,
+			     struct regcache *regcache,
+			     CORE_ADDR addr, uint32_t insn)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int RA_opcode = PPC_RA(insn);
+
+  switch (RA_opcode)
+    {
+    case 2:	/* VSX Vector Test Least-Significant Bit by Byte */
+    case 25:	/* VSX Vector round and Convert Single-Precision format
+		   to Half-Precision format.  Only changes the CR
+		   field.  */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+    case 17:	/* VSX Vector Convert with round Single-Precision
+		   to bfloat16 format */
+    case 24:	/* VSX Vector Convert Half-Precision format to
+		   Single-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 16:	/* VSX Vector Convert bfloat16 to Single-Precision
+		   format Non-signaling */
+    case 23:	/* VSX Vector Byte-Reverse Doubleword */
+    case 31:	/* VSX Vector Byte-Reverse Quadword */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
+    }
+
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-60 at ADDR.
    Return 0 if successful.  */
 
@@ -5583,37 +6053,30 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
       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;
+      if (ppc_process_record_op60_XX2 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      return 0;
     }
 
   switch (ext)
     {
-    case 360:		/* VSX Vector Splat Immediate Byte */
-      if (PPC_FIELD (insn, 11, 2) == 0)
+    case 360:
+      if (PPC_FIELD (insn, 11, 2) == 0)  /* VSX Vector Splat Immediate Byte */
+	{
+	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+	  return 0;
+	}
+      if (PPC_FIELD (insn, 11, 5) == 31)  /* Load VSX Vector Special Value
+					     Quadword */
 	{
 	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
 	  return 0;
 	}
       break;
+    case 916:		/* VSX Vector Generate PCV from Byte Mask */
+    case 917:		/* VSX Vector Generate PCV from Halfword Mask */
+    case 948:		/* VSX Vector Generate PCV from Word Mask */
+    case 949:		/* VSX Vector Generate PCV from Word Mask */
     case 918:		/* VSX Scalar Insert Exponent Double-Precision */
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
@@ -5894,6 +6357,35 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
 			   Quad-Precision */
     case 516:		/* VSX Scalar Subtract Quad-Precision */
     case 548:		/* VSX Scalar Divide Quad-Precision */
+    case 994:
+      {
+      switch (PPC_FIELD (insn, 11, 5))
+	{
+	case 0:	/* DFP Convert From Fixed Quadword Quad */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_fp0_regnum
+					 + PPC_FRT (insn));
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_fp0_regnum
+					 + PPC_FRT (insn) + 1);
+	  return 0;
+	case 1:	/* DFP Convert To Fixed Quadword Quad */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+	  return 0;
+	}
+      }
+
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
+    case 68:		/* VSX Scalar Compare Equal Quad-Precision */
+    case 196:		/* VSX Scalar Compare Greater Than or Equal
+			   Quad-Precision */
+    case 228:		/* VSX Scalar Compare Greater Than Quad-Precision */
+    case 676:		/* VSX Scalar Maximum Type-C Quad-Precision */
+    case 740:		/* VSX Scalar Minimum Type-C Quad-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       /* FALL-THROUGH */
     case 100:		/* VSX Scalar Copy Sign Quad-Precision */
@@ -5920,14 +6412,22 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 836:
       switch (PPC_FIELD (insn, 11, 5))
 	{
+	case 0:		/* VSX Scalar Convert with round to zero
+			   Quad-Precision to Unsigned Quadword  */
 	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 3:		/* VSX Scalar Convert with round
+			   Unsigned Quadword to Quad-Precision  */
+	case 8:		/* VSX Scalar Convert with round to zero
+			   Quad-Precision to Signed Quadword  */
 	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 11:	/* VSX Scalar Convert with round
+			   Signed Quadword to Quad-Precision */
 	case 17:	/* VSX Scalar truncate & Convert Quad-Precision format
 			   to Unsigned Doubleword format */
 	case 20:	/* VSX Scalar round & Convert Quad-Precision format to
@@ -5947,17 +6447,651 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Record the prefixed instructions with primary opcode 32.  The arguments are
+   the first 32-bits of the instruction (insn_prefix), and the second 32-bits
+   of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op42 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if (ST1 != 0)
+    return -1;
+
+  switch (type)
+    {
+    case 0:  /* Prefixed Load VSX Scalar Doubleword, plxsd */
+      ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
+      break;
+    case 2:  /* Prefixed Load Halfword Algebraic, plha */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum
+				     + PPC_RT (insn_suffix));
+      break;
+    default:
+      return -1;
+    }
+  return 0;
+}
+
+/* Record the prefixed instructions with primary opcode 59 of type XX3.  The
+   arguments are the first 32-bits of the instruction (insn_prefix), and the
+   second 32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op59_XX3 (struct gdbarch *gdbarch,
+				    struct regcache *regcache,
+				    uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int opcode = PPC_FIELD (insn_suffix, 21, 8);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  int at = PPC_FIELD (insn_suffix, 6, 3);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 3)
+    {
+      if (ST4 == 9)
+	switch (opcode)
+	  {
+	  case 35:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
+			   MMIRR, pmxvi4ger8 */
+	  case 34:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
+			   MMIRR, pmxvi4ger8pp */
+
+	  case 99:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER with Saturate Positive multiply,
+			   Positive accumulate, xvi8ger4spp */
+
+	  case 3:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER MMIRR, pmxvi8ger4 */
+	  case 2:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER Positive multiply, Positive accumulate
+			   MMIRR, pmxvi8ger4pp */
+
+	  case 75:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER MMIRR, pmxvi16ger2 */
+	  case 107:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER  Positive multiply, Positive accumulate,
+			   pmxvi16ger2pp */
+
+	  case 43:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER with Saturation MMIRR, pmxvi16ger2s */
+	  case 42:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER with Saturation Positive multiply, Positive
+			   accumulate MMIRR, pmxvi16ger2spp */
+	    ppc_record_ACC_fpscr (regcache, tdep, at, DO_NOT_RECORD_FPSCR);
+	    return 0;
+
+	  case 19:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER MMIRR, pmxvf16ger2 */
+	  case 18:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Positive multiply, Positive accumulate MMIRR,
+			   pmxvf16ger2pp */
+	  case 146:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf16ger2pn */
+	  case 82:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf16ger2np */
+	  case 210:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf16ger2nn */
+
+	  case 27:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER MMIRR, pmxvf32ger */
+	  case 26:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Positive multiply, Positive accumulate MMIRR,
+			   pmxvf32gerpp */
+	  case 154:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf32gerpn */
+	  case 90:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf32gernp */
+	  case 218:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf32gernn */
+
+	  case 59:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER MMIRR, pmxvf64ger */
+	  case 58:	/* Floating-Point GER Positive multiply, Positive
+			   accumulate MMIRR, pmxvf64gerpp */
+	  case 186:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf64gerpn */
+	  case 122:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf64gernp */
+	  case 250:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf64gernn */
+
+	  case 51:	/* Prefixed Masked VSX Vector bfloat16 GER MMIRR,
+			   pmxvbf16ger2 */
+	  case 50:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
+			   multiply, Positive accumulate MMIRR,
+			   pmxvbf16ger2pp */
+	  case 178:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
+			   multiply, Negative accumulate MMIRR,
+			   pmxvbf16ger2pn */
+	  case 114:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
+			   multiply, Positive accumulate MMIRR,
+			   pmxvbf16ger2np */
+	  case 242:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
+			   multiply, Negative accumulate MMIRR,
+			   pmxvbf16ger2nn */
+	    ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
+	    return 0;
+	  }
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed store instructions.  The arguments are the instruction
+   address, the first 32-bits of the instruction(insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_store (struct gdbarch *gdbarch,
+				 struct regcache *regcache,
+				 CORE_ADDR addr, uint32_t insn_prefix,
+				 uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST iaddr = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int op6 = PPC_OP6 (insn_suffix);
+
+  if (R == 0)
+    {
+      if (PPC_RA (insn_suffix) != 0)
+	regcache_raw_read_unsigned (regcache, tdep->ppc_gp0_regnum
+				    + PPC_RA (insn_suffix), &iaddr);
+    }
+  else
+    {
+      iaddr = addr;     /* PC relative */
+    }
+
+  switch (op6)
+    {
+    case 38:
+      size =  1;    /* store byte, pstb */
+      break;
+    case 44:
+      size =  2;    /* store halfword, psth */
+      break;
+    case 36:
+    case 52:
+      size =  4;    /* store word, pstw, pstfs */
+      break;
+    case 54:
+    case 61:
+      size =  8;    /* store double word, pstd, pstfd */
+      break;
+    case 60:
+      size = 16;    /* store quadword, pstq */
+      break;
+    default: return -1;
+    }
+
+  iaddr += P_PPC_D (insn_prefix, insn_suffix);
+  record_full_arch_list_add_mem (iaddr, size);
+  return 0;
+}
+
+/* Record the prefixed instructions with primary op code 32.  The arguments
+   are the first 32-bits of the instruction(insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op32 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1)
+    {
+      if (ST4 == 0)
+	{
+	  switch (PPC_FIELD (insn_suffix, 11, 3))
+	    {
+	    case 0:  	/* VSX Vector Splat Immediate Word 8RR, xxsplti32dx */
+	      ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
+	      return 0;
+	    }
+
+	  switch (PPC_FIELD (insn_suffix, 11, 4))
+	    {
+	    case 2:  	/* VSX Vector Splat Immediate Double-Precision
+			   8RR, xxspltidp */
+	    case 3:  	/* VSX Vector Splat Immediate Word 8RR, xxspltiw */
+	      ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
+	      return 0;
+	    default:
+	      return -1;
+	    }
+	}
+      else
+	return -1;
+
+    }
+  else if (type == 2)
+    {
+      if (ST1 == 0)  		/* Prefixed Load Word and Zero, plwz */
+	record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	return -1;
+
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed instructions with primary op code 33.  The arguments
+   are the first 32-bits of the instruction(insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op33 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1)
+    {
+      if (ST4 == 0)
+	switch (PPC_FIELD (insn_suffix, 26, 2))
+	  {
+	  case 0:  	/* VSX Vector Blend Variable Byte 8RR, xxblendvb */
+	  case 1:  	/* VSX Vector Blend Variable Halfword, xxblendvh */
+	  case 2:  	/* VSX Vector Blend Variable Word, xxblendvw */
+	  case 3:  	/* VSX Vector Blend Variable Doubleword, xxblendvd */
+	    ppc_record_vsr (regcache, tdep, PPC_XT (insn_suffix));
+	  break;
+	  default:
+	    return -1;
+	  }
+      else
+	return -1;
+
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed instructions with primary op code 34.  The arguments
+   are the first 32-bits of the instruction(insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op34 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1)
+    {
+      if (ST4 == 0)
+	switch (PPC_FIELD (insn_suffix, 26, 2))
+	  {
+	  case 0:  	/* VSX Vector Permute Extended 8RR, xxpermx */
+	  case 1:  	/* VSX Vector Evaluate 8RR, xxeval */
+	    ppc_record_vsr (regcache, tdep, P_PPC_XT (insn_suffix));
+	    break;
+	  default:
+	    return -1;
+	  }
+      else
+	return -1;
+
+    }
+  else if (type == 2)
+    {
+      if (ST1 == 0)  		/* Prefixed Load Word and Zero, plbz */
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	return -1;
+
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed VSX store, form DS, instructions.  The arguments are the
+   instruction address (addr), the first 32-bits of the instruction
+   (insn_prefix) followed by the 32-bit instruction suffix (insn_suffix).
+   Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_store_vsx_ds_form (struct gdbarch *gdbarch,
+					     struct regcache *regcache,
+					     CORE_ADDR addr,
+					     uint32_t insn_prefix,
+					     uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST ea = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if ((type == 0) && (ST1 == 0))
+    {
+      if (R == 0)
+	{
+	  if (PPC_RA (insn_suffix) != 0)
+	    regcache_raw_read_unsigned (regcache,
+					tdep->ppc_gp0_regnum
+					+ PPC_RA (insn_suffix),
+					&ea);
+	}
+      else
+	{
+	  ea = addr;     /* PC relative */
+	}
+
+      ea += P_PPC_D (insn_prefix, insn_suffix);
+      switch (PPC_FIELD (insn_suffix, 0, 6))
+	{
+	case 46:    /* Prefixed Store VSX Scalar Doubleword, pstxsd */
+	  size = 8;
+	  break;
+	case 47:    /* Prefixed,Store VSX Scalar Single-Precision, pstxssp */
+	  size = 4;
+	  break;
+	default:
+	  return -1;
+	}
+      record_full_arch_list_add_mem (ea, size);
+      return 0;
+  }
+  else
+    return -1;
+}
+
+/* Record the prefixed VSX, form D, instructions.  The arguments are the
+   instruction address for PC-relative addresss (addr), the first 32-bits of
+   the instruction (insn_prefix) and the following 32-bits of the instruction
+   (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_vsx_d_form (struct gdbarch *gdbarch,
+				      struct regcache *regcache,
+				      CORE_ADDR addr,
+				      uint32_t insn_prefix,
+				      uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST ea = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if ((type == 0) && (ST1 == 0))
+    {
+      switch (PPC_FIELD (insn_suffix, 0, 5))
+	{
+	case 25:	/* Prefixed Load VSX Vector, plxv */
+	  ppc_record_vsr (regcache, tdep, P_PPC_XT5 (insn_prefix));
+	  return 0;
+	case 27:	/* Prefixed Store VSX Vector 8LS, pstxv */
+	  {
+	    size = 16;
+	    if (R == 0)
+	      {
+		if (PPC_RA (insn_suffix) != 0)
+		  regcache_raw_read_unsigned (regcache,
+					      tdep->ppc_gp0_regnum
+					      + PPC_RA (insn_suffix),
+					      &ea);
+	      }
+	    else
+	      {
+		ea = addr;     /* PC relative */
+	      }
+
+	    ea += P_PPC_D (insn_prefix, insn_suffix);
+	    record_full_arch_list_add_mem (ea, size);
+	    return 0;
+	  }
+	}
+      return -1;
+    }
+  else
+    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.  */
 
+/* This is the main function for handling the recording of the various prefix
+   instructions.  It takes the instruction address, the first 32-bits of the
+   instruction (insn_prefix) and the following 32-bits of the instruction
+   (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_prefix_instruction (int insn_prefix, int insn_suffix,
+				CORE_ADDR addr,	struct gdbarch *gdbarch,
+				struct regcache *regcache)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int op6;
+
+  /* D-form has uses a 5-bit opcode in the instruction suffix */
+  if (ppc_process_record_prefix_vsx_d_form ( gdbarch, regcache, addr,
+					     insn_prefix, insn_suffix) == 0)
+    goto SUCCESS;
+
+  op6 = PPC_OP6 (insn_suffix);  /* 6-bit opcode in the instruction suffix */
+
+  switch (op6)
+    {
+    case 14:		/* Prefixed Add Immediate, paddi */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 32:
+      if (ppc_process_record_prefix_op32 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 33:
+      if (ppc_process_record_prefix_op33 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 34:		/* Prefixed Load Byte and Zero, plbz */
+      if (ppc_process_record_prefix_op34 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+    case 40:		/* Prefixed Load Halfword and Zero, plhz */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+      break;
+
+    case 36:		/* Prefixed Store Word, pstw */
+    case 38:		/* Prefixed Store Byte, pstb */
+    case 44:		/* Prefixed Store Halfword, psth */
+    case 52:		/* Prefixed Store Floating-Point Single, pstfs */
+    case 54:		/* Prefixed Store Floating-Point Double, pstfd */
+    case 60:		/* Prefixed Store Quadword, pstq */
+    case 61:		/* Prefixed Store Doubleword, pstd */
+      if (ppc_process_record_prefix_store (gdbarch, regcache, addr,
+					   insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 42:
+      if (ppc_process_record_prefix_op42 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 43:          /* Prefixed Load VSX Scalar Single-Precision, plxssp */
+      if ((type == 0) && (ST1 == 0))
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
+      else
+	  goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 46:
+    case 47:
+      if (ppc_process_record_prefix_store_vsx_ds_form (gdbarch, regcache, addr,
+					       insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 56:		/* Prefixed Load Quadword, plq */
+      {
+	if ((type == 0) && (ST1 == 0))
+	  {
+	    int tmp;
+	    tmp = tdep->ppc_gp0_regnum + (PPC_RT (insn_suffix) & ~1);
+	    record_full_arch_list_add_reg (regcache, tmp);
+	    record_full_arch_list_add_reg (regcache, tmp + 1);
+	  }
+	else
+	  goto UNKNOWN_PREFIX_OP;
+	break;
+      }
+
+    case 41:		/* Prefixed Load Word Algebraic, plwa */
+    case 57:  		/* Prefixed Load Doubleword, pld */
+      if ((type == 0) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 48:		/* Prefixed Load Floating-Point Single, plfs */
+    case 50:		/* Prefixed Load Floating-Point Double, plfd */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_fp0_regnum
+				       + PPC_FRT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 58:		/* Prefixed Load VSX Vector Paired, plxvp */
+      if ((type == 0) && (ST1 == 0))
+	{
+	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix));
+	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix) + 1);
+	}
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 59:
+      if (ppc_process_record_prefix_op59_XX3 (gdbarch, regcache, insn_prefix,
+					      insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 62:	    /* Prefixed Store VSX Vector Paired 8LS, pstxvp */
+      if ((type == 0) && (ST1 == 0))
+	{
+	  int R = PPC_BIT (insn_prefix, 11);
+	  CORE_ADDR ea = 0;
+
+	  if (R == 0)
+	    {
+	      if (PPC_RA (insn_suffix) != 0)
+		regcache_raw_read_unsigned (regcache,
+					    tdep->ppc_gp0_regnum
+					    + PPC_RA (insn_suffix), &ea);
+	    }
+	  else
+	    {
+	      ea = addr;     /* PC relative */
+	    }
+
+	  ea += P_PPC_D (insn_prefix, insn_suffix) << 4;
+	  record_full_arch_list_add_mem (ea, 32);
+	}
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    default:
+    UNKNOWN_PREFIX_OP:
+      gdb_printf (gdb_stdlog,
+		  "Warning: Don't know how to record prefix inst "
+		  "%08x %08x at %s, %d.\n",
+		  insn_prefix, insn_suffix, paddress (gdbarch, addr),
+		  op6);
+      return -1;
+    }
+
+ SUCCESS:
+  if (record_full_arch_list_add_reg (regcache, PPC_PC_REGNUM))
+    return -1;
+
+  if (record_full_arch_list_add_end ())
+    return -1;
+  return 0;
+}
+
 int
 ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 		      CORE_ADDR addr)
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  uint32_t insn;
+  uint32_t insn, insn_suffix;
   int op6, tmp, i;
 
   insn = read_memory_unsigned_integer (addr, 4, byte_order);
@@ -5965,6 +7099,13 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 
   switch (op6)
     {
+    case 1:		/* prefixed instruction */
+      {
+	/* Get the lower 32-bits of the prefixed instruction. */
+	insn_suffix = read_memory_unsigned_integer (addr+4, 4, byte_order);
+	return ppc_process_prefix_instruction (insn, insn_suffix, addr,
+					       gdbarch, regcache);
+      }
     case 2:		/* Trap Doubleword Immediate */
     case 3:		/* Trap Word Immediate */
       /* Do nothing.  */
@@ -5975,6 +7116,11 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 	return -1;
       break;
 
+    case 6:
+      if (ppc_process_record_op6 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      break;
+
     case 17:		/* System call */
       if (PPC_LEV (insn) != 0)
 	goto UNKNOWN_OP;
-- 
2.31.1



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/2 Version 2] Add recording support for the ISA 3.1 Powerpc instructions
  2022-03-06 12:42   ` Joel Brobecker
@ 2022-04-12 17:09     ` Carl Love
  2022-04-13 14:12       ` will schmidt
  0 siblings, 1 reply; 25+ messages in thread
From: Carl Love @ 2022-04-12 17:09 UTC (permalink / raw)
  To: Joel Brobecker, gdb-patches, cel
  Cc: Ulrich Weigand, Tulio Magno, Rogerio Alves

Joel, GDB maintainers:

On Sun, 2022-03-06 at 16:42 +0400, Joel Brobecker via Gdb-patches
wrote:

<snip>

> I am not a specialist of writing testcases in the GDB testsuite,
> anymore, so others may have more comments. In the meantime, here
> are the things I saw.
> 
> FWIW, the description you provide at the start of this email would
> also be useful to have in the commit message as well, to give people
> a record of what you did without having to read your email version.
> 

I believe you are referring to the testing of the patch.  Added the
testing to the commit message.

> One general note: The formatting seems to have been affected by
> the sending, which surprises me a little, as this was sent by
> "git send-email", is that right? What makes me say this is because
> we see a number of lines where it looks like the text was moved
> to the next line. E.g.
> 
> > +###### Test 1:  Test an ISA 2.06 load (lxvd2x) and square root
> > instructiion
> > +###### (xvsqrtsp).  The load instruction will load vs1.  The sqrt
> > instruction
> 
> I'm going to assume this is correct in your patch, but it would
> be nice to figure out where this is coming from.
> 
That was my screw up on setting the formatting in the email message. 
Fixed.

> 
> > +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
> 
> Can you please add a copyright header to this file, and more
> generally, to all new files?

Fixed.

> 
> > +/* globals used for vector tests */
> > +static vector unsigned long vec_xa, vec_xb, vec_xt;
> > +static unsigned long ra, rb, rs;
> > +
> > +int main () {

Fixed.

<snip?
> 
> > +# The basic flow of the record tests are:
> > +#    1) Stop before executing the instructions of interest. Record
> 
> Missing second space after period.

fixed.
> 
> > +standard_testfile ppc_record_test_isa_2_06.c
> 
> Just thinking out loud: Wondering if ppc_record_test_isa_2_06.c
> is actually needed, here...

Nope, removed the name of the source code file in both test files. 
Seems to work without explicitly giving the source file name.

> 
> > +if ![runto_main] then {
> > +    perror "couldn't run to breakpoint"
> > +    continue
> > +}
> 
> For this block, let's follow what our testcase template
> recommends:

Fixed.


<snip>

> 
> Here and below, can you make sure there is a space between
> the "#" and the start of the text. Also, can you start them
> with an upper-case letter in this case, and end the sentence
> with a period? This is mandated by the GNU Coding Style.

Fixed.

> 
> > +# Change execution direction to forward for next test
> > +gdb_test "set exec-direction forward" "" "Start forward test2"
> > +#gdb_test_no_output "set exec-direction forward"
> 
> Can you removed this commented-out line? I don't think we need
> to keep it.

Removed in both files.

> 
> > +gdb_test "record stop" ".*Process record is stopped.*" "Stopped
> > recording"
> > +set test_del_bkpts "delete breakpoints, answer prompt"
> > +gdb_test_multiple "delete breakpoints" $test_del_bkpts {
> > +    -re "Delete all breakpoints.*y or n.*$" {
> > +	send_gdb "y\n"
> > +    }
> > +}
> > +
> > +gdb_test "record" "" "Start recording test2"
> 
> Is this part needed? There doesn't seem anything done after,
> so I'm wondering what the purpose of this test is.

Not needed, didn't get cleaned up when I split the test into separate
ISA 2.06 and an ISA 3.1 tests.
> 
> (note: if needed, we should use gdb_test_no_output instead)
> 
> > +if ![runto_main] then {
> > +    perror "couldn't run to breakpoint"
> > +    continue
> > +}
> 
Fixed

> Same as above.
> 
> > +#check initial and new of r0 are different
> 
> Here and below, same as above.
> > +# Change execution direction to forward for next test
> > +gdb_test "set exec-direction forward" "" "Start forward test3"
> > +#gdb_test_no_output "set exec-direction forward"

Fixed

> 
> Same as above, can you remove this commented-out line, please?

Fixed

> 
> > +gdb_test "record stop" ".*Process record is stopped.*" "Stopped
> > recording 2"
> > +set test_del_bkpts "delete breakpoints, answer prompt 2"
> > +gdb_test_multiple "delete breakpoints" $test_del_bkpts {
> > +    -re "Delete all breakpoints.*y or n.*$" {
> > +	send_gdb "y\n"
> > +    }
> > +}
> 
> I think you can simplify the above using something like:
> 
>    with confirm off -- delete breakpoints

Above replaced with:

# Delete all breakpoints and catchpoints.
delete_breakpoints

Patch retested on Power 10 with no regressions.

Please let me know if the patch looks ok now.

                                   Carl Love
--------------------------------------------------------------
GDB Powerpc record test cases for ISA 2.06 and ISA 3.1

This patch adds Powerpc specific tests to verify recording of various
instructions.  The first test case checks a couple of ISA 2.06 instructions.
The second test case tests several of the ISA 3.01 instructions.  Specifically,
it checks the word and prefixed instructions and some of the Matrix
Multiply Assist (MMA) instructions.

The patch has been run on both Power 10 and Power 9 to verify the ISA
2.06 test case runs on both platforms without errors.  The ISA 3.1 test
runs without errors on Power 10 and is skipped as expected on Power 9.
---
 .../gdb.reverse/ppc_record_test_isa_2_06.c    |  48 ++
 .../gdb.reverse/ppc_record_test_isa_2_06.exp  | 123 +++++
 .../gdb.reverse/ppc_record_test_isa_3_1.c     | 102 ++++
 .../gdb.reverse/ppc_record_test_isa_3_1.exp   | 494 ++++++++++++++++++
 4 files changed, 767 insertions(+)
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp

diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
new file mode 100644
index 00000000000..03ba90e2bff
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
@@ -0,0 +1,48 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <ctype.h>     // isspace
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>    // getopt
+#include <altivec.h>   // vector
+
+/* globals used for vector tests */
+static vector unsigned long vec_xa, vec_xb, vec_xt;
+static unsigned long ra, rb, rs;
+
+int main ()
+{
+  ra = 0xABCDEF012;
+  rb = 0;
+  rs = 0x012345678;
+
+  /* 9.0, 16.0, 25.0, 36.0 */
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+
+  vec_xt = (vector unsigned long){0xFF00FF00FF00FF00, 0xAA00AA00AA00AA00};
+
+  /* Test 1 ISA 2.06 instructions.  Load source into vs1, result of sqrt
+     put into vs0.  */
+  ra = (unsigned long) & vec_xb;        /* stop 1 */
+  __asm__ __volatile__ ("lxvd2x 1, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("xvsqrtsp 0, 1");
+  ra = 0;                               /* stop 2 */
+}
+
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
new file mode 100644
index 00000000000..b6522606262
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
@@ -0,0 +1,123 @@
+# Copyright 2008-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# This file is part of the GDB testsuite.  It tests reverse stepping.
+# Lots of code borrowed from "step-reverse.exp".
+#
+# Test instruction record for Powerpc, ISA 2.06.
+#
+
+# The basic flow of the record tests are:
+#    1) Stop before executing the instructions of interest. Record
+#       the initial value of the registers that the instruction will
+#       change, i.e. the destination register.
+#    2) Execute the instructions.  Record the new value of the
+#       registers that changed.
+#    3) Reverse the direction of the execution and execute back to
+#       just before the instructions of interest.  Record the final
+#       value of the registers of interest.
+#    4) Check that the initial and new values of the registers are
+#       different, i.e. the instruction changed the registers as expected.
+#    5) Check that the initial and final values of the registers are
+#       the same, i.e. gdb record restored the registers to their
+#       original values.
+
+standard_testfile
+
+set gen_src record_test_isa_2_06.c
+set executable record_test_isa_2_06
+set options [list debug]
+
+if {![istarget "powerpc*"]} then  {
+    verbose "Skipping Powerpc ISA 2.06 instruction record_test_2_06."
+    return
+}
+
+if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
+    return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] then {
+    untested "could not run to main"
+    continue
+}
+
+gdb_test_no_output "record"
+
+###### Test 1:  Test an ISA 2.06 load (lxvd2x) and square root instruction
+###### (xvsqrtsp).  The load instruction will load vs1.  The sqrt instruction
+###### will put its result into vs0.
+
+set stop1  [gdb_get_line_number "stop 1"]
+set stop2  [gdb_get_line_number "stop 2"]
+
+gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test 1"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 1"
+
+# Record the initial values in vs0, vs1.
+# Load the argument into vs1, result of sqrt is put into vs0.
+set vs0_initial [capture_command_output "info register vs0" ""]
+set vs1_initial [capture_command_output "info register vs1" ""]
+
+gdb_test "break $stop2" ".*Breakpoint .*" "executed lxvd2x, xvsqrtsp"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 2"
+
+# The lxvd2x, xvsqrtsp and has been executed loading the argument into vs1
+# Record the new values of vs0 and vs1.
+set vs0_new [capture_command_output "info register vs0" ""]
+set vs1_new [capture_command_output "info register vs1" ""]
+
+# Execute in reverse to before the lxvd2x instruction.
+gdb_test_no_output "set exec-direction reverse"
+
+gdb_test "break $stop1" ".*Breakpoint .*" "un executed lxvd2x, xvsqrtsp"
+gdb_test "continue"  ".*Breakpoint.*" "At stop 1 in reverse"
+
+# Record the final values of vs0, vs1.
+set vs0_final [capture_command_output "info register vs0" ""]
+set vs1_final [capture_command_output "info register vs1" ""]
+
+# Check initial and new of vs0 are different.
+set test_vs0_init_new "check vs0 initial versus vs0 new"
+if {[string compare $vs0_initial  $vs0_new ] == 0} {
+    fail $test_vs0_init_new
+} else {
+    pass $test_vs0_init_new
+}
+
+# Check initial and new of vs1 are different.
+set test_vs1_init_new "check vs0 initial versus vs1 new"
+if {[string compare $vs1_initial  $vs1_new ] == 0} {
+    fail $test_vs1_init_new
+} else {
+    pass $test_vs1_init_new
+}
+
+# Check initial and final are the same.
+set test_vs0_init_final "check vs0 initial versus vs0 final"
+if {[string compare $vs0_initial  $vs0_final ] == 0} {
+    pass $test_vs0_init_final
+} else {
+    fail $test_vs0_init_final
+}
+
+# Check initial and final are the same.
+set test_vs1_init_final "check vs1 initial versus vs1 final"
+if {[string compare $vs1_initial  $vs1_final ] == 0} {
+    pass $test_vs1_init_final
+} else {
+    fail $test_vs1_init_final
+}
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
new file mode 100644
index 00000000000..e02c3daaed3
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
@@ -0,0 +1,102 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <ctype.h>     // isspace
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>    // getopt
+#include <altivec.h>   // vector
+
+/* globals used for vector tests */
+static vector unsigned long vec_xa, vec_xb, vec_xt;
+static unsigned long ra, rb, rs;
+
+int main ()
+{
+  ra = 0xABCDEF012;
+  rb = 0;
+  rs = 0x012345678;
+
+  /* 9.0, 16.0, 25.0, 36.0 */
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+
+  vec_xt = (vector unsigned long){0xFF00FF00FF00FF00, 0xAA00AA00AA00AA00};
+
+  /* Test 1, ISA 3.1 word instructions. Load source into r1, result of brh
+     put in r0.  */
+  ra = 0xABCDEF012;                     /* stop 1 */
+  __asm__ __volatile__ ("pld 1, %0" :: "r" (ra ));
+  __asm__ __volatile__ ("brh 0, 1" );
+  ra = 0;                               /* stop 2 */
+
+  /* Test 2, ISA 3.1 MMA instructions with results in various ACC entries
+     xxsetaccz    - ACC[3]
+     xvi4ger8     - ACC[4]
+     xvf16ger2pn  - ACC[5]
+     pmxvi8ger4   - ACC[6]
+     pmxvf32gerpp - ACC[7] and fpscr */
+  /* Need to initialize the vs registers to a non zero value.  */
+  ra = (unsigned long) & vec_xb;
+  __asm__ __volatile__ ("lxvd2x 12, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 13, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 14, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 15, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xa = (vector unsigned long){0x333134343987601, 0x9994bbbc9983307};
+  vec_xb = (vector unsigned long){0x411234041898760, 0x41c833042103400};
+  __asm__ __volatile__ ("lxvd2x 16, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x123456789987650, 0x235676546989807};
+  __asm__ __volatile__ ("lxvd2x 17, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x878363439823470, 0x413434c99839870};
+  __asm__ __volatile__ ("lxvd2x 18, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x043765434398760, 0x419876555558850};
+  __asm__ __volatile__ ("lxvd2x 19, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x33313434398760, 0x9994bbbc99899330};
+  __asm__ __volatile__ ("lxvd2x 20, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 21, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 22, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 23, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 24, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 25, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 26, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 27, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xa = (vector unsigned long){0x33313434398760, 0x9994bbbc998330};
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+  __asm__ __volatile__ ("lxvd2x 28, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x4567000046800000, 0x4458000048700000};
+  __asm__ __volatile__ ("lxvd2x 29, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x41dd000041e00000, 0x41c8000046544400};
+  __asm__ __volatile__ ("lxvd2x 30, %0, %1" :: "r" (ra ), "r" (rb));
+
+  /* SNAN */
+  vec_xb = (vector unsigned long){0x7F8F00007F8F0000, 0x7F8F00007F8F0000};
+
+  __asm__ __volatile__ ("lxvd2x 31, %0, %1" :: "r" (ra ), "r" (rb));
+
+  ra = 0xAB;                            /* stop 3 */
+  __asm__ __volatile__ ("xxsetaccz 3");
+  __asm__ __volatile__ ("xvi4ger8 4, %x0, %x1" :: "wa" (vec_xa), \
+			"wa" (vec_xb) );
+  __asm__ __volatile__ ("xvf16ger2pn 5, %x0, %x1" :: "wa" (vec_xa),\
+			"wa" (vec_xb) );
+  __asm__ __volatile__ ("pmxvi8ger4spp  6, %x0, %x1, 11, 13, 5"
+                                :: "wa" (vec_xa), "wa" (vec_xb) );
+  __asm__ __volatile__ ("pmxvf32gerpp  7, %x0, %x1, 11, 13"
+                                :: "wa" (vec_xa), "wa" (vec_xb) );
+  ra = 0;                               /* stop 4 */
+}
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
new file mode 100644
index 00000000000..f0340db92f0
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
@@ -0,0 +1,494 @@
+# Copyright 2008-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# This file is part of the GDB testsuite.  It tests reverse stepping.
+# Lots of code borrowed from "step-reverse.exp".
+#
+# Test instruction record for Powerpc, ISA 3.1.
+#
+
+# The basic flow of the record tests are:
+#    1) Stop before executing the instructions of interest.  Record
+#       the initial value of the registers that the instruction will
+#       change, i.e. the destination register.
+#    2) Execute the instructions.  Record the new value of the
+#       registers that changed.
+#    3) Reverse the direction of the execution and execute back to
+#       just before the instructions of interest.  Record the final
+#       value of the registers of interest.
+#    4) Check that the initial and new values of the registers are
+#       different, i.e. the instruction changed the registers as expected.
+#    5) Check that the initial and final values of the registers are
+#       the same, i.e. gdb record restored the registers to their
+#       original values.
+
+
+standard_testfile
+
+set gen_src record_test_isa_3_1.c
+set executable record_test_isa_3_1
+
+if {![istarget "powerpc*"] || [skip_power_isa_3_1_tests] } then  {
+    verbose "Skipping Powerpc ISA 3.1 instruction record_test."
+    return
+}
+
+set options [list additional_flags=-mcpu=power10  debug]
+if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
+    return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] then {
+    untested "could not run to main"
+    continue
+}
+
+gdb_test_no_output "record"
+
+######  Test 1:  Test an ISA 3.1 byte reverse word instruction (brd) and a
+######   prefixed load double (pld) instruction.
+set stop1  [gdb_get_line_number "stop 1"]
+set stop2  [gdb_get_line_number "stop 2"]
+
+gdb_test "break $stop1" ".*Breakpoint .*" "about to execute Test 1"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 1"
+
+# Record the initial values in r0, r1
+# Load the argument into r1, result of byte reverse is put into r0.
+set r0_initial [capture_command_output "info register r0" ""]
+set r1_initial [capture_command_output "info register r1" ""]
+
+gdb_test "break $stop2" ".*Breakpoint .*" "executed test 1"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 2"
+
+# Record the new values of r0 and r1
+set r0_new [capture_command_output "info register r0" ""]
+set r1_new [capture_command_output "info register r1" ""]
+
+# Execute in reverse to before test 1
+gdb_test "set exec-direction reverse" "" "Reverse to start of Test 1"
+#gdb_test_no_output "set exec-direction reverse"
+
+gdb_test "break $stop1" ".*Breakpoint .*" "reverse stop at test 1 start"
+gdb_test "continue"  ".*Breakpoint.*" "At stop 1 in reverse"
+
+# Record the final values of r0, r1
+set r0_final [capture_command_output "info register r0" ""]
+set r1_final [capture_command_output "info register r1" ""]
+
+# Check initial and new of r0 are different.
+set test_r0_init_new "check r0 initial versus r0 new"
+if {[string compare $r0_initial  $r0_new ] == 0} {
+    fail $test_r0_init_new
+} else {
+    pass $test_r0_init_new
+}
+
+# Check initial and new of r1 are different.
+set test_r1_init_new "check r0 initial versus r1 new"
+if {[string compare $r1_initial  $r1_new ] == 0} {
+    fail $test_r1_init_new
+} else {
+    pass $test_r1_init_new
+}
+
+# Check initial and final are the same.
+set test_r0_init_final "check r0 initial versus r0 final"
+if {[string compare $r0_initial  $r0_final ] == 0} {
+    pass $test_r0_init_final
+} else {
+    fail $test_r0_init_final
+}
+
+# Check initial and final are the same.
+set test_r1_init_final "check r1 initial versus r1 final"
+if {[string compare $r1_initial  $r1_final ] == 0} {
+    pass $test_r1_init_final
+} else {
+    fail $test_r1_init_final
+}
+
+
+# Change execution direction to forward for next test.
+gdb_test "set exec-direction forward" "" "Start forward test3"
+gdb_test "record stop" ".*Process record is stopped.*" "Stopped recording 2"
+set test_del_bkpts "delete breakpoints, answer prompt 2"
+
+# Delete all breakpoints and catchpoints.
+delete_breakpoints
+
+gdb_test "record" "" "Start recording test2"
+
+
+######  Test 2:  Test the ISA 3.1 MMA instructions xxsetaccz, xvi4ger8,
+######  xvf16ger2pn, pmxvi8ger4, and pmxvf32gerpp.  Goal here is to hit all
+######  the places where ppc_record_ACC_fpscr() gets called.
+##
+##       xxsetaccz    - ACC[3], vs[12] to vs[15]
+##       xvi4ger8     - ACC[4], vs[16] to vs[19]
+##       xvf16ger2pn  - ACC[5], vs[20] to vs[23]
+##       pmxvi8ger4   - ACC[6], vs[21] to vs[27]
+##       pmxvf32gerpp - ACC[7], vs[28] to vs[31] and fpscr
+
+set stop3  [gdb_get_line_number "stop 3"]
+set stop4  [gdb_get_line_number "stop 4"]
+
+gdb_test "break $stop3" ".*Breakpoint .*" "about to execute Test 2"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 3"
+
+# Record the initial values of vs's that correspond to the ACC entries,
+# and fpscr.
+set acc_3_0_initial [capture_command_output "info register vs12" ""]
+set acc_3_1_initial [capture_command_output "info register vs13" ""]
+set acc_3_2_initial [capture_command_output "info register vs14" ""]
+set acc_3_3_initial [capture_command_output "info register vs15" ""]
+set acc_4_0_initial [capture_command_output "info register vs16" ""]
+set acc_4_1_initial [capture_command_output "info register vs17" ""]
+set acc_4_2_initial [capture_command_output "info register vs18" ""]
+set acc_4_3_initial [capture_command_output "info register vs19" ""]
+set acc_5_0_initial [capture_command_output "info register vs20" ""]
+set acc_5_1_initial [capture_command_output "info register vs21" ""]
+set acc_5_2_initial [capture_command_output "info register vs22" ""]
+set acc_5_3_initial [capture_command_output "info register vs23" ""]
+set acc_6_0_initial [capture_command_output "info register vs24" ""]
+set acc_6_1_initial [capture_command_output "info register vs25" ""]
+set acc_6_2_initial [capture_command_output "info register vs26" ""]
+set acc_6_3_initial [capture_command_output "info register vs27" ""]
+set acc_7_0_initial [capture_command_output "info register vs28" ""]
+set acc_7_1_initial [capture_command_output "info register vs29" ""]
+set acc_7_2_initial [capture_command_output "info register vs30" ""]
+set acc_7_3_initial [capture_command_output "info register vs31" ""]
+set fpscr_initial [capture_command_output "info register fpscr" ""]
+
+gdb_test "break $stop4" ".*Breakpoint .*" "executed test 2"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 4"
+
+# Record the new values of the ACC entries and fpscr.
+set acc_3_0_new [capture_command_output "info register vs12" ""]
+set acc_3_1_new [capture_command_output "info register vs13" ""]
+set acc_3_2_new [capture_command_output "info register vs14" ""]
+set acc_3_3_new [capture_command_output "info register vs15" ""]
+set acc_4_0_new [capture_command_output "info register vs16" ""]
+set acc_4_1_new [capture_command_output "info register vs17" ""]
+set acc_4_2_new [capture_command_output "info register vs18" ""]
+set acc_4_3_new [capture_command_output "info register vs19" ""]
+set acc_5_0_new [capture_command_output "info register vs20" ""]
+set acc_5_1_new [capture_command_output "info register vs21" ""]
+set acc_5_2_new [capture_command_output "info register vs22" ""]
+set acc_5_3_new [capture_command_output "info register vs23" ""]
+set acc_6_0_new [capture_command_output "info register vs24" ""]
+set acc_6_1_new [capture_command_output "info register vs25" ""]
+set acc_6_2_new [capture_command_output "info register vs26" ""]
+set acc_6_3_new [capture_command_output "info register vs27" ""]
+set acc_7_0_new [capture_command_output "info register vs28" ""]
+set acc_7_1_new [capture_command_output "info register vs29" ""]
+set acc_7_2_new [capture_command_output "info register vs30" ""]
+set acc_7_3_new [capture_command_output "info register vs31" ""]
+set fpscr_new [capture_command_output "info register fpscr" ""]
+
+# Execute in reverse to before test 2.
+gdb_test "set exec-direction reverse" "" "Reverse to start of Test 2"
+
+gdb_test "break $stop3" ".*Breakpoint .*" "reverse stop at test 2 start"
+gdb_test "continue"  ".*Breakpoint.*" "At stop 3 in reverse"
+
+# Record the final values of the ACC entries and fpscr.
+set acc_3_0_final [capture_command_output "info register vs12" ""]
+set acc_3_1_final [capture_command_output "info register vs13" ""]
+set acc_3_2_final [capture_command_output "info register vs14" ""]
+set acc_3_3_final [capture_command_output "info register vs15" ""]
+set acc_4_0_final [capture_command_output "info register vs16" ""]
+set acc_4_1_final [capture_command_output "info register vs17" ""]
+set acc_4_2_final [capture_command_output "info register vs18" ""]
+set acc_4_3_final [capture_command_output "info register vs19" ""]
+set acc_5_0_final [capture_command_output "info register vs20" ""]
+set acc_5_1_final [capture_command_output "info register vs21" ""]
+set acc_5_2_final [capture_command_output "info register vs22" ""]
+set acc_5_3_final [capture_command_output "info register vs23" ""]
+set acc_6_0_final [capture_command_output "info register vs24" ""]
+set acc_6_1_final [capture_command_output "info register vs25" ""]
+set acc_6_2_final [capture_command_output "info register vs26" ""]
+set acc_6_3_final [capture_command_output "info register vs27" ""]
+set acc_7_0_final [capture_command_output "info register vs28" ""]
+set acc_7_1_final [capture_command_output "info register vs29" ""]
+set acc_7_2_final [capture_command_output "info register vs30" ""]
+set acc_7_3_final [capture_command_output "info register vs31" ""]
+set fpscr_final [capture_command_output "info register fpscr" ""]
+
+# check initial and new ACC entries.
+set test_acc_3_0_init_new "check vs12 initial versus new"
+if {[string compare $acc_3_0_initial  $acc_3_0_new ] == 0} {
+    fail $test_acc_3_0_init_new
+} else {
+    pass $test_acc_3_0_init_new
+}
+set test_acc_3_1_init_new "check vs13 initial versus new"
+if {[string compare $acc_3_1_initial  $acc_3_1_new ] == 0} {
+    fail $test_acc_3_1_init_new
+} else {
+    pass $test_acc_3_1_init_new
+}
+set test_acc_3_2_init_new "check vs14 initial versus new"
+if {[string compare $acc_3_2_initial  $acc_3_2_new ] == 0} {
+    fail $test_acc_3_2_init_new
+} else {
+    pass $test_acc_3_2_init_new
+}
+set test_acc_3_3_init_new "check vs15 initial versus new"
+if {[string compare $acc_3_3_initial  $acc_3_3_new ] == 0} {
+    fail $test_acc_3_3_init_new
+} else {
+    pass $test_acc_3_3_init_new
+}
+
+set test_acc_4_0_init_new "check vs16 initial versus new"
+if {[string compare $acc_4_0_initial  $acc_4_0_new ] == 0} {
+    fail $test_acc_4_0_init_new
+} else {
+    pass $test_acc_4_0_init_new
+}
+set test_acc_4_1_init_new "check vs17 initial versus new"
+if {[string compare $acc_4_1_initial  $acc_4_1_new ] == 0} {
+    fail $test_acc_4_1_init_new
+} else {
+    pass $test_acc_4_1_init_new
+}
+set test_acc_4_2_init_new "check vs18 initial versus new"
+if {[string compare $acc_4_2_initial  $acc_4_2_new ] == 0} {
+    fail $test_acc_4_2_init_new
+} else {
+    pass $test_acc_4_2_init_new
+}
+set test_acc_4_3_init_new "check vs19 initial versus new"
+if {[string compare $acc_4_3_initial  $acc_4_3_new ] == 0} {
+    fail $test_acc_4_3_init_new
+} else {
+    pass $test_acc_4_3_init_new
+}
+
+set test_acc_5_0_init_new "check vs20 initial versus new"
+if {[string compare $acc_5_0_initial  $acc_5_0_new ] == 0} {
+    fail $test_acc_5_0_init_new
+} else {
+    pass $test_acc_5_0_init_new
+}
+set test_acc_5_1_init_new "check vs21 initial versus new"
+if {[string compare $acc_5_1_initial  $acc_5_1_new ] == 0} {
+    fail $test_acc_5_1_init_new
+} else {
+    pass $test_acc_5_1_init_new
+}
+set test_acc_5_2_init_new "check vs22 initial versus new"
+if {[string compare $acc_5_2_initial  $acc_5_2_new ] == 0} {
+    fail $test_acc_5_2_init_new
+} else {
+    pass $test_acc_5_2_init_new
+}
+set test_acc_5_3_init_new "check vs23 initial versus new"
+if {[string compare $acc_5_3_initial  $acc_5_3_new ] == 0} {
+    fail $test_acc_5_3_init_new
+} else {
+    pass $test_acc_5_3_init_new
+}
+
+set test_acc_6_0_init_new "check vs24 initial versus new"
+if {[string compare $acc_6_0_initial  $acc_6_0_new ] == 0} {
+    fail $test_acc_6_0_init_new
+} else {
+    pass $test_acc_6_0_init_new
+}
+set test_acc_6_1_init_new "check vs25 initial versus new"
+if {[string compare $acc_6_1_initial  $acc_6_1_new ] == 0} {
+    fail $test_acc_6_1_init_new
+} else {
+    pass $test_acc_6_1_init_new
+}
+set test_acc_6_2_init_new "check vs26 initial versus new"
+if {[string compare $acc_6_2_initial  $acc_6_2_new ] == 0} {
+    fail $test_acc_6_2_init_new
+} else {
+    pass $test_acc_6_2_init_new
+}
+set test_acc_6_3_init_new "check vs27 initial versus new"
+if {[string compare $acc_6_3_initial  $acc_6_3_new ] == 0} {
+    fail $test_acc_6_3_init_new
+} else {
+    pass $test_acc_6_3_init_new
+}
+
+set test_acc_7_0_init_new "check vs28 initial versus new"
+if {[string compare $acc_7_0_initial  $acc_7_0_new ] == 0} {
+    fail $test_acc_7_0_init_new
+} else {
+    pass $test_acc_7_0_init_new
+}
+set test_acc_7_1_init_new "check vs29 initial versus new"
+if {[string compare $acc_7_1_initial  $acc_7_1_new ] == 0} {
+    fail $test_acc_7_1_init_new
+} else {
+    pass $test_acc_7_1_init_new
+}
+set test_acc_7_2_init_new "check vs30 initial versus new"
+if {[string compare $acc_7_2_initial  $acc_7_2_new ] == 0} {
+    fail $test_acc_7_2_init_new
+} else {
+    pass $test_acc_7_2_init_new
+}
+set test_acc_7_3_init_new "check vs31 initial versus new"
+if {[string compare $acc_7_3_initial  $acc_7_3_new ] == 0} {
+    fail $test_acc_7_3_init_new
+} else {
+    pass $test_acc_7_3_init_new
+}
+set test_fpscr_init_new "check fpscr initial versus new"
+if {[string compare $fpscr_initial  $fpscr_new ] == 0} {
+    fail $test_fpscr_init_new
+} else {
+    pass $test_fpscr_init_new
+}
+
+# Check initial and new ACC entries are different.
+set test_acc_3_0_init_final "check vs12 initial versus final"
+if {[string compare $acc_3_0_initial  $acc_3_0_final ] == 0} {
+    pass $test_acc_3_0_init_final
+} else {
+    fail $test_acc_3_0_init_final
+}
+set test_acc_3_1_init_final "check vs13 initial versus final"
+if {[string compare $acc_3_1_initial  $acc_3_1_final ] == 0} {
+    pass $test_acc_3_1_init_final
+} else {
+    fail $test_acc_3_0_init_final
+}
+set test_acc_3_2_init_final "check vs14 initial versus final"
+if {[string compare $acc_3_2_initial  $acc_3_2_final ] == 0} {
+    pass $test_acc_3_2_init_final
+} else {
+    fail $test_acc_3_2_init_final
+}
+set test_acc_3_3_init_final "check vs15 initial versus final"
+if {[string compare $acc_3_3_initial  $acc_3_3_final ] == 0} {
+    pass $test_acc_3_3_init_final
+} else {
+    new $test_acc_3_3_init_final
+}
+
+set test_acc_4_0_init_final "check vs16 initial versus final"
+if {[string compare $acc_4_0_initial  $acc_4_0_final ] == 0} {
+    pass $test_acc_4_0_init_final
+} else {
+    new $test_acc_4_0_init_final
+}
+set test_acc_4_1_init_final "check vs17 initial versus final"
+if {[string compare $acc_4_1_initial  $acc_4_1_final ] == 0} {
+    pass $test_acc_4_1_init_final
+} else {
+    new $test_acc_4_0_init_final
+}
+set test_acc_4_2_init_final "check vs18 initial versus final"
+if {[string compare $acc_4_2_initial  $acc_4_2_final ] == 0} {
+    pass $test_acc_4_2_init_final
+} else {
+    new $test_acc_4_2_init_final
+}
+set test_acc_4_3_init_final "check vs19 initial versus final"
+if {[string compare $acc_4_3_initial  $acc_4_3_final ] == 0} {
+    pass $test_acc_4_3_init_final
+} else {
+    fail $test_acc_4_3_init_final
+}
+
+set test_acc_5_0_init_final "check vs20 initial versus final"
+if {[string compare $acc_5_0_initial  $acc_5_0_final ] == 0} {
+    pass $test_acc_5_0_init_final
+} else {
+    fail $test_acc_5_0_init_final
+}
+set test_acc_5_1_init_final "check vs21 initial versus final"
+if {[string compare $acc_5_1_initial  $acc_5_1_final ] == 0} {
+    pass $test_acc_5_1_init_final
+} else {
+    fail $test_acc_5_0_init_final
+}
+set test_acc_5_2_init_final "check vs22 initial versus final"
+if {[string compare $acc_5_2_initial  $acc_5_2_final ] == 0} {
+    pass $test_acc_5_2_init_final
+} else {
+    fail $test_acc_5_2_init_final
+}
+set test_acc_5_3_init_final "check vs23 initial versus final"
+if {[string compare $acc_5_3_initial  $acc_5_3_final ] == 0} {
+    pass $test_acc_5_3_init_final
+} else {
+    fail $test_acc_5_3_init_final
+}
+
+set test_acc_6_0_init_final "check vs24 initial versus final"
+if {[string compare $acc_6_0_initial  $acc_6_0_final ] == 0} {
+    pass $test_acc_6_0_init_final
+} else {
+    fail $test_acc_6_0_init_final
+}
+set test_acc_6_1_init_final "check vs25 initial versus final"
+if {[string compare $acc_6_1_initial  $acc_6_1_final ] == 0} {
+    pass $test_acc_6_1_init_final
+} else {
+    fail $test_acc_6_0_init_final
+}
+set test_acc_6_2_init_final "check vs26 initial versus final"
+if {[string compare $acc_6_2_initial  $acc_6_2_final ] == 0} {
+    pass $test_acc_6_2_init_final
+} else {
+    fail $test_acc_6_2_init_final
+}
+set test_acc_6_3_init_final "check vs27 initial versus final"
+if {[string compare $acc_6_3_initial  $acc_6_3_final ] == 0} {
+    pass $test_acc_6_3_init_final
+} else {
+    fail $test_acc_6_3_init_final
+}
+
+set test_acc_7_0_init_final "check vs28 initial versus final"
+if {[string compare $acc_7_0_initial  $acc_7_0_final ] == 0} {
+    pass $test_acc_7_0_init_final
+} else {
+    fail $test_acc_7_0_init_final
+}
+set test_acc_7_1_init_final "check vs29 initial versus final"
+if {[string compare $acc_7_1_initial  $acc_7_1_final ] == 0} {
+    pass $test_acc_7_1_init_final
+} else {
+    fail $test_acc_7_0_init_final
+}
+set test_acc_7_2_init_final "check vs30 initial versus final"
+if {[string compare $acc_7_2_initial  $acc_7_2_final ] == 0} {
+    pass $test_acc_7_2_init_final
+} else {
+    fail $test_acc_7_2_init_final
+}
+set test_acc_7_3_init_final "check vs31 initial versus final"
+if {[string compare $acc_7_3_initial  $acc_7_3_final ] == 0} {
+    pass $test_acc_7_3_init_final
+} else {
+    fail $test_acc_7_3_init_final
+}
+set test_fpscr_init_final "check fpscr initial versus final"
+if {[string compare $fpscr_initial  $fpscr_final ] == 0} {
+    pass $test_fpscr_init_final
+} else {
+    fail $test_fpscr_init_final
+}
+
-- 
2.31.1




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/2  Version 2] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-12 17:09     ` [PATCH 1/2 Version 2] " Carl Love
@ 2022-04-12 21:50       ` will schmidt
  2022-04-13 17:26         ` [PATCH 1/2 Version 3] " Carl Love
  0 siblings, 1 reply; 25+ messages in thread
From: will schmidt @ 2022-04-12 21:50 UTC (permalink / raw)
  To: Carl Love, Joel Brobecker, gdb-patches
  Cc: Ulrich Weigand, Tulio Magno, Rogerio Alves

On Tue, 2022-04-12 at 10:09 -0700, Carl Love via Gdb-patches wrote:
> Joel, GDB maintainers:
> 
> I have addressed the following comments:
> 
> On Sun, 2022-03-06 at 15:53 +0400, Joel Brobecker via Gdb-patches
> wrote:
> > <snip>
> > >  
> > > +#define RECORD_FPSCR 1
> > > +#define DO_NOT_RECORD_FPSCR 0
> > 
> > I think these macros deserves documentation as well.
> 
> Added a header comment for the function and defines.
> > > +     NOTE:
> > > +     In ISA 3.1 the ACC is mapped on top of VSR[0] thru VSR[31].
> > > +
> > > +     In the future, the ACC may be implemented as an independent
> > > register file
> > > +     rather then mapping on top of the VSRs. This will then
> > > require the ACC to
> > 
> > Small typo: "then" -> "than".
> 
> Fixed.
> 
> > Also, can you add an extra space after the period (just before
> > "This will [...]" above)?
> Fixed.
> 
> > > +     be assigned its on register number and the ptrace interface
> > > to be able
> > > +     access the ACC.
> > > +  */
> > > +
> > > +  /* ACC maps over the same VSR space as the fp registers.  */
> > > +  for (i = 0; i<4; i++) {
> > 
> > GNU Coding style: Can you place the opening curly brace on the next
> > line, please, indented 2 characters relative to the "for". You'll
> > probably want to adjust the indentation of the block accordingly,
> > including the closing curly brace.
> 
> Fixed this coding style throughout the patch.
> 
> > > @@ -5174,15 +5517,13 @@ ppc_process_record_op31 (struct gdbarch
> > > *gdbarch, struct regcache *regcache,
> > >    return -1;
> > >  }
> > >  
> > > -/* Parse and record instructions of primary opcode-59 at ADDR.
> > > -   Return 0 if successful.  */
> > > -
> > >  static int
> > >  ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache
> > > *regcache,
> > 
> > Can you explain why you are removing this function documentation?
> > Is it now OBE? Either way, can you make sure we either keep the doc,
> > or replace it with an updated version?
> 
> Should not have been removed, put the comment back in.
> 
> > > +
> > > +  if (type == 1) {
> > > +    if (ST4 == 0) {
> Fixed.
> <snip>
> > > +    } else
> > 
> > Coding standard: The "else" should be on the next line.
> fixed
> > 
> > > +      return -1;
> > > +
> > > +  } else if (type == 2) {
> > 
> > Same here, please, and also watch out for the training "{" which
> > should also be moved to the next line.
> > 
> > The following are also other coding style violations I noticed
> > through skimming your patch:
> > 
> > > +  if (type == 1) {
> > > +  } else
> > > +  if (type == 1) {
> > > +  } else if (type == 2) {
> > > +  } else
> > > +  if ((type == 0) && (ST1 == 0)) {
> > > +    if (R == 0) {
> > > +    } else {
> > > +  if ((type == 0) && (ST1 == 0)) {
> > > +	  if (R == 0) {
> > > +	  } else {
> > > +  } else
> fixed
> 
> I do believe I have all of the coding style issues.
> 
> Patch has been retested on Power 10 with no regressions.
> 
>                              Carl Love
Consider consolidating all of the above
into "V2: Updated per feedback".  It otherwise takes a lot of
scrolling to get to the patch here.


No issues on the code below, but assorted commentary on the comments, as follows.

> 
> ---------------------------------------------------------------------
> Add recording support for the ISA 3.1 Powerpc instructions.
> 
> This patch adds support for the Powerpc ISA 3.1 instructions to the Powerpc
> gdb instruction recording routines.  Case statement entries are added to a
> number of the existing routines for recording the 32-bit word instructions.
> A few new functions were added to handle the new word instructions.  The 64-bit
> prefix instructions are all handled by a set of new routines.  The function
> ppc_process_prefix_instruction() is the primary function to handle the
> prefixed instructions. It calls additional functions to handle specific
> sets of prefixed instructions.  These new functions are:

Does this fit in 80 chars?


>   ppc_process_record_prefix_vsx_d_form(),
>   ppc_process_record_prefix_store_vsx_ds_form(),
>   ppc_process_record_prefix_op34(),
>   ppc_process_record_prefix_op33(),
>   ppc_process_record_prefix_op32(),
>   ppc_process_record_prefix_store(),
>   ppc_process_record_prefix_op59_XX3(),
>   ppc_process_record_prefix_op42().
> ---
>  gdb/rs6000-tdep.c | 1196 ++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 1171 insertions(+), 25 deletions(-)
> 
> diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
> index 44828bcff6d..7b4b4a71746 100644
> --- a/gdb/rs6000-tdep.c
> +++ b/gdb/rs6000-tdep.c
> @@ -4123,8 +4123,26 @@ bfd_uses_spe_extensions (bfd *abfd)
>  #define PPC_LEV(insn)	PPC_FIELD (insn, 20, 7)
> 
>  #define PPC_XT(insn)	((PPC_TX (insn) << 5) | PPC_T (insn))
> +#define PPC_XTp(insn)	((PPC_BIT (insn, 10) << 5)	\
> +			 | PPC_FIELD (insn, 6, 4) << 1)
> +#define PPC_XSp(insn)	((PPC_BIT (insn, 10) << 5)	\
> +			 | PPC_FIELD (insn, 6, 4) << 1)
>  #define PPC_XER_NB(xer)	(xer & 0x7f)
> 
> +/* The following macros are for the prefixed instructions.  */
> +#define P_PPC_D(insn_prefix, insn_suffix) \
> +  PPC_SEXT (PPC_FIELD (insn_prefix, 14, 18) << 16 \
> +	    | PPC_FIELD (insn_suffix, 16, 16), 34)
> +#define P_PPC_TX5(insn_sufix)	PPC_BIT (insn_suffix, 5)
> +#define P_PPC_TX15(insn_suffix) PPC_BIT (insn_suffix, 15)
> +#define P_PPC_XT(insn_suffix)	((PPC_TX (insn_suffix) << 5) \
> +				 | PPC_T (insn_suffix))
> +#define P_PPC_XT5(insn_suffix) ((P_PPC_TX5 (insn_suffix) << 5) \
> +				| PPC_T (insn_suffix))
> +#define P_PPC_XT15(insn_suffix) \
> +  ((P_PPC_TX15 (insn_suffix) << 5) | PPC_T (insn_suffix))
> +
> +

Remove the extra blank new line. 

>  /* Record Vector-Scalar Registers.
>     For VSR less than 32, it's represented by an FPR and an VSR-upper register.
>     Otherwise, it's just a VR register.  Record them accordingly.  */
> @@ -4152,6 +4170,60 @@ ppc_record_vsr (struct regcache *regcache, ppc_gdbarch_tdep *tdep, int vsr)
>    return 0;
>  }
> 
> +/* The ppc_record_ACC_fpscr() records te changes to the floating point
> +   registers modified by a floating point instruction.  The RECORD_FPSCR
> +   or DO_NOT_RECORD_FPSCR argument to the function specifies if the instruction
> +   modifies the floating point condition code register which also needs to be
> +   recorded.  Return 0 on success.  */

FPSCR is "Floating-Point Status and Control Register".   The Condition
Code is one of the fields defined within that register.  The comment
should be updated to clarify which is being referred to. 

> +
> +#define RECORD_FPSCR 1
> +#define DO_NOT_RECORD_FPSCR 0
> +
> +static int
> +ppc_record_ACC_fpscr (struct regcache *regcache, ppc_gdbarch_tdep *tdep,
> +		      int at, int save_fpscr)
> +{
> +  int i;
> +  if (at < 0 || at >= 8)
> +    return -1;
> +
> +  /* The ACC consists of 8 entries, each entries consist of four 128-bit
> +     rows.

Is this "consists of 8 entries", or "There are 8 Accumulators"?


> +
> +     The ACC rows map to specific VSR registers.
> +         ACC[0][0] -> VSR[0]
> +         ACC[0][1] -> VSR[1]
> +         ACC[0][2] -> VSR[2]
> +         ACC[0][3] -> VSR[3]
> +              ...
> +         ACC[7][0] -> VSR[28]
> +         ACC[7][1] -> VSR[29]
> +         ACC[7][2] -> VSR[30]
> +         ACC[7][3] -> VSR[31]
> +
> +     NOTE:
> +     In ISA 3.1 the ACC is mapped on top of VSR[0] thru VSR[31].
> +
> +     In the future, the ACC may be implemented as an independent register file
> +     rather than mapping on top of the VSRs.  This will then require the ACC to
> +     be assigned its on register number and the ptrace interface to be able
> +     access the ACC.  */

s/on/own/
Perhaps need to add " ptrace interfaces ... will need to be
implemented ... to be able to access.. "

> +
> +  /* ACC maps over the same VSR space as the fp registers.  */
> +  for (i = 0; i<4; i++)
> +    {
> +      record_full_arch_list_add_reg (regcache, tdep->ppc_fp0_regnum
> +				     + at*4 + i);
> +      record_full_arch_list_add_reg (regcache,
> +				     tdep->ppc_vsr0_upper_regnum + at*4 + i);
> +    }
> +
> +  if (save_fpscr)
> +    record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
> +
> +  return 0;
> +}
> +
>  /* Parse and record instructions primary opcode-4 at ADDR.
>     Return 0 if successful.  */
> 
> @@ -4171,9 +4243,34 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 41:		/* Vector Multiply-Sum Signed Halfword Saturate */
>        record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
>        /* FALL-THROUGH */
> +    case 20:		/* Move To VSR Byte Mask Immediate opcode, ignore
> +			   bit 31 */
> +    case 21:		/* Move To VSR Byte Mask Immediate opcode, ignore
> +			   bit 31 */

This looks like a copy/paste glitch.  Are these cases both for the same
"Move to VSR ..." ?

> +    case 23:		/* Vector Multiply-Sum & write Carry-out Unsigned
> +			   Doubleword */
> +    case 24:		/* Vector Extract Double Unsigned Byte to VSR
> +			   using GPR-specified Left-Index */
> +    case 25:		/* Vector Extract Double Unsigned Byte to VSR
> +			   using GPR-specified Right-Index */
> +    case 26:		/* Vector Extract Double Unsigned Halfword to VSR
> +			   using GPR-specified Left-Index */
> +    case 27:		/* Vector Extract Double Unsigned Halfword to VSR
> +			   using GPR-specified Right-Index */
> +    case 28:		/* Vector Extract Double Unsigned Word to VSR
> +			   using GPR-specified Left-Index */
> +    case 29:		/* Vector Extract Double Unsigned Word to VSR
> +			   using GPR-specified Right-Index */
> +    case 30:		/* Vector Extract Double Unsigned Doubleword to VSR
> +			   using GPR-specified Left-Index */
> +    case 31:		/* Vector Extract Double Unsigned Doubleword to VSR
> +			   using GPR-specified Right-Index */
>      case 42:		/* Vector Select */
>      case 43:		/* Vector Permute */
>      case 59:		/* Vector Permute Right-indexed */
> +    case 22: 		/* Vector Shift
> +			      Left  Double by Bit Immediate if insn[21] = 0
> +			      Right Double by Bit Immediate if insn[21] = 1 */
>      case 44:		/* Vector Shift Left Double by Octet Immediate */
>      case 45:		/* Vector Permute and Exclusive-OR */
>      case 60:		/* Vector Add Extended Unsigned Quadword Modulo */
> @@ -4236,6 +4333,9 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>    /* Bit-21 is used for RC */
>    switch (ext & 0x3ff)
>      {
> +    case 5:		/* Vector Rotate Left Quadword */
> +    case 69:		/* Vector Rotate Left Quadword then Mask Insert */
> +    case 325:		/* Vector Rotate Left Quadword then AND with Mask */
>      case 6:		/* Vector Compare Equal To Unsigned Byte */
>      case 70:		/* Vector Compare Equal To Unsigned Halfword */
>      case 134:		/* Vector Compare Equal To Unsigned Word */
> @@ -4244,13 +4344,16 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      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 903:		/* Vector Compare Greater Than Signed Quadword */
>      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 647:		/* Vector Compare Greater Than Unsigned Quadword */
>      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 455:		/* Vector Compare Equal Quadword */
>      case 710:		/* Vector Compare Greater Than Single-Precision */
>      case 7:		/* Vector Compare Not Equal Byte */
>      case 71:		/* Vector Compare Not Equal Halfword */
> @@ -4263,6 +4366,21 @@ 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 13:
> +      switch (vra)    /* Bit-21 is used for RC */
> +	{
> +	case 0:       /* Vector String Isolate Byte Left-justified */
> +	case 1:       /* Vector String Isolate Byte Right-justified */
> +	case 2:       /* Vector String Isolate Halfword Left-justified */
> +	case 3:       /* Vector String Isolate Halfword Right-justified */
> +	  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;
> +	}
>      }
> 
>    if (ext  == 1538)
> @@ -4287,6 +4405,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>  	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 27:	/* Vector Extend Sign Doubleword To Quadword */
>  	case 28:	/* Vector Count Trailing Zeros Byte */
>  	case 29:	/* Vector Count Trailing Zeros Halfword */
>  	case 30:	/* Vector Count Trailing Zeros Word */
> @@ -4297,8 +4416,58 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>  	}
>      }
> 
> +  if (ext == 1602)
> +    {
> +      switch (vra)
> +	{
> +	case 0: 	/* Vector Expand Byte Mask */
> +	case 1: 	/* Vector Expand Halfword Mask */
> +	case 2: 	/* Vector Expand Word Mask */
> +	case 3: 	/* Vector Expand Doubleword Mask */
> +	case 4: 	/* Vector Expand Quadword Mask */
> +	case 16:	/* Move to VSR Byte Mask */
> +	case 17:	/* Move to VSR Halfword Mask */
> +	case 18:	/* Move to VSR Word Mask */
> +	case 19:	/* Move to VSR Doubleword Mask */
> +	case 20:	/* Move to VSR Quadword Mask */
> +	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
> +	  return 0;
> +
> +	case 8: 	/* Vector Extract Byte Mask */
> +	case 9: 	/* Vector Extract Halfword Mask */
> +	case 10: 	/* Vector Extract Word Mask */
> +	case 11: 	/* Vector Extract Doubleword Mask */
> +	case 12: 	/* Vector Extract Quadword Mask */
> +
> +	/* vra field is used as additional opcode field.  Ignore the MP bit in
> +	   the LSB position. */

What does this comment mean, with respect to any of the nearby code?

> +	case 24:	/* Vector Count Mask Bits Byte */
> +	case 25:	/* Vector Count Mask Bits Byte */
> +	case 26:	/* Vector Count Mask Bits Halfword */
> +	case 27:	/* Vector Count Mask Bits Halfword */
> +	case 28:	/* Vector Count Mask Bits Word */
> +	case 29:	/* Vector Count Mask Bits Word */
> +	case 30:	/* Vector Count Mask Bits Doubleword */
> +	case 31:	/* Vector Count Mask Bits Doubleword */
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_gp0_regnum + PPC_RT (insn));
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_gp0_regnum + PPC_RT (insn));
> +	  return 0;
> +	}
> +    }
> +
>    switch (ext)
>      {
> +
> +    case 257:		/* Vector Compare Unsigned Quadword */
> +    case 321:		/* Vector Compare Signed Quadword */
> +      /* Comparison tests that always set CR field BF */
> +      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;
> +
>      case 142:		/* Vector Pack Unsigned Halfword Unsigned Saturate */
>      case 206:		/* Vector Pack Unsigned Word Unsigned Saturate */
>      case 270:		/* Vector Pack Signed Halfword Unsigned Saturate */
> @@ -4338,6 +4507,8 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 268:		/* Vector Merge Low Byte */
>      case 332:		/* Vector Merge Low Halfword */
>      case 396:		/* Vector Merge Low Word */
> +    case 397:		/* Vector Clear Leftmost Bytes */
> +    case 461:		/* Vector Clear Rightmost Bytes */
>      case 526:		/* Vector Unpack High Signed Byte */
>      case 590:		/* Vector Unpack High Signed Halfword */
>      case 654:		/* Vector Unpack Low Signed Byte */
> @@ -4356,8 +4527,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 780:		/* Vector Splat Immediate Signed Byte */
>      case 844:		/* Vector Splat Immediate Signed Halfword */
>      case 908:		/* Vector Splat Immediate Signed Word */
> +    case 261:		/* Vector Shift Left Quadword */
>      case 452:		/* Vector Shift Left */
> +    case 517:		/* Vector Shift Right Quadword */
>      case 708:		/* Vector Shift Right */
> +    case 773:		/* Vector Shift Right Algebraic Quadword */
>      case 1036:		/* Vector Shift Left by Octet */
>      case 1100:		/* Vector Shift Right by Octet */
>      case 0:		/* Vector Add Unsigned Byte Modulo */
> @@ -4370,15 +4544,43 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 8:		/* Vector Multiply Odd Unsigned Byte */
>      case 72:		/* Vector Multiply Odd Unsigned Halfword */
>      case 136:		/* Vector Multiply Odd Unsigned Word */
> +    case 200:		/* Vector Multiply Odd Unsigned Doubleword */
>      case 264:		/* Vector Multiply Odd Signed Byte */
>      case 328:		/* Vector Multiply Odd Signed Halfword */
>      case 392:		/* Vector Multiply Odd Signed Word */
> +    case 456:		/* Vector Multiply Odd Signed Doubleword */
>      case 520:		/* Vector Multiply Even Unsigned Byte */
>      case 584:		/* Vector Multiply Even Unsigned Halfword */
>      case 648:		/* Vector Multiply Even Unsigned Word */
> +    case 712:		/* Vector Multiply Even Unsigned Doubleword */
>      case 776:		/* Vector Multiply Even Signed Byte */
>      case 840:		/* Vector Multiply Even Signed Halfword */
>      case 904:		/* Vector Multiply Even Signed Word */
> +    case 968:		/* Vector Multiply Even Signed Doubleword */
> +    case 457:		/* Vector Multiply Low Doubleword */
> +    case 649:		/* Vector Multiply High Unsigned Word */
> +    case 713:		/* Vector Multiply High Unsigned Doubleword */
> +    case 905:		/* Vector Multiply High Signed Word */
> +    case 969:		/* Vector Multiply High Signed Doubleword */
> +    case 11:		/* Vector Divide Unsigned Quadword */
> +    case 203:		/* Vector Divide Unsigned Doubleword */
> +    case 139:		/* Vector Divide Unsigned Word */
> +    case 267:		/* Vector Divide Signed Quadword */
> +    case 459:		/* Vector Divide Signed Doubleword */
> +    case 395:		/* Vector Divide Signed Word */
> +    case 523:		/* Vector Divide Extended Unsigned Quadword */
> +    case 715:		/* Vector Divide Extended Unsigned Doubleword */
> +    case 651:		/* Vector Divide Extended Unsigned Word */
> +    case 779:		/* Vector Divide Extended Signed Quadword */
> +    case 971:		/* Vector Divide Extended Signed Doubleword */
> +    case 907:		/* Vector Divide Extended Unsigned Word */
> +    case 1547:		/* Vector Modulo Unsigned Quadword */
> +    case 1675:		/* Vector Modulo Unsigned Word */
> +    case 1739:		/* Vector Modulo Unsigned Doubleword */
> +    case 1803:		/* Vector Modulo Signed Quadword */
> +    case 1931:		/* Vector Modulo Signed Word */
> +    case 1995:		/* Vector Modulo Signed Doubleword */
> +
>      case 137:		/* Vector Multiply Unsigned Word Modulo */
>      case 1024:		/* Vector Subtract Unsigned Byte Modulo */
>      case 1088:		/* Vector Subtract Unsigned Halfword Modulo */
> @@ -4462,7 +4664,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 1794:		/* Vector Count Leading Zeros Byte */
>      case 1858:		/* Vector Count Leading Zeros Halfword */
>      case 1922:		/* Vector Count Leading Zeros Word */
> +    case 1924:		/* Vector Count Leading Zeros Doubleword under
> +			   bit Mask*/
>      case 1986:		/* Vector Count Leading Zeros Doubleword */
> +    case 1988:		/* Vector Count Trailing Zeros Doubleword under bit
> +			   Mask */
>      case 1795:		/* Vector Population Count Byte */
>      case 1859:		/* Vector Population Count Halfword */
>      case 1923:		/* Vector Population Count Word */
> @@ -4488,14 +4694,50 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 589:		/* Vector Extract Unsigned Halfword */
>      case 653:		/* Vector Extract Unsigned Word */
>      case 717:		/* Vector Extract Doubleword */
> +    case 15:		/* Vector Insert Byte from VSR using GPR-specified
> +			   Left-Index */
> +    case 79:		/* Vector Insert Halfword from VSR using GPR-specified
> +			   Left-Index */
> +    case 143:		/* Vector Insert Word from VSR using GPR-specified
> +			   Left-Index */
> +    case 207:		/* Vector Insert Word from GPR using
> +			   immediate-specified index */
> +    case 463:		/* Vector Insert Doubleword from GPR using
> +			   immediate-specified index */
> +    case 271:		/* Vector Insert Byte from VSR using GPR-specified
> +			   Right-Index */
> +    case 335:		/* Vector Insert Halfword from VSR using GPR-specified
> +			   Right-Index */
> +    case 399:		/* Vector Insert Word from VSR using GPR-specified
> +			   Right-Index */
> +    case 527:		/* Vector Insert Byte from GPR using GPR-specified
> +			   Left-Index */
> +    case 591:		/* Vector Insert Halfword from GPR using GPR-specified
> +			   Left-Index */
> +    case 655:		/* Vector Insert Word from GPR using GPR-specified
> +			   Left-Index */
> +    case 719:		/* Vector Insert Doubleword from GPR using
> +			    GPR-specified Left-Index */
> +    case 783:		/* Vector Insert Byte from GPR using GPR-specified
> +			   Right-Index */
> +    case 847:		/* Vector Insert Halfword from GPR using GPR-specified
> +			   Left-Index */
> +    case 911:		/* Vector Insert Word from GPR using GPR-specified
> +			   Left-Index */
> +    case 975:		/* Vector Insert Doubleword from GPR using
> +			    GPR-specified Right-Index */
>      case 781:		/* Vector Insert Byte */
>      case 845:		/* Vector Insert Halfword */
>      case 909:		/* Vector Insert Word */
>      case 973:		/* Vector Insert Doubleword */
> +    case 1357:		/* Vector Centrifuge Doubleword */
> +    case 1421:		/* Vector Parallel Bits Extract Doubleword */
> +    case 1485:		/* Vector Parallel Bits Deposit Doubleword */
>        record_full_arch_list_add_reg (regcache,
>  				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
>        return 0;
> 
> +    case 1228:		/* Vector Gather every Nth Bit */
>      case 1549:		/* Vector Extract Unsigned Byte Left-Indexed */
>      case 1613:		/* Vector Extract Unsigned Halfword Left-Indexed */
>      case 1677:		/* Vector Extract Unsigned Word Left-Indexed */
> @@ -4525,6 +4767,34 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>    return -1;
>  }
> 
> +/* Parse and record instructions of primary opcode 6 at ADDR.
> +   Return 0 if successful.  */
> +
> +static int
> +ppc_process_record_op6 (struct gdbarch *gdbarch, struct regcache *regcache,
> +			CORE_ADDR addr, uint32_t insn)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  int subtype = PPC_FIELD (insn, 28, 4);
> +  CORE_ADDR ea = 0;
> +
> +  switch (subtype)
> +    {
> +    case 0:    /* Load VSX Vector Paired */
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
> +      return 0;
> +    case 1:    /* Store VSX Vector Paired */
> +      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, 32);
> +      return 0;
> +    }
> +  return -1;
> +}
> +
>  /* Parse and record instructions of primary opcode-19 at ADDR.
>     Return 0 if successful.  */
> 
> @@ -4577,6 +4847,30 @@ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
>    return -1;
>  }
> 
> +/* Parse and record instructions of primary opcode-31 with the extended opcode
> +   177.  The argument is the word instruction (insn).  Return 0 if successful.
> +*/
> +
> +static int
> +ppc_process_record_op31_177 (struct gdbarch *gdbarch,
> +			     struct regcache *regcache,
> +			     uint32_t insn)
> +{
> +  int RA_opcode = PPC_RA(insn);
> +  int as = PPC_FIELD (insn, 6, 3);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  switch (RA_opcode)
> +    {
> +    case 0: 		/* VSX Move From Accumulator, xxmfacc */
> +    case 1: 		/* VSX Move To Accumulator, xxmtacc */
> +    case 3: 		/* VSX Set Accumulator to Zero, xxsetaccz */
> +      ppc_record_ACC_fpscr (regcache, tdep, as, DO_NOT_RECORD_FPSCR);
> +      return 0;
> +    }
> +  return -1;
> +}
> +
>  /* Parse and record instructions of primary opcode-31 at ADDR.
>     Return 0 if successful.  */
> 
> @@ -4586,7 +4880,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>  {
>    ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
>    int ext = PPC_EXTOP (insn);
> -  int tmp, nr, nb, i;
> +  int tmp, nr, nb = 0, i;
>    CORE_ADDR at_dcsz, ea = 0;
>    ULONGEST rb, ra, xer;
>    int size = 0;
> @@ -4677,6 +4971,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 371:		/* Move From Time Base [Phased-Out]  */
>      case 309:		/* Load Doubleword Monitored Indexed  */
>      case 128:		/* Set Boolean */
> +    case 384:		/* Set Boolean Condition */
> +    case 416:		/* Set Boolean Condition Reverse */
> +    case 448:		/* Set Negative Boolean Condition */
> +    case 480:		/* Set Negative Boolean Condition Reverse */
>      case 755:		/* Deliver A Random Number */
>        record_full_arch_list_add_reg (regcache,
>  				     tdep->ppc_gp0_regnum + PPC_RT (insn));
> @@ -4684,8 +4982,15 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
> 
>      /* These only write to RA.  */
>      case 51:		/* Move From VSR Doubleword */
> +    case 59:		/* Count Leading Zeros Doubleword under bit Mask */
>      case 115:		/* Move From VSR Word and Zero */
>      case 122:		/* Population count bytes */
> +    case 155:		/* Byte-Reverse Word */
> +    case 156:		/* Parallel Bits Deposit Doubleword */
> +    case 187:		/* Byte-Reverse Doubleword */
> +    case 188:		/* Parallel Bits Extract Doubleword */
> +    case 219:		/* Byte-Reverse Halfword */
> +    case 220:		/* Centrifuge Doubleword */
>      case 378:		/* Population count words */
>      case 506:		/* Population count doublewords */
>      case 154:		/* Parity Word */
> @@ -4695,6 +5000,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 314:		/* Convert Binary Coded Decimal To Declets */
>      case 508:		/* Compare bytes */
>      case 307:		/* Move From VSR Lower Doubleword */
> +    case 571:		/* Count Trailing Zeros Doubleword under bit Mask */
>        record_full_arch_list_add_reg (regcache,
>  				     tdep->ppc_gp0_regnum + PPC_RA (insn));
>        return 0;
> @@ -4819,6 +5125,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>        record_full_arch_list_add_reg (regcache, tmp + 1);
>        return 0;
> 
> +    /* These write RT. */

PPC_RT ?

>      case 179:		/* Move To VSR Doubleword */
>      case 211:		/* Move To VSR Word Algebraic */
>      case 243:		/* Move To VSR Word and Zero */
> @@ -4826,6 +5133,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>      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 13:		/* Load VSX Vector Rightmost Byte Indexed */
> +    case 45:		/* Load VSX Vector Rightmost Halfword Indexed */
> +    case 77:		/* Load VSX Vector Rightmost Word Indexed */
> +    case 109:		/* Load VSX Vector Rightmost Doubleword 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 */
> @@ -4842,6 +5153,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>        ppc_record_vsr (regcache, tdep, PPC_XT (insn));
>        return 0;
> 
> +    case 333:		/* Load VSX Vector Paired Indexed */
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
> +      return 0;
> +
>      /* These write RA.  Update CR if RC is set.  */
>      case 24:		/* Shift Left Word */
>      case 26:		/* Count Leading Zeros Word */
> @@ -5006,6 +5322,31 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>        record_full_arch_list_add_mem (ea, size);
>        return 0;
> 
> +    case 141:		/* Store VSX Vector Rightmost Byte Indexed */
> +    case 173:		/* Store VSX Vector Rightmost Halfword Indexed */
> +    case 205:		/* Store VSX Vector Rightmost Word Indexed */
> +    case 237:		/* Store VSX Vector Rightmost Doubleword Indexed */
> +      switch(ext)
> +	{
> +	  case 141: nb = 1;
> +	  break;
> +	  case 173: nb = 2;
> +	  break;
> +	  case 205: nb = 4;
> +	  break;
> +	  case 237: nb = 8;
> +	  break;
> +	}
> +      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;
> +      record_full_arch_list_add_mem (ea, nb);
> +      return 0;
> +
>      case 397:		/* Store VSX Vector with Length */
>      case 429:		/* Store VSX Vector Left-justified with Length */
>        ra = 0;
> @@ -5021,6 +5362,19 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>  	record_full_arch_list_add_mem (ea, nb);
>        return 0;
> 
> +    case 461:		/* Store VSX Vector Paired Indexed */
> +      {
> +	if (PPC_RA (insn) != 0)
> +	  regcache_raw_read_unsigned (regcache,
> +				      tdep->ppc_gp0_regnum
> +				      + PPC_RA (insn), &ea);
> +	regcache_raw_read_unsigned (regcache,
> +				    tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
> +	ea += rb;
> +	record_full_arch_list_add_mem (ea, 32);
> +	return 0;
> +      }
> +
>      case 710:		/* Store Word Atomic */
>      case 742:		/* Store Doubleword Atomic */
>        ra = 0;
> @@ -5166,6 +5520,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>        ea = (ra + rb) & ~((ULONGEST) (at_dcsz - 1));
>        record_full_arch_list_add_mem (ea, at_dcsz);
>        return 0;
> +
> +    case 177:
> +      if (ppc_process_record_op31_177 (gdbarch, regcache, insn) == 0)
> +	return 0;
>      }
> 
>  UNKNOWN_OP:
> @@ -5179,10 +5537,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
> 
>  static int
>  ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
> -			   CORE_ADDR addr, uint32_t insn)
> +			 CORE_ADDR addr, uint32_t insn)
>  {
>    ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
>    int ext = PPC_EXTOP (insn);
> +  int at = PPC_FIELD (insn, 6, 3);
> 
>    switch (ext & 0x1f)
>      {
> @@ -5206,6 +5565,75 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
>        return 0;
>      }
> 
> +  /* MMA instructions, if no match keep looking.  */


Can probably drop "if no match..." fragment.


> +  switch (ext >> 2)    /* Additioanl opcode field is upper 8-bits of ext */

Additional



> +    {
> +    case 3:	/* VSX Vector 8-bit Signed/Unsigned Integer GER, xvi8ger4 */
> +    case 2:	/* VSX Vector 8-bit Signed/Unsigned Integer GER Positive
> +		   multiply, Positive accumulate, xvi8ger4pp */
> +
> +    case 99:	/* VSX Vector 8-bit Signed/Unsigned Integer GER with
> +		   Saturate Positive multiply, Positive accumulate,
> +		   xvi8ger4spp */
> +
> +    case 35:	/* VSX Vector 4-bit Signed Integer GER, xvi4ger8 */
> +    case 34:	/* VSX Vector 4-bit Signed Integer GER Positive multiply,
> +		   Positive accumulate, xvi4ger8pp */
> +
> +    case 75:	/* VSX Vector 16-bit Signed Integer GER, xvi16ger2 */
> +    case 107:	/* VSX Vector 16-bit Signed Integer GER  Positive multiply,
> +		   Positive accumulate, xvi16ger2pp */
> +
> +    case 43:	/* VSX Vector 16-bit Signed Integer GER with Saturation,
> +		   xvi16ger2s */
> +    case 42:	/* VSX Vector 16-bit Signed Integer GER with Saturation
> +		   Positive multiply, Positive accumulate, xvi16ger2spp */
> +      ppc_record_ACC_fpscr (regcache, tdep, at, DO_NOT_RECORD_FPSCR);
> +      return 0;
> +
> +    case 19:	/* VSX Vector 16-bit Floating-Point GER, xvf16ger2 */
> +    case 18:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
> +		   Positive accumulate, xvf16ger2pp */
> +    case 146:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
> +		   Negative accumulate, xvf16ger2pn */
> +    case 82:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
> +		   Positive accumulate, xvf16ger2np */
> +    case 210:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
> +		   Negative accumulate, xvf16ger2nn */
> +
> +    case 27:	/* VSX Vector 32-bit Floating-Point GER, xvf32ger */

> +    case 26:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
> +		   Positive accumulate, xvf32gerpp */

> +    case 154:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
> +		   Negative accumulate, xvf32gerpn */

> +    case 90:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
> +		   Positive accumulate, xvf32gernp */

> +    case 218:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
> +		   Negative accumulate, xvf32gernn */
> +
> +    case 59:	/* VSX Vector 64-bit Floating-Point GER */

For consistency, add the appropriate xvf... instruction in the comment
there. 

> +    case 58:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
> +		   Positive accumulate, xvf64gerpp */

> +    case 186:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
> +		   Negative accumulate, xvf64gerpn */

> +    case 122:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
> +		   Positive accumulate, xvf64gernp */

> +    case 250:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
> +		   Negative accumulate */

And here.

> +
> +    case 51:	/* VSX Vector bfloat16 GER, xvbf16ger2 */

> +    case 50:	/* VSX Vector bfloat16 GER Positive multiply,
> +		   Positive accumulate, xvbf16ger2pp */

> +    case 178:	/* VSX Vector bfloat16 GER Positive multiply,
> +		   Negative accumulate, xvbf16ger2pn */

> +    case 114:	/* VSX Vector bfloat16 GER Negative multiply,
> +		   Positive accumulate, xvbf16ger2np */

> +    case 242:	/* VSX Vector bfloat16 GER Negative multiply,
> +		   Negative accumulate, xvbf16ger2nn */


> +      ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
> +      return 0;
> +    }
> +
>    switch (ext)
>      {
>      case 2:		/* DFP Add */
> @@ -5268,6 +5696,48 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
>    return -1;
>  }
> 
> +/* Parse and record instructions of primary opcode-60 form XXX at ADDR.  The
> +   word instruction is in argument insn.  Return 0 if successful.  */

"is an" ?

Would the comment make more sense if the "primary opcode-60 form XXX"
is replaced with "XXX-Form instruction with opcode 60" ?
This should
actually be XX2-form.  (Noting that these are the instruction forms
that are documented in the Power ISA).


> +
> +static int
> +ppc_process_record_op60_XX2 (struct gdbarch *gdbarch,
> +			     struct regcache *regcache,
> +			     CORE_ADDR addr, uint32_t insn)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  int RA_opcode = PPC_RA(insn);
> +
> +  switch (RA_opcode)
> +    {
> +    case 2:	/* VSX Vector Test Least-Significant Bit by Byte */
> +    case 25:	/* VSX Vector round and Convert Single-Precision format
> +		   to Half-Precision format.  Only changes the CR
> +		   field.  */
> +      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
> +      return 0;
> +    case 17:	/* VSX Vector Convert with round Single-Precision
> +		   to bfloat16 format */
> +    case 24:	/* VSX Vector Convert Half-Precision format to
> +		   Single-Precision format */
> +      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
> +      /* FALL-THROUGH */

I suggest changing the comment to lower case.  (I note this is
copy/paste/modify from elsewhere).

> +    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 16:	/* VSX Vector Convert bfloat16 to Single-Precision
> +		   format Non-signaling */
> +    case 23:	/* VSX Vector Byte-Reverse Doubleword */
> +    case 31:	/* VSX Vector Byte-Reverse Quadword */
> +      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
> +      return 0;
> +    }
> +
> +  return -1;
> +}
> +
>  /* Parse and record instructions of primary opcode-60 at ADDR.
>     Return 0 if successful.  */
> 
> @@ -5583,37 +6053,30 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
>        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;
> +      if (ppc_process_record_op60_XX2 (gdbarch, regcache, addr, insn) != 0)
> +	return -1;
> +      return 0;
>      }
> 
>    switch (ext)
>      {
> -    case 360:		/* VSX Vector Splat Immediate Byte */
> -      if (PPC_FIELD (insn, 11, 2) == 0)
> +    case 360:
> +      if (PPC_FIELD (insn, 11, 2) == 0)  /* VSX Vector Splat Immediate Byte */
> +	{
> +	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
> +	  return 0;
> +	}
> +      if (PPC_FIELD (insn, 11, 5) == 31)  /* Load VSX Vector Special Value
> +					     Quadword */
>  	{
>  	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
>  	  return 0;
>  	}
>        break;
> +    case 916:		/* VSX Vector Generate PCV from Byte Mask */
> +    case 917:		/* VSX Vector Generate PCV from Halfword Mask */
> +    case 948:		/* VSX Vector Generate PCV from Word Mask */
> +    case 949:		/* VSX Vector Generate PCV from Word Mask */

Both "Word Mask" ? 


>      case 918:		/* VSX Scalar Insert Exponent Double-Precision */
>        ppc_record_vsr (regcache, tdep, PPC_XT (insn));
>        return 0;
> @@ -5894,6 +6357,35 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
>  			   Quad-Precision */
>      case 516:		/* VSX Scalar Subtract Quad-Precision */
>      case 548:		/* VSX Scalar Divide Quad-Precision */
> +    case 994:
> +      {
> +      switch (PPC_FIELD (insn, 11, 5))
> +	{
> +	case 0:	/* DFP Convert From Fixed Quadword Quad */
> +	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
> +
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_fp0_regnum
> +					 + PPC_FRT (insn));
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_fp0_regnum
> +					 + PPC_FRT (insn) + 1);
> +	  return 0;
> +	case 1:	/* DFP Convert To Fixed Quadword Quad */
> +	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
> +	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
> +	  return 0;
> +	}
> +      }
> +
> +      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
> +      /* FALL-THROUGH */
> +    case 68:		/* VSX Scalar Compare Equal Quad-Precision */
> +    case 196:		/* VSX Scalar Compare Greater Than or Equal
> +			   Quad-Precision */
> +    case 228:		/* VSX Scalar Compare Greater Than Quad-Precision */
> +    case 676:		/* VSX Scalar Maximum Type-C Quad-Precision */
> +    case 740:		/* VSX Scalar Minimum Type-C Quad-Precision */
>        record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
>        /* FALL-THROUGH */
>      case 100:		/* VSX Scalar Copy Sign Quad-Precision */
> @@ -5920,14 +6412,22 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 836:
>        switch (PPC_FIELD (insn, 11, 5))
>  	{
> +	case 0:		/* VSX Scalar Convert with round to zero
> +			   Quad-Precision to Unsigned Quadword  */
>  	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 3:		/* VSX Scalar Convert with round
> +			   Unsigned Quadword to Quad-Precision  */
> +	case 8:		/* VSX Scalar Convert with round to zero
> +			   Quad-Precision to Signed Quadword  */
>  	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 11:	/* VSX Scalar Convert with round
> +			   Signed Quadword to Quad-Precision */
>  	case 17:	/* VSX Scalar truncate & Convert Quad-Precision format
>  			   to Unsigned Doubleword format */
>  	case 20:	/* VSX Scalar round & Convert Quad-Precision format to
> @@ -5947,17 +6447,651 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
>    return -1;
>  }
> 
> +/* Record the prefixed instructions with primary opcode 32.  The arguments are
> +   the first 32-bits of the instruction (insn_prefix), and the second 32-bits
> +   of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_op42 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +
> +  if (ST1 != 0)
> +    return -1;
> +
> +  switch (type)
> +    {
> +    case 0:  /* Prefixed Load VSX Scalar Doubleword, plxsd */
> +      ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
> +      break;
> +    case 2:  /* Prefixed Load Halfword Algebraic, plha */
> +      record_full_arch_list_add_reg (regcache,
> +				     tdep->ppc_gp0_regnum
> +				     + PPC_RT (insn_suffix));
> +      break;
> +    default:
> +      return -1;
> +    }
> +  return 0;
> +}
> +
> +/* Record the prefixed instructions with primary opcode 59 of type XX3.  The
> +   arguments are the first 32-bits of the instruction (insn_prefix), and the
> +   second 32-bits of the instruction (insn_suffix).  Return 0 on success.  */

s/type XX3/XX3-FORM/ ?

> +
> +static int
> +ppc_process_record_prefix_op59_XX3 (struct gdbarch *gdbarch,
> +				    struct regcache *regcache,
> +				    uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  int opcode = PPC_FIELD (insn_suffix, 21, 8);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  int at = PPC_FIELD (insn_suffix, 6, 3);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  if (type == 3)
> +    {
> +      if (ST4 == 9)
> +	switch (opcode)
> +	  {
> +	  case 35:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
> +			   MMIRR, pmxvi4ger8 */
> +	  case 34:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
> +			   MMIRR, pmxvi4ger8pp */
> +
> +	  case 99:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
> +			   Integer GER with Saturate Positive multiply,
> +			   Positive accumulate, xvi8ger4spp */
> +
> +	  case 3:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
> +			   Integer GER MMIRR, pmxvi8ger4 */
> +	  case 2:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
> +			   Integer GER Positive multiply, Positive accumulate
> +			   MMIRR, pmxvi8ger4pp */
> +
> +	  case 75:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
> +			   GER MMIRR, pmxvi16ger2 */
> +	  case 107:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
> +			   GER  Positive multiply, Positive accumulate,
> +			   pmxvi16ger2pp */
> +
> +	  case 43:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
> +			   GER with Saturation MMIRR, pmxvi16ger2s */
> +	  case 42:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
> +			   GER with Saturation Positive multiply, Positive
> +			   accumulate MMIRR, pmxvi16ger2spp */
> +	    ppc_record_ACC_fpscr (regcache, tdep, at, DO_NOT_RECORD_FPSCR);
> +	    return 0;
> +
> +	  case 19:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER MMIRR, pmxvf16ger2 */
> +	  case 18:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER Positive multiply, Positive accumulate MMIRR,
> +			   pmxvf16ger2pp */
> +	  case 146:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER Positive multiply, Negative accumulate MMIRR,
> +			   pmxvf16ger2pn */
> +	  case 82:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER Negative multiply, Positive accumulate MMIRR,
> +			   pmxvf16ger2np */
> +	  case 210:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER Negative multiply, Negative accumulate MMIRR,
> +			   pmxvf16ger2nn */
> +
> +	  case 27:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER MMIRR, pmxvf32ger */
> +	  case 26:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER Positive multiply, Positive accumulate MMIRR,
> +			   pmxvf32gerpp */
> +	  case 154:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER Positive multiply, Negative accumulate MMIRR,
> +			   pmxvf32gerpn */
> +	  case 90:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER Negative multiply, Positive accumulate MMIRR,
> +			   pmxvf32gernp */
> +	  case 218:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER Negative multiply, Negative accumulate MMIRR,
> +			   pmxvf32gernn */
> +
> +	  case 59:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
> +			   GER MMIRR, pmxvf64ger */
> +	  case 58:	/* Floating-Point GER Positive multiply, Positive
> +			   accumulate MMIRR, pmxvf64gerpp */
> +	  case 186:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
> +			   GER Positive multiply, Negative accumulate MMIRR,
> +			   pmxvf64gerpn */
> +	  case 122:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
> +			   GER Negative multiply, Positive accumulate MMIRR,
> +			   pmxvf64gernp */
> +	  case 250:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
> +			   GER Negative multiply, Negative accumulate MMIRR,
> +			   pmxvf64gernn */
> +
> +	  case 51:	/* Prefixed Masked VSX Vector bfloat16 GER MMIRR,
> +			   pmxvbf16ger2 */
> +	  case 50:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
> +			   multiply, Positive accumulate MMIRR,
> +			   pmxvbf16ger2pp */
> +	  case 178:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
> +			   multiply, Negative accumulate MMIRR,
> +			   pmxvbf16ger2pn */
> +	  case 114:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
> +			   multiply, Positive accumulate MMIRR,
> +			   pmxvbf16ger2np */
> +	  case 242:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
> +			   multiply, Negative accumulate MMIRR,
> +			   pmxvbf16ger2nn */
> +	    ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
> +	    return 0;
> +	  }
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed store instructions.  The arguments are the instruction
> +   address, the first 32-bits of the instruction(insn_prefix) and the following
> +   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_store (struct gdbarch *gdbarch,
> +				 struct regcache *regcache,
> +				 CORE_ADDR addr, uint32_t insn_prefix,
> +				 uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  ULONGEST iaddr = 0;
> +  int size;
> +  int R = PPC_BIT (insn_prefix, 11);
> +  int op6 = PPC_OP6 (insn_suffix);
> +
> +  if (R == 0)
> +    {
> +      if (PPC_RA (insn_suffix) != 0)
> +	regcache_raw_read_unsigned (regcache, tdep->ppc_gp0_regnum
> +				    + PPC_RA (insn_suffix), &iaddr);
> +    }
> +  else
> +    {
> +      iaddr = addr;     /* PC relative */
> +    }
> +
> +  switch (op6)
> +    {
> +    case 38:
> +      size =  1;    /* store byte, pstb */
> +      break;
> +    case 44:
> +      size =  2;    /* store halfword, psth */
> +      break;
> +    case 36:
> +    case 52:
> +      size =  4;    /* store word, pstw, pstfs */
> +      break;
> +    case 54:
> +    case 61:
> +      size =  8;    /* store double word, pstd, pstfd */
> +      break;
> +    case 60:
> +      size = 16;    /* store quadword, pstq */
> +      break;
> +    default: return -1;
> +    }
> +
> +  iaddr += P_PPC_D (insn_prefix, insn_suffix);
> +  record_full_arch_list_add_mem (iaddr, size);
> +  return 0;
> +}
> +
> +/* Record the prefixed instructions with primary op code 32.  The arguments
> +   are the first 32-bits of the instruction(insn_prefix) and the following
> +   32-bits of the instruction (insn_suffix).  Return 0 on success.  */

No preference to which, but space between instruction and (insn_prefix)
shoud be consistently there, or not.  


> +
> +static int
> +ppc_process_record_prefix_op32 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  if (type == 1)
> +    {
> +      if (ST4 == 0)
> +	{
> +	  switch (PPC_FIELD (insn_suffix, 11, 3))
> +	    {
> +	    case 0:  	/* VSX Vector Splat Immediate Word 8RR, xxsplti32dx */
> +	      ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
> +	      return 0;
> +	    }
> +
> +	  switch (PPC_FIELD (insn_suffix, 11, 4))
> +	    {
> +	    case 2:  	/* VSX Vector Splat Immediate Double-Precision
> +			   8RR, xxspltidp */
> +	    case 3:  	/* VSX Vector Splat Immediate Word 8RR, xxspltiw */
> +	      ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
> +	      return 0;
> +	    default:
> +	      return -1;
> +	    }
> +	}
> +      else
> +	return -1;
> +
> +    }
> +  else if (type == 2)
> +    {
> +      if (ST1 == 0)  		/* Prefixed Load Word and Zero, plwz */
> +	record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	return -1;
> +
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed instructions with primary op code 33.  The arguments
> +   are the first 32-bits of the instruction(insn_prefix) and the following
> +   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_op33 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  if (type == 1)
> +    {
> +      if (ST4 == 0)
> +	switch (PPC_FIELD (insn_suffix, 26, 2))
> +	  {
> +	  case 0:  	/* VSX Vector Blend Variable Byte 8RR, xxblendvb */
> +	  case 1:  	/* VSX Vector Blend Variable Halfword, xxblendvh */
> +	  case 2:  	/* VSX Vector Blend Variable Word, xxblendvw */
> +	  case 3:  	/* VSX Vector Blend Variable Doubleword, xxblendvd */
> +	    ppc_record_vsr (regcache, tdep, PPC_XT (insn_suffix));
> +	  break;
> +	  default:
> +	    return -1;
> +	  }
> +      else
> +	return -1;
> +
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed instructions with primary op code 34.  The arguments
> +   are the first 32-bits of the instruction(insn_prefix) and the following
> +   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_op34 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  if (type == 1)
> +    {
> +      if (ST4 == 0)
> +	switch (PPC_FIELD (insn_suffix, 26, 2))
> +	  {
> +	  case 0:  	/* VSX Vector Permute Extended 8RR, xxpermx */
> +	  case 1:  	/* VSX Vector Evaluate 8RR, xxeval */
> +	    ppc_record_vsr (regcache, tdep, P_PPC_XT (insn_suffix));
> +	    break;
> +	  default:
> +	    return -1;
> +	  }
> +      else
> +	return -1;
> +
> +    }
> +  else if (type == 2)
> +    {
> +      if (ST1 == 0)  		/* Prefixed Load Word and Zero, plbz */
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	return -1;
> +
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed VSX store, form DS, instructions.  The arguments are the
> +   instruction address (addr), the first 32-bits of the instruction
> +   (insn_prefix) followed by the 32-bit instruction suffix (insn_suffix).
> +   Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_store_vsx_ds_form (struct gdbarch *gdbarch,
> +					     struct regcache *regcache,
> +					     CORE_ADDR addr,
> +					     uint32_t insn_prefix,
> +					     uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  ULONGEST ea = 0;
> +  int size;
> +  int R = PPC_BIT (insn_prefix, 11);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +
> +  if ((type == 0) && (ST1 == 0))
> +    {
> +      if (R == 0)
> +	{
> +	  if (PPC_RA (insn_suffix) != 0)
> +	    regcache_raw_read_unsigned (regcache,
> +					tdep->ppc_gp0_regnum
> +					+ PPC_RA (insn_suffix),
> +					&ea);
> +	}
> +      else
> +	{
> +	  ea = addr;     /* PC relative */
> +	}
> +
> +      ea += P_PPC_D (insn_prefix, insn_suffix);
> +      switch (PPC_FIELD (insn_suffix, 0, 6))
> +	{
> +	case 46:    /* Prefixed Store VSX Scalar Doubleword, pstxsd */
> +	  size = 8;
> +	  break;
> +	case 47:    /* Prefixed,Store VSX Scalar Single-Precision, pstxssp */
> +	  size = 4;
> +	  break;
> +	default:
> +	  return -1;
> +	}
> +      record_full_arch_list_add_mem (ea, size);
> +      return 0;
> +  }
> +  else
> +    return -1;
> +}
> +
> +/* Record the prefixed VSX, form D, instructions.  The arguments are the
> +   instruction address for PC-relative addresss (addr), the first 32-bits of
> +   the instruction (insn_prefix) and the following 32-bits of the instruction
> +   (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_vsx_d_form (struct gdbarch *gdbarch,
> +				      struct regcache *regcache,
> +				      CORE_ADDR addr,
> +				      uint32_t insn_prefix,
> +				      uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  ULONGEST ea = 0;
> +  int size;
> +  int R = PPC_BIT (insn_prefix, 11);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +
> +  if ((type == 0) && (ST1 == 0))
> +    {
> +      switch (PPC_FIELD (insn_suffix, 0, 5))
> +	{
> +	case 25:	/* Prefixed Load VSX Vector, plxv */
> +	  ppc_record_vsr (regcache, tdep, P_PPC_XT5 (insn_prefix));
> +	  return 0;
> +	case 27:	/* Prefixed Store VSX Vector 8LS, pstxv */
> +	  {
> +	    size = 16;
> +	    if (R == 0)
> +	      {
> +		if (PPC_RA (insn_suffix) != 0)
> +		  regcache_raw_read_unsigned (regcache,
> +					      tdep->ppc_gp0_regnum
> +					      + PPC_RA (insn_suffix),
> +					      &ea);
> +	      }
> +	    else
> +	      {
> +		ea = addr;     /* PC relative */
> +	      }
> +
> +	    ea += P_PPC_D (insn_prefix, insn_suffix);
> +	    record_full_arch_list_add_mem (ea, size);
> +	    return 0;
> +	  }
> +	}
> +      return -1;
> +    }
> +  else
> +    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.  */
> 
> +/* This is the main function for handling the recording of the various prefix
> +   instructions.  It takes the instruction address, the first 32-bits of the
> +   instruction (insn_prefix) and the following 32-bits of the instruction
> +   (insn_suffix).  Return 0 on success.  */

s/is the main function for handling/handles/


> +
> +static int
> +ppc_process_prefix_instruction (int insn_prefix, int insn_suffix,
> +				CORE_ADDR addr,	struct gdbarch *gdbarch,
> +				struct regcache *regcache)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  int op6;
> +
> +  /* D-form has uses a 5-bit opcode in the instruction suffix */
> +  if (ppc_process_record_prefix_vsx_d_form ( gdbarch, regcache, addr,
> +					     insn_prefix, insn_suffix) == 0)
> +    goto SUCCESS;
> +
> +  op6 = PPC_OP6 (insn_suffix);  /* 6-bit opcode in the instruction suffix */
> +
> +  switch (op6)
> +    {
> +    case 14:		/* Prefixed Add Immediate, paddi */
> +      if ((type == 2) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 32:
> +      if (ppc_process_record_prefix_op32 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 33:
> +      if (ppc_process_record_prefix_op33 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 34:		/* Prefixed Load Byte and Zero, plbz */
> +      if (ppc_process_record_prefix_op34 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +    case 40:		/* Prefixed Load Halfword and Zero, plhz */
> +      if ((type == 2) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +      break;
> +
> +    case 36:		/* Prefixed Store Word, pstw */
> +    case 38:		/* Prefixed Store Byte, pstb */
> +    case 44:		/* Prefixed Store Halfword, psth */
> +    case 52:		/* Prefixed Store Floating-Point Single, pstfs */
> +    case 54:		/* Prefixed Store Floating-Point Double, pstfd */
> +    case 60:		/* Prefixed Store Quadword, pstq */
> +    case 61:		/* Prefixed Store Doubleword, pstd */
> +      if (ppc_process_record_prefix_store (gdbarch, regcache, addr,
> +					   insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 42:
> +      if (ppc_process_record_prefix_op42 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 43:          /* Prefixed Load VSX Scalar Single-Precision, plxssp */
> +      if ((type == 0) && (ST1 == 0))
> +	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
> +      else
> +	  goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 46:
> +    case 47:
> +      if (ppc_process_record_prefix_store_vsx_ds_form (gdbarch, regcache, addr,
> +					       insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 56:		/* Prefixed Load Quadword, plq */
> +      {
> +	if ((type == 0) && (ST1 == 0))
> +	  {
> +	    int tmp;
> +	    tmp = tdep->ppc_gp0_regnum + (PPC_RT (insn_suffix) & ~1);
> +	    record_full_arch_list_add_reg (regcache, tmp);
> +	    record_full_arch_list_add_reg (regcache, tmp + 1);
> +	  }
> +	else
> +	  goto UNKNOWN_PREFIX_OP;
> +	break;
> +      }
> +
> +    case 41:		/* Prefixed Load Word Algebraic, plwa */
> +    case 57:  		/* Prefixed Load Doubleword, pld */
> +      if ((type == 0) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 48:		/* Prefixed Load Floating-Point Single, plfs */
> +    case 50:		/* Prefixed Load Floating-Point Double, plfd */
> +      if ((type == 2) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_fp0_regnum
> +				       + PPC_FRT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 58:		/* Prefixed Load VSX Vector Paired, plxvp */
> +      if ((type == 0) && (ST1 == 0))
> +	{
> +	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix));
> +	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix) + 1);
> +	}
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 59:
> +      if (ppc_process_record_prefix_op59_XX3 (gdbarch, regcache, insn_prefix,
> +					      insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 62:	    /* Prefixed Store VSX Vector Paired 8LS, pstxvp */
> +      if ((type == 0) && (ST1 == 0))
> +	{
> +	  int R = PPC_BIT (insn_prefix, 11);
> +	  CORE_ADDR ea = 0;
> +
> +	  if (R == 0)
> +	    {
> +	      if (PPC_RA (insn_suffix) != 0)
> +		regcache_raw_read_unsigned (regcache,
> +					    tdep->ppc_gp0_regnum
> +					    + PPC_RA (insn_suffix), &ea);
> +	    }
> +	  else
> +	    {
> +	      ea = addr;     /* PC relative */
> +	    }
> +
> +	  ea += P_PPC_D (insn_prefix, insn_suffix) << 4;
> +	  record_full_arch_list_add_mem (ea, 32);
> +	}
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    default:
> +    UNKNOWN_PREFIX_OP:

The non-prefix flavor of this goto target has "UNKNOWN_OP:" fully left
justified. 


> +      gdb_printf (gdb_stdlog,
> +		  "Warning: Don't know how to record prefix inst "
> +		  "%08x %08x at %s, %d.\n",
> +		  insn_prefix, insn_suffix, paddress (gdbarch, addr),
> +		  op6);

Spell out instruction in printf. (it is not abbreviated in other
printf's in this file). 

> +      return -1;
> +    }
> +
> + SUCCESS:
> +  if (record_full_arch_list_add_reg (regcache, PPC_PC_REGNUM))
> +    return -1;
> +
> +  if (record_full_arch_list_add_end ())
> +    return -1;
> +  return 0;
> +}
> +
>  int
>  ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
>  		      CORE_ADDR addr)
>  {
>    ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
>    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
> -  uint32_t insn;
> +  uint32_t insn, insn_suffix;
>    int op6, tmp, i;
> 
>    insn = read_memory_unsigned_integer (addr, 4, byte_order);
> @@ -5965,6 +7099,13 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
> 
>    switch (op6)
>      {
> +    case 1:		/* prefixed instruction */
> +      {
> +	/* Get the lower 32-bits of the prefixed instruction. */
> +	insn_suffix = read_memory_unsigned_integer (addr+4, 4, byte_order);
> +	return ppc_process_prefix_instruction (insn, insn_suffix, addr,
> +					       gdbarch, regcache);
> +      }
>      case 2:		/* Trap Doubleword Immediate */
>      case 3:		/* Trap Word Immediate */
>        /* Do nothing.  */
> @@ -5975,6 +7116,11 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
>  	return -1;
>        break;
> 
> +    case 6:
> +      if (ppc_process_record_op6 (gdbarch, regcache, addr, insn) != 0)

Comment if possible? 


Thanks,
-Will

> +	return -1;
> +      break;
> +
>      case 17:		/* System call */
>        if (PPC_LEV (insn) != 0)
>  	goto UNKNOWN_OP;


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/2 Version 2] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-12 17:09     ` [PATCH 2/2 Version 2] " Carl Love
@ 2022-04-13 14:12       ` will schmidt
  2022-04-13 21:38         ` [PATCH 2/2 Version 3] " Carl Love
  0 siblings, 1 reply; 25+ messages in thread
From: will schmidt @ 2022-04-13 14:12 UTC (permalink / raw)
  To: Carl Love, Joel Brobecker, gdb-patches
  Cc: Ulrich Weigand, Tulio Magno, Rogerio Alves

On Tue, 2022-04-12 at 10:09 -0700, Carl Love via Gdb-patches wrote:
> Joel, GDB maintainers:
> 
> On Sun, 2022-03-06 at 16:42 +0400, Joel Brobecker via Gdb-patches
> wrote:
> 
> <snip>
> 
> > I am not a specialist of writing testcases in the GDB testsuite,
> > anymore, so others may have more comments. In the meantime, here
> > are the things I saw.
> > 
> > FWIW, the description you provide at the start of this email would
> > also be useful to have in the commit message as well, to give people
> > a record of what you did without having to read your email version.
> > 
> 
> I believe you are referring to the testing of the patch.  Added the
> testing to the commit message.

The context was snipped from the replies, so no way to tell without digging up the original. 
(found it..)
The original 2/2 started with 

> The patch adds the gdb recording test cases for the Powerpc ISA 2.06
> and ISA 3.1 instruction sets.


> 
> > One general note: The formatting seems to have been affected by
> > the sending, which surprises me a little, as this was sent by
> > "git send-email", is that right? What makes me say this is because
> > we see a number of lines where it looks like the text was moved
> > to the next line. E.g.
> > 
> > > +###### Test 1:  Test an ISA 2.06 load (lxvd2x) and square root
> > > instructiion
> > > +###### (xvsqrtsp).  The load instruction will load vs1.  The sqrt
> > > instruction
> > 
> > I'm going to assume this is correct in your patch, but it would
> > be nice to figure out where this is coming from.
> > 
> That was my screw up on setting the formatting in the email message. 
> Fixed.
> 
> > > +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
> > 
> > Can you please add a copyright header to this file, and more
> > generally, to all new files?
> 
> Fixed.
> 
> > > +/* globals used for vector tests */
> > > +static vector unsigned long vec_xa, vec_xb, vec_xt;
> > > +static unsigned long ra, rb, rs;
> > > +
> > > +int main () {
> 
> Fixed.
> 
> <snip?
> > > +# The basic flow of the record tests are:
> > > +#    1) Stop before executing the instructions of interest. Record
> > 
> > Missing second space after period.
> 
> fixed.
> > > +standard_testfile ppc_record_test_isa_2_06.c
> > 
> > Just thinking out loud: Wondering if ppc_record_test_isa_2_06.c
> > is actually needed, here...
> 
> Nope, removed the name of the source code file in both test files. 
> Seems to work without explicitly giving the source file name.
> 
> > > +if ![runto_main] then {
> > > +    perror "couldn't run to breakpoint"
> > > +    continue
> > > +}
> > 
> > For this block, let's follow what our testcase template
> > recommends:
> 
> Fixed.
> 
> 
> <snip>
> 
> > Here and below, can you make sure there is a space between
> > the "#" and the start of the text. Also, can you start them
> > with an upper-case letter in this case, and end the sentence
> > with a period? This is mandated by the GNU Coding Style.
> 
> Fixed.
> 
> > > +# Change execution direction to forward for next test
> > > +gdb_test "set exec-direction forward" "" "Start forward test2"
> > > +#gdb_test_no_output "set exec-direction forward"
> > 
> > Can you removed this commented-out line? I don't think we need
> > to keep it.
> 
> Removed in both files.
> 
> > > +gdb_test "record stop" ".*Process record is stopped.*" "Stopped
> > > recording"
> > > +set test_del_bkpts "delete breakpoints, answer prompt"
> > > +gdb_test_multiple "delete breakpoints" $test_del_bkpts {
> > > +    -re "Delete all breakpoints.*y or n.*$" {
> > > +	send_gdb "y\n"
> > > +    }
> > > +}
> > > +
> > > +gdb_test "record" "" "Start recording test2"
> > 
> > Is this part needed? There doesn't seem anything done after,
> > so I'm wondering what the purpose of this test is.
> 
> Not needed, didn't get cleaned up when I split the test into separate
> ISA 2.06 and an ISA 3.1 tests.
> > (note: if needed, we should use gdb_test_no_output instead)
> > 
> > > +if ![runto_main] then {
> > > +    perror "couldn't run to breakpoint"
> > > +    continue
> > > +}
> Fixed
> 
> > Same as above.
> > 
> > > +#check initial and new of r0 are different
> > 
> > Here and below, same as above.
> > > +# Change execution direction to forward for next test
> > > +gdb_test "set exec-direction forward" "" "Start forward test3"
> > > +#gdb_test_no_output "set exec-direction forward"
> 
> Fixed
> 
> > Same as above, can you remove this commented-out line, please?
> 
> Fixed
> 
> > > +gdb_test "record stop" ".*Process record is stopped.*" "Stopped
> > > recording 2"
> > > +set test_del_bkpts "delete breakpoints, answer prompt 2"
> > > +gdb_test_multiple "delete breakpoints" $test_del_bkpts {
> > > +    -re "Delete all breakpoints.*y or n.*$" {
> > > +	send_gdb "y\n"
> > > +    }
> > > +}
> > 
> > I think you can simplify the above using something like:
> > 
> >    with confirm off -- delete breakpoints
> 
> Above replaced with:
> 
> # Delete all breakpoints and catchpoints.
> delete_breakpoints
> 
> Patch retested on Power 10 with no regressions.
> 
> Please let me know if the patch looks ok now.



I'll maintain this would be cleaner to consolidate in a simple "V2:
updates per feedback".   :-)


> 
>                                    Carl Love
> --------------------------------------------------------------
> GDB Powerpc record test cases for ISA 2.06 and ISA 3.1
> 
> This patch adds Powerpc specific tests to verify recording of various
> instructions.  The first test case checks a couple of ISA 2.06 instructions.

The test uses two instructions, but per context looks like it only
intends to test the one ISA 2.06 instruction, with a load instruction
in place just for setup.

> The second test case tests several of the ISA 3.01 instructions.  Specifically,
> it checks the word and prefixed instructions and some of the Matrix
> Multiply Assist (MMA) instructions.
> 
> The patch has been run on both Power 10 and Power 9 to verify the ISA
> 2.06 test case runs on both platforms without errors.  The ISA 3.1 test
> runs without errors on Power 10 and is skipped as expected on Power 9.
> ---
>  .../gdb.reverse/ppc_record_test_isa_2_06.c    |  48 ++
>  .../gdb.reverse/ppc_record_test_isa_2_06.exp  | 123 +++++
>  .../gdb.reverse/ppc_record_test_isa_3_1.c     | 102 ++++
>  .../gdb.reverse/ppc_record_test_isa_3_1.exp   | 494 ++++++++++++++++++
>  4 files changed, 767 insertions(+)
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> 
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
> new file mode 100644
> index 00000000000..03ba90e2bff
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
> @@ -0,0 +1,48 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2012-2022 Free Software Foundation, Inc.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <ctype.h>     // isspace
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>    // getopt
> +#include <altivec.h>   // vector
> +
> +/* globals used for vector tests */
> +static vector unsigned long vec_xa, vec_xb, vec_xt;
> +static unsigned long ra, rb, rs;

vec_xa is unused below. 
It looks like vec_xt and ra are assigned but
not subsequently referenced.
Probably doesn't matter for a testcase, but
a properly paranoid compiler should complain.
> +
> +int main ()
> +{
> +  ra = 0xABCDEF012;
> +  rb = 0;
> +  rs = 0x012345678;
> +
> +  /* 9.0, 16.0, 25.0, 36.0 */
> +  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
> +
> +  vec_xt = (vector unsigned long){0xFF00FF00FF00FF00, 0xAA00AA00AA00AA00};
> +
> +  /* Test 1 ISA 2.06 instructions.  Load source into vs1, result of sqrt
> +     put into vs0.  */
> +  ra = (unsigned long) & vec_xb;        /* stop 1 */
> +  __asm__ __volatile__ ("lxvd2x 1, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("xvsqrtsp 0, 1");
> +  ra = 0;                               /* stop 2 */
> +}
> +
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
> new file mode 100644
> index 00000000000..b6522606262
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
> @@ -0,0 +1,123 @@
> +# Copyright 2008-2022 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +# This file is part of the GDB testsuite.  It tests reverse stepping.
> +# Lots of code borrowed from "step-reverse.exp".
> +#
> +# Test instruction record for Powerpc, ISA 2.06.
> +#
> +
> +# The basic flow of the record tests are:
> +#    1) Stop before executing the instructions of interest. Record
> +#       the initial value of the registers that the instruction will
> +#       change, i.e. the destination register.
> +#    2) Execute the instructions.  Record the new value of the
> +#       registers that changed.
> +#    3) Reverse the direction of the execution and execute back to
> +#       just before the instructions of interest.  Record the final
> +#       value of the registers of interest.
> +#    4) Check that the initial and new values of the registers are
> +#       different, i.e. the instruction changed the registers as expected.
> +#    5) Check that the initial and final values of the registers are
> +#       the same, i.e. gdb record restored the registers to their
> +#       original values.
> +
> +standard_testfile
> +
> +set gen_src record_test_isa_2_06.c
> +set executable record_test_isa_2_06
> +set options [list debug]
> +
> +if {![istarget "powerpc*"]} then  {
> +    verbose "Skipping Powerpc ISA 2.06 instruction record_test_2_06."
> +    return


> +}
> +
> +if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
> +    return -1
> +}
> +
> +clean_restart $executable
> +
> +if ![runto_main] then {
> +    untested "could not run to main"
> +    continue
> +}
> +
> +gdb_test_no_output "record"
> +T
> +###### Test 1:  Test an ISA 2.06 load (lxvd2x) and square root instruction
> +###### (xvsqrtsp).  The load instruction will load vs1.  The sqrt instruction
> +###### will put its result into vs0.
> +
> +set stop1  [gdb_get_line_number "stop 1"]
> +set stop2  [gdb_get_line_number "stop 2"]
> +
> +gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test 1"
> +gdb_test "continue"  ".*Breakpoint .*" "At stop 1"
> +
> +# Record the initial values in vs0, vs1.
> +# Load the argument into vs1, result of sqrt is put into vs0.

Appears to be a duplicated comment.

> +set vs0_initial [capture_command_output "info register vs0" ""]
> +set vs1_initial [capture_command_output "info register vs1" ""]
> +
> +gdb_test "break $stop2" ".*Breakpoint .*" "executed lxvd2x, xvsqrtsp"
> +gdb_test "continue"  ".*Breakpoint .*" "At stop 2"
> +
> +# The lxvd2x, xvsqrtsp and has been executed loading the argument into vs1
> +# Record the new values of vs0 and vs1.

"and has" ?

> +set vs0_new [capture_command_output "info register vs0" ""]
> +set vs1_new [capture_command_output "info register vs1" ""]
> +
> +# Execute in reverse to before the lxvd2x instruction.
> +gdb_test_no_output "set exec-direction reverse"

This actually just sets the direction.  The lxvd2x instruction
reference belongs after the test.


> +
> +gdb_test "break $stop1" ".*Breakpoint .*" "un executed lxvd2x, xvsqrtsp"
> +gdb_test "continue"  ".*Breakpoint.*" "At stop 1 in reverse"
> +
> +# Record the final values of vs0, vs1.
> +set vs0_final [capture_command_output "info register vs0" ""]
> +set vs1_final [capture_command_output "info register vs1" ""]
> +
> +# Check initial and new of vs0 are different.
> +set test_vs0_init_new "check vs0 initial versus vs0 new"
> +if {[string compare $vs0_initial  $vs0_new ] == 0} {
> +    fail $test_vs0_init_new
> +} else {
> +    pass $test_vs0_init_new
> +}
> +
> +# Check initial and new of vs1 are different.
> +set test_vs1_init_new "check vs0 initial versus vs1 new"
> +if {[string compare $vs1_initial  $vs1_new ] == 0} {
> +    fail $test_vs1_init_new
> +} else {
> +    pass $test_vs1_init_new
> +}
> +
> +# Check initial and final are the same.
> +set test_vs0_init_final "check vs0 initial versus vs0 final"
> +if {[string compare $vs0_initial  $vs0_final ] == 0} {
> +    pass $test_vs0_init_final
> +} else {
> +    fail $test_vs0_init_final
> +}
> +
> +# Check initial and final are the same.
> +set test_vs1_init_final "check vs1 initial versus vs1 final"
> +if {[string compare $vs1_initial  $vs1_final ] == 0} {
> +    pass $test_vs1_init_final
> +} else {
> +    fail $test_vs1_init_final
> +}
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
> new file mode 100644
> index 00000000000..e02c3daaed3
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
> @@ -0,0 +1,102 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2012-2022 Free Software Foundation, Inc.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <ctype.h>     // isspace
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>    // getopt
> +#include <altivec.h>   // vector
> +
> +/* globals used for vector tests */
> +static vector unsigned long vec_xa, vec_xb, vec_xt;
> +static unsigned long ra, rb, rs;
> +
> +int main ()
> +{
> +  ra = 0xABCDEF012;
> +  rb = 0;
> +  rs = 0x012345678;
> +
> +  /* 9.0, 16.0, 25.0, 36.0 */
> +  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
> +
> +  vec_xt = (vector unsigned long){0xFF00FF00FF00FF00, 0xAA00AA00AA00AA00};
> +
> +  /* Test 1, ISA 3.1 word instructions. Load source into r1, result of brh
> +     put in r0.  */
> +  ra = 0xABCDEF012;                     /* stop 1 */
> +  __asm__ __volatile__ ("pld 1, %0" :: "r" (ra ));
> +  __asm__ __volatile__ ("brh 0, 1" );
> +  ra = 0;                               /* stop 2 */
> +
> +  /* Test 2, ISA 3.1 MMA instructions with results in various ACC entries
> +     xxsetaccz    - ACC[3]
> +     xvi4ger8     - ACC[4]
> +     xvf16ger2pn  - ACC[5]
> +     pmxvi8ger4   - ACC[6]
> +     pmxvf32gerpp - ACC[7] and fpscr */
> +  /* Need to initialize the vs registers to a non zero value.  */
> +  ra = (unsigned long) & vec_xb;
> +  __asm__ __volatile__ ("lxvd2x 12, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 13, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 14, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 15, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xa = (vector unsigned long){0x333134343987601, 0x9994bbbc9983307};
> +  vec_xb = (vector unsigned long){0x411234041898760, 0x41c833042103400};
> +  __asm__ __volatile__ ("lxvd2x 16, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x123456789987650, 0x235676546989807};
> +  __asm__ __volatile__ ("lxvd2x 17, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x878363439823470, 0x413434c99839870};
> +  __asm__ __volatile__ ("lxvd2x 18, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x043765434398760, 0x419876555558850};
> +  __asm__ __volatile__ ("lxvd2x 19, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x33313434398760, 0x9994bbbc99899330};
> +  __asm__ __volatile__ ("lxvd2x 20, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 21, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 22, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 23, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 24, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 25, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 26, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 27, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xa = (vector unsigned long){0x33313434398760, 0x9994bbbc998330};
> +  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
> +  __asm__ __volatile__ ("lxvd2x 28, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x4567000046800000, 0x4458000048700000};
> +  __asm__ __volatile__ ("lxvd2x 29, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x41dd000041e00000, 0x41c8000046544400};
> +  __asm__ __volatile__ ("lxvd2x 30, %0, %1" :: "r" (ra ), "r" (rb));
> +
> +  /* SNAN */
> +  vec_xb = (vector unsigned long){0x7F8F00007F8F0000, 0x7F8F00007F8F0000};
> +
> +  __asm__ __volatile__ ("lxvd2x 31, %0, %1" :: "r" (ra ), "r" (rb));
> +
> +  ra = 0xAB;                            /* stop 3 */
> +  __asm__ __volatile__ ("xxsetaccz 3");
> +  __asm__ __volatile__ ("xvi4ger8 4, %x0, %x1" :: "wa" (vec_xa), \
> +			"wa" (vec_xb) );
> +  __asm__ __volatile__ ("xvf16ger2pn 5, %x0, %x1" :: "wa" (vec_xa),\
> +			"wa" (vec_xb) );
> +  __asm__ __volatile__ ("pmxvi8ger4spp  6, %x0, %x1, 11, 13, 5"
> +                                :: "wa" (vec_xa), "wa" (vec_xb) );
> +  __asm__ __volatile__ ("pmxvf32gerpp  7, %x0, %x1, 11, 13"
> +                                :: "wa" (vec_xa), "wa" (vec_xb) );
> +  ra = 0;                               /* stop 4 */
> +}
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> new file mode 100644
> index 00000000000..f0340db92f0
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> @@ -0,0 +1,494 @@
> +# Copyright 2008-2022 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +# This file is part of the GDB testsuite.  It tests reverse stepping.
> +# Lots of code borrowed from "step-reverse.exp".
> +#
> +# Test instruction record for Powerpc, ISA 3.1.
> +#
> +
> +# The basic flow of the record tests are:
> +#    1) Stop before executing the instructions of interest.  Record
> +#       the initial value of the registers that the instruction will
> +#       change, i.e. the destination register.
> +#    2) Execute the instructions.  Record the new value of the
> +#       registers that changed.
> +#    3) Reverse the direction of the execution and execute back to
> +#       just before the instructions of interest.  Record the final
> +#       value of the registers of interest.
> +#    4) Check that the initial and new values of the registers are
> +#       different, i.e. the instruction changed the registers as expected.
> +#    5) Check that the initial and final values of the registers are
> +#       the same, i.e. gdb record restored the registers to their
> +#       original values.
> +
> +
> +standard_testfile
> +
> +set gen_src record_test_isa_3_1.c
> +set executable record_test_isa_3_1
> +
> +if {![istarget "powerpc*"] || [skip_power_isa_3_1_tests] } then  {
> +    verbose "Skipping Powerpc ISA 3.1 instruction record_test."
> +    return
> +}
> +
> +set options [list additional_flags=-mcpu=power10  debug]
> +if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
> +    return -1
> +}
> +
> +clean_restart $executable
> +
> +if ![runto_main] then {
> +    untested "could not run to main"
> +    continue
> +}
> +
> +gdb_test_no_output "record"
> +
> +######  Test 1:  Test an ISA 3.1 byte reverse word instruction (brd) and a
> +######   prefixed load double (pld) instruction.
> +set stop1  [gdb_get_line_number "stop 1"]
> +set stop2  [gdb_get_line_number "stop 2"]
> +
> +gdb_test "break $stop1" ".*Breakpoint .*" "about to execute Test 1"
> +gdb_test "continue"  ".*Breakpoint .*" "At stop 1"
> +
> +# Record the initial values in r0, r1
> +# Load the argument into r1, result of byte reverse is put into r0.
> +set r0_initial [capture_command_output "info register r0" ""]
> +set r1_initial [capture_command_output "info register r1" ""]
> +
> +gdb_test "break $stop2" ".*Breakpoint .*" "executed test 1"

inconsistent (case) reference to "test 1" versus "Test 1".  Here and
later.   No additional/different comments below.

<snip>

Thanks
-Will



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/2  Version 3] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-12 21:50       ` will schmidt
@ 2022-04-13 17:26         ` Carl Love
  2022-04-17 16:23           ` Joel Brobecker
  0 siblings, 1 reply; 25+ messages in thread
From: Carl Love @ 2022-04-13 17:26 UTC (permalink / raw)
  To: will schmidt, Joel Brobecker, gdb-patches
  Cc: Ulrich Weigand, Tulio Magno, Rogerio Alves, cel

Joel, Will, GDB maintainers:

Version 2 fixed the various code formatting and typos that Joel pointed
out.

Version 3 fixed the various typos 

I have retested the two test cases again on Power 10 to ensure I didn't
break anything.

Please let me know if you see any additional things that need fixing in
this patch.

Note, the testcase in PATCH 2/2 version 2 were not changed.

                      Carl Love
------------------------------------------------------------------
Add recording support for the ISA 3.1 Powerpc instructions.

This patch adds support for the Powerpc ISA 3.1 instructions to the Powerpc
gdb instruction recording routines.  Case statement entries are added to a
number of the existing routines for recording the 32-bit word instructions.
A few new functions were added to handle the new word instructions.  The 64-bit
prefix instructions are all handled by a set of new routines.  The function
ppc_process_prefix_instruction() is the primary function to handle the
prefixed instructions. It calls additional functions to handle specific
sets of prefixed instructions.  These new functions are:
  ppc_process_record_prefix_vsx_d_form(),
  ppc_process_record_prefix_store_vsx_ds_form(),
  ppc_process_record_prefix_op34(),
  ppc_process_record_prefix_op33(),
  ppc_process_record_prefix_op32(),
  ppc_process_record_prefix_store(),
  ppc_process_record_prefix_op59_XX3(),
  ppc_process_record_prefix_op42().
---
 gdb/rs6000-tdep.c | 1199 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 1173 insertions(+), 26 deletions(-)

diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 44828bcff6d..31a86b902c7 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -4123,8 +4123,25 @@ bfd_uses_spe_extensions (bfd *abfd)
 #define PPC_LEV(insn)	PPC_FIELD (insn, 20, 7)
 
 #define PPC_XT(insn)	((PPC_TX (insn) << 5) | PPC_T (insn))
+#define PPC_XTp(insn)	((PPC_BIT (insn, 10) << 5)	\
+			 | PPC_FIELD (insn, 6, 4) << 1)
+#define PPC_XSp(insn)	((PPC_BIT (insn, 10) << 5)	\
+			 | PPC_FIELD (insn, 6, 4) << 1)
 #define PPC_XER_NB(xer)	(xer & 0x7f)
 
+/* The following macros are for the prefixed instructions.  */
+#define P_PPC_D(insn_prefix, insn_suffix) \
+  PPC_SEXT (PPC_FIELD (insn_prefix, 14, 18) << 16 \
+	    | PPC_FIELD (insn_suffix, 16, 16), 34)
+#define P_PPC_TX5(insn_sufix)	PPC_BIT (insn_suffix, 5)
+#define P_PPC_TX15(insn_suffix) PPC_BIT (insn_suffix, 15)
+#define P_PPC_XT(insn_suffix)	((PPC_TX (insn_suffix) << 5) \
+				 | PPC_T (insn_suffix))
+#define P_PPC_XT5(insn_suffix) ((P_PPC_TX5 (insn_suffix) << 5) \
+				| PPC_T (insn_suffix))
+#define P_PPC_XT15(insn_suffix) \
+  ((P_PPC_TX15 (insn_suffix) << 5) | PPC_T (insn_suffix))
+
 /* Record Vector-Scalar Registers.
    For VSR less than 32, it's represented by an FPR and an VSR-upper register.
    Otherwise, it's just a VR register.  Record them accordingly.  */
@@ -4152,6 +4169,63 @@ ppc_record_vsr (struct regcache *regcache, ppc_gdbarch_tdep *tdep, int vsr)
   return 0;
 }
 
+/* The ppc_record_ACC_fpscr() records te changes to the floating point
+   registers modified by a floating point instruction.  Some of the
+   instructions also update one of the condition code fields in the
+   "Floating-Point Status and Control Register" (FPSCR).   The RECORD_FPSCR
+   or DO_NOT_RECORD_FPSCR arguments to the function specifies if the
+   instruction modifies the FPSCR or not and thus it also needs to be recorded.
+   Return 0 on success.  */
+
+#define RECORD_FPSCR 1
+#define DO_NOT_RECORD_FPSCR 0
+
+static int
+ppc_record_ACC_fpscr (struct regcache *regcache, ppc_gdbarch_tdep *tdep,
+		      int at, int save_fpscr)
+{
+  int i;
+  if (at < 0 || at >= 8)
+    return -1;
+
+  /* The ACC register file consists of 8 register entries, each register
+     entry consist of four 128-bit rows.
+
+     The ACC rows map to specific VSR registers.
+         ACC[0][0] -> VSR[0]
+         ACC[0][1] -> VSR[1]
+         ACC[0][2] -> VSR[2]
+         ACC[0][3] -> VSR[3]
+              ...
+         ACC[7][0] -> VSR[28]
+         ACC[7][1] -> VSR[29]
+         ACC[7][2] -> VSR[30]
+         ACC[7][3] -> VSR[31]
+
+     NOTE:
+     In ISA 3.1 the ACC is mapped on top of VSR[0] thru VSR[31].
+
+     In the future, the ACC may be implemented as an independent register file
+     rather than mapping on top of the VSRs.  This will then require the ACC to
+     be assigned its own register number and the ptrace interface to be able
+     access the ACC.  Note the ptrace interface for the ACC will also need to
+     be implemented.  */
+
+  /* ACC maps over the same VSR space as the fp registers.  */
+  for (i = 0; i<4; i++)
+    {
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fp0_regnum
+				     + at*4 + i);
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_vsr0_upper_regnum + at*4 + i);
+    }
+
+  if (save_fpscr)
+    record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+
+  return 0;
+}
+
 /* Parse and record instructions primary opcode-4 at ADDR.
    Return 0 if successful.  */
 
@@ -4171,9 +4245,34 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 41:		/* Vector Multiply-Sum Signed Halfword Saturate */
       record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
       /* FALL-THROUGH */
+    case 20:		/* Move To VSR Byte Mask Immediate opcode, b2 = 0,
+			   ignore bit 31 */
+    case 21:		/* Move To VSR Byte Mask Immediate opcode, b2 = 1,
+			   ignore bit 31 */
+    case 23:		/* Vector Multiply-Sum & write Carry-out Unsigned
+			   Doubleword */
+    case 24:		/* Vector Extract Double Unsigned Byte to VSR
+			   using GPR-specified Left-Index */
+    case 25:		/* Vector Extract Double Unsigned Byte to VSR
+			   using GPR-specified Right-Index */
+    case 26:		/* Vector Extract Double Unsigned Halfword to VSR
+			   using GPR-specified Left-Index */
+    case 27:		/* Vector Extract Double Unsigned Halfword to VSR
+			   using GPR-specified Right-Index */
+    case 28:		/* Vector Extract Double Unsigned Word to VSR
+			   using GPR-specified Left-Index */
+    case 29:		/* Vector Extract Double Unsigned Word to VSR
+			   using GPR-specified Right-Index */
+    case 30:		/* Vector Extract Double Unsigned Doubleword to VSR
+			   using GPR-specified Left-Index */
+    case 31:		/* Vector Extract Double Unsigned Doubleword to VSR
+			   using GPR-specified Right-Index */
     case 42:		/* Vector Select */
     case 43:		/* Vector Permute */
     case 59:		/* Vector Permute Right-indexed */
+    case 22: 		/* Vector Shift
+			      Left  Double by Bit Immediate if insn[21] = 0
+			      Right Double by Bit Immediate if insn[21] = 1 */
     case 44:		/* Vector Shift Left Double by Octet Immediate */
     case 45:		/* Vector Permute and Exclusive-OR */
     case 60:		/* Vector Add Extended Unsigned Quadword Modulo */
@@ -4236,6 +4335,9 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
   /* Bit-21 is used for RC */
   switch (ext & 0x3ff)
     {
+    case 5:		/* Vector Rotate Left Quadword */
+    case 69:		/* Vector Rotate Left Quadword then Mask Insert */
+    case 325:		/* Vector Rotate Left Quadword then AND with Mask */
     case 6:		/* Vector Compare Equal To Unsigned Byte */
     case 70:		/* Vector Compare Equal To Unsigned Halfword */
     case 134:		/* Vector Compare Equal To Unsigned Word */
@@ -4244,13 +4346,16 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     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 903:		/* Vector Compare Greater Than Signed Quadword */
     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 647:		/* Vector Compare Greater Than Unsigned Quadword */
     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 455:		/* Vector Compare Equal Quadword */
     case 710:		/* Vector Compare Greater Than Single-Precision */
     case 7:		/* Vector Compare Not Equal Byte */
     case 71:		/* Vector Compare Not Equal Halfword */
@@ -4263,6 +4368,21 @@ 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 13:
+      switch (vra)    /* Bit-21 is used for RC */
+	{
+	case 0:       /* Vector String Isolate Byte Left-justified */
+	case 1:       /* Vector String Isolate Byte Right-justified */
+	case 2:       /* Vector String Isolate Halfword Left-justified */
+	case 3:       /* Vector String Isolate Halfword Right-justified */
+	  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;
+	}
     }
 
   if (ext  == 1538)
@@ -4287,6 +4407,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
 	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 27:	/* Vector Extend Sign Doubleword To Quadword */
 	case 28:	/* Vector Count Trailing Zeros Byte */
 	case 29:	/* Vector Count Trailing Zeros Halfword */
 	case 30:	/* Vector Count Trailing Zeros Word */
@@ -4297,8 +4418,57 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
 	}
     }
 
+  if (ext == 1602)
+    {
+      switch (vra)
+	{
+	case 0: 	/* Vector Expand Byte Mask */
+	case 1: 	/* Vector Expand Halfword Mask */
+	case 2: 	/* Vector Expand Word Mask */
+	case 3: 	/* Vector Expand Doubleword Mask */
+	case 4: 	/* Vector Expand Quadword Mask */
+	case 16:	/* Move to VSR Byte Mask */
+	case 17:	/* Move to VSR Halfword Mask */
+	case 18:	/* Move to VSR Word Mask */
+	case 19:	/* Move to VSR Doubleword Mask */
+	case 20:	/* Move to VSR Quadword Mask */
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+	  return 0;
+
+	case 8: 	/* Vector Extract Byte Mask */
+	case 9: 	/* Vector Extract Halfword Mask */
+	case 10: 	/* Vector Extract Word Mask */
+	case 11: 	/* Vector Extract Doubleword Mask */
+	case 12: 	/* Vector Extract Quadword Mask */
+
+	/* Ignore the MP bit in the LSB position of the vra value. */
+	case 24:	/* Vector Count Mask Bits Byte, MP = 0 */
+	case 25:	/* Vector Count Mask Bits Byte, MP = 1 */
+	case 26:	/* Vector Count Mask Bits Halfword, MP = 0 */
+	case 27:	/* Vector Count Mask Bits Halfword, MP = 1 */
+	case 28:	/* Vector Count Mask Bits Word, MP = 0 */
+	case 29:	/* Vector Count Mask Bits Word, MP = 1 */
+	case 30:	/* Vector Count Mask Bits Doubleword, MP = 0 */
+	case 31:	/* Vector Count Mask Bits Doubleword, MP = 1 */
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_gp0_regnum + PPC_RT (insn));
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_gp0_regnum + PPC_RT (insn));
+	  return 0;
+	}
+    }
+
   switch (ext)
     {
+
+    case 257:		/* Vector Compare Unsigned Quadword */
+    case 321:		/* Vector Compare Signed Quadword */
+      /* Comparison tests that always set CR field BF */
+      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;
+
     case 142:		/* Vector Pack Unsigned Halfword Unsigned Saturate */
     case 206:		/* Vector Pack Unsigned Word Unsigned Saturate */
     case 270:		/* Vector Pack Signed Halfword Unsigned Saturate */
@@ -4338,6 +4508,8 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 268:		/* Vector Merge Low Byte */
     case 332:		/* Vector Merge Low Halfword */
     case 396:		/* Vector Merge Low Word */
+    case 397:		/* Vector Clear Leftmost Bytes */
+    case 461:		/* Vector Clear Rightmost Bytes */
     case 526:		/* Vector Unpack High Signed Byte */
     case 590:		/* Vector Unpack High Signed Halfword */
     case 654:		/* Vector Unpack Low Signed Byte */
@@ -4356,8 +4528,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 780:		/* Vector Splat Immediate Signed Byte */
     case 844:		/* Vector Splat Immediate Signed Halfword */
     case 908:		/* Vector Splat Immediate Signed Word */
+    case 261:		/* Vector Shift Left Quadword */
     case 452:		/* Vector Shift Left */
+    case 517:		/* Vector Shift Right Quadword */
     case 708:		/* Vector Shift Right */
+    case 773:		/* Vector Shift Right Algebraic Quadword */
     case 1036:		/* Vector Shift Left by Octet */
     case 1100:		/* Vector Shift Right by Octet */
     case 0:		/* Vector Add Unsigned Byte Modulo */
@@ -4370,15 +4545,43 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 8:		/* Vector Multiply Odd Unsigned Byte */
     case 72:		/* Vector Multiply Odd Unsigned Halfword */
     case 136:		/* Vector Multiply Odd Unsigned Word */
+    case 200:		/* Vector Multiply Odd Unsigned Doubleword */
     case 264:		/* Vector Multiply Odd Signed Byte */
     case 328:		/* Vector Multiply Odd Signed Halfword */
     case 392:		/* Vector Multiply Odd Signed Word */
+    case 456:		/* Vector Multiply Odd Signed Doubleword */
     case 520:		/* Vector Multiply Even Unsigned Byte */
     case 584:		/* Vector Multiply Even Unsigned Halfword */
     case 648:		/* Vector Multiply Even Unsigned Word */
+    case 712:		/* Vector Multiply Even Unsigned Doubleword */
     case 776:		/* Vector Multiply Even Signed Byte */
     case 840:		/* Vector Multiply Even Signed Halfword */
     case 904:		/* Vector Multiply Even Signed Word */
+    case 968:		/* Vector Multiply Even Signed Doubleword */
+    case 457:		/* Vector Multiply Low Doubleword */
+    case 649:		/* Vector Multiply High Unsigned Word */
+    case 713:		/* Vector Multiply High Unsigned Doubleword */
+    case 905:		/* Vector Multiply High Signed Word */
+    case 969:		/* Vector Multiply High Signed Doubleword */
+    case 11:		/* Vector Divide Unsigned Quadword */
+    case 203:		/* Vector Divide Unsigned Doubleword */
+    case 139:		/* Vector Divide Unsigned Word */
+    case 267:		/* Vector Divide Signed Quadword */
+    case 459:		/* Vector Divide Signed Doubleword */
+    case 395:		/* Vector Divide Signed Word */
+    case 523:		/* Vector Divide Extended Unsigned Quadword */
+    case 715:		/* Vector Divide Extended Unsigned Doubleword */
+    case 651:		/* Vector Divide Extended Unsigned Word */
+    case 779:		/* Vector Divide Extended Signed Quadword */
+    case 971:		/* Vector Divide Extended Signed Doubleword */
+    case 907:		/* Vector Divide Extended Unsigned Word */
+    case 1547:		/* Vector Modulo Unsigned Quadword */
+    case 1675:		/* Vector Modulo Unsigned Word */
+    case 1739:		/* Vector Modulo Unsigned Doubleword */
+    case 1803:		/* Vector Modulo Signed Quadword */
+    case 1931:		/* Vector Modulo Signed Word */
+    case 1995:		/* Vector Modulo Signed Doubleword */
+
     case 137:		/* Vector Multiply Unsigned Word Modulo */
     case 1024:		/* Vector Subtract Unsigned Byte Modulo */
     case 1088:		/* Vector Subtract Unsigned Halfword Modulo */
@@ -4462,7 +4665,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 1794:		/* Vector Count Leading Zeros Byte */
     case 1858:		/* Vector Count Leading Zeros Halfword */
     case 1922:		/* Vector Count Leading Zeros Word */
+    case 1924:		/* Vector Count Leading Zeros Doubleword under
+			   bit Mask*/
     case 1986:		/* Vector Count Leading Zeros Doubleword */
+    case 1988:		/* Vector Count Trailing Zeros Doubleword under bit
+			   Mask */
     case 1795:		/* Vector Population Count Byte */
     case 1859:		/* Vector Population Count Halfword */
     case 1923:		/* Vector Population Count Word */
@@ -4488,14 +4695,50 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 589:		/* Vector Extract Unsigned Halfword */
     case 653:		/* Vector Extract Unsigned Word */
     case 717:		/* Vector Extract Doubleword */
+    case 15:		/* Vector Insert Byte from VSR using GPR-specified
+			   Left-Index */
+    case 79:		/* Vector Insert Halfword from VSR using GPR-specified
+			   Left-Index */
+    case 143:		/* Vector Insert Word from VSR using GPR-specified
+			   Left-Index */
+    case 207:		/* Vector Insert Word from GPR using
+			   immediate-specified index */
+    case 463:		/* Vector Insert Doubleword from GPR using
+			   immediate-specified index */
+    case 271:		/* Vector Insert Byte from VSR using GPR-specified
+			   Right-Index */
+    case 335:		/* Vector Insert Halfword from VSR using GPR-specified
+			   Right-Index */
+    case 399:		/* Vector Insert Word from VSR using GPR-specified
+			   Right-Index */
+    case 527:		/* Vector Insert Byte from GPR using GPR-specified
+			   Left-Index */
+    case 591:		/* Vector Insert Halfword from GPR using GPR-specified
+			   Left-Index */
+    case 655:		/* Vector Insert Word from GPR using GPR-specified
+			   Left-Index */
+    case 719:		/* Vector Insert Doubleword from GPR using
+			    GPR-specified Left-Index */
+    case 783:		/* Vector Insert Byte from GPR using GPR-specified
+			   Right-Index */
+    case 847:		/* Vector Insert Halfword from GPR using GPR-specified
+			   Left-Index */
+    case 911:		/* Vector Insert Word from GPR using GPR-specified
+			   Left-Index */
+    case 975:		/* Vector Insert Doubleword from GPR using
+			    GPR-specified Right-Index */
     case 781:		/* Vector Insert Byte */
     case 845:		/* Vector Insert Halfword */
     case 909:		/* Vector Insert Word */
     case 973:		/* Vector Insert Doubleword */
+    case 1357:		/* Vector Centrifuge Doubleword */
+    case 1421:		/* Vector Parallel Bits Extract Doubleword */
+    case 1485:		/* Vector Parallel Bits Deposit Doubleword */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
       return 0;
 
+    case 1228:		/* Vector Gather every Nth Bit */
     case 1549:		/* Vector Extract Unsigned Byte Left-Indexed */
     case 1613:		/* Vector Extract Unsigned Halfword Left-Indexed */
     case 1677:		/* Vector Extract Unsigned Word Left-Indexed */
@@ -4525,6 +4768,34 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record instructions of primary opcode 6 at ADDR.
+   Return 0 if successful.  */
+
+static int
+ppc_process_record_op6 (struct gdbarch *gdbarch, struct regcache *regcache,
+			CORE_ADDR addr, uint32_t insn)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int subtype = PPC_FIELD (insn, 28, 4);
+  CORE_ADDR ea = 0;
+
+  switch (subtype)
+    {
+    case 0:    /* Load VSX Vector Paired */
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
+      return 0;
+    case 1:    /* Store VSX Vector Paired */
+      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, 32);
+      return 0;
+    }
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-19 at ADDR.
    Return 0 if successful.  */
 
@@ -4577,6 +4848,30 @@ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record instructions of primary opcode-31 with the extended opcode
+   177.  The argument is the word instruction (insn).  Return 0 if successful.
+*/
+
+static int
+ppc_process_record_op31_177 (struct gdbarch *gdbarch,
+			     struct regcache *regcache,
+			     uint32_t insn)
+{
+  int RA_opcode = PPC_RA(insn);
+  int as = PPC_FIELD (insn, 6, 3);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  switch (RA_opcode)
+    {
+    case 0: 		/* VSX Move From Accumulator, xxmfacc */
+    case 1: 		/* VSX Move To Accumulator, xxmtacc */
+    case 3: 		/* VSX Set Accumulator to Zero, xxsetaccz */
+      ppc_record_ACC_fpscr (regcache, tdep, as, DO_NOT_RECORD_FPSCR);
+      return 0;
+    }
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-31 at ADDR.
    Return 0 if successful.  */
 
@@ -4586,7 +4881,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
-  int tmp, nr, nb, i;
+  int tmp, nr, nb = 0, i;
   CORE_ADDR at_dcsz, ea = 0;
   ULONGEST rb, ra, xer;
   int size = 0;
@@ -4677,6 +4972,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 371:		/* Move From Time Base [Phased-Out]  */
     case 309:		/* Load Doubleword Monitored Indexed  */
     case 128:		/* Set Boolean */
+    case 384:		/* Set Boolean Condition */
+    case 416:		/* Set Boolean Condition Reverse */
+    case 448:		/* Set Negative Boolean Condition */
+    case 480:		/* Set Negative Boolean Condition Reverse */
     case 755:		/* Deliver A Random Number */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_gp0_regnum + PPC_RT (insn));
@@ -4684,8 +4983,15 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 
     /* These only write to RA.  */
     case 51:		/* Move From VSR Doubleword */
+    case 59:		/* Count Leading Zeros Doubleword under bit Mask */
     case 115:		/* Move From VSR Word and Zero */
     case 122:		/* Population count bytes */
+    case 155:		/* Byte-Reverse Word */
+    case 156:		/* Parallel Bits Deposit Doubleword */
+    case 187:		/* Byte-Reverse Doubleword */
+    case 188:		/* Parallel Bits Extract Doubleword */
+    case 219:		/* Byte-Reverse Halfword */
+    case 220:		/* Centrifuge Doubleword */
     case 378:		/* Population count words */
     case 506:		/* Population count doublewords */
     case 154:		/* Parity Word */
@@ -4695,6 +5001,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 314:		/* Convert Binary Coded Decimal To Declets */
     case 508:		/* Compare bytes */
     case 307:		/* Move From VSR Lower Doubleword */
+    case 571:		/* Count Trailing Zeros Doubleword under bit Mask */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_gp0_regnum + PPC_RA (insn));
       return 0;
@@ -4819,6 +5126,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache, tmp + 1);
       return 0;
 
+    /* These write to destination register PPC_XT. */
     case 179:		/* Move To VSR Doubleword */
     case 211:		/* Move To VSR Word Algebraic */
     case 243:		/* Move To VSR Word and Zero */
@@ -4826,6 +5134,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     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 13:		/* Load VSX Vector Rightmost Byte Indexed */
+    case 45:		/* Load VSX Vector Rightmost Halfword Indexed */
+    case 77:		/* Load VSX Vector Rightmost Word Indexed */
+    case 109:		/* Load VSX Vector Rightmost Doubleword 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 */
@@ -4842,6 +5154,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
 
+    case 333:		/* Load VSX Vector Paired Indexed */
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
+      return 0;
+
     /* These write RA.  Update CR if RC is set.  */
     case 24:		/* Shift Left Word */
     case 26:		/* Count Leading Zeros Word */
@@ -5006,6 +5323,31 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_mem (ea, size);
       return 0;
 
+    case 141:		/* Store VSX Vector Rightmost Byte Indexed */
+    case 173:		/* Store VSX Vector Rightmost Halfword Indexed */
+    case 205:		/* Store VSX Vector Rightmost Word Indexed */
+    case 237:		/* Store VSX Vector Rightmost Doubleword Indexed */
+      switch(ext)
+	{
+	  case 141: nb = 1;
+	  break;
+	  case 173: nb = 2;
+	  break;
+	  case 205: nb = 4;
+	  break;
+	  case 237: nb = 8;
+	  break;
+	}
+      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;
+      record_full_arch_list_add_mem (ea, nb);
+      return 0;
+
     case 397:		/* Store VSX Vector with Length */
     case 429:		/* Store VSX Vector Left-justified with Length */
       ra = 0;
@@ -5021,6 +5363,19 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 	record_full_arch_list_add_mem (ea, nb);
       return 0;
 
+    case 461:		/* Store VSX Vector Paired Indexed */
+      {
+	if (PPC_RA (insn) != 0)
+	  regcache_raw_read_unsigned (regcache,
+				      tdep->ppc_gp0_regnum
+				      + PPC_RA (insn), &ea);
+	regcache_raw_read_unsigned (regcache,
+				    tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
+	ea += rb;
+	record_full_arch_list_add_mem (ea, 32);
+	return 0;
+      }
+
     case 710:		/* Store Word Atomic */
     case 742:		/* Store Doubleword Atomic */
       ra = 0;
@@ -5166,6 +5521,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       ea = (ra + rb) & ~((ULONGEST) (at_dcsz - 1));
       record_full_arch_list_add_mem (ea, at_dcsz);
       return 0;
+
+    case 177:
+      if (ppc_process_record_op31_177 (gdbarch, regcache, insn) == 0)
+	return 0;
     }
 
 UNKNOWN_OP:
@@ -5179,10 +5538,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 
 static int
 ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
-			   CORE_ADDR addr, uint32_t insn)
+			 CORE_ADDR addr, uint32_t insn)
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
+  int at = PPC_FIELD (insn, 6, 3);
 
   switch (ext & 0x1f)
     {
@@ -5206,6 +5566,75 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
+  /* MMA instructions, keep looking.  */
+  switch (ext >> 2)    /* Additional opcode field is upper 8-bits of ext */
+    {
+    case 3:	/* VSX Vector 8-bit Signed/Unsigned Integer GER, xvi8ger4 */
+    case 2:	/* VSX Vector 8-bit Signed/Unsigned Integer GER Positive
+		   multiply, Positive accumulate, xvi8ger4pp */
+
+    case 99:	/* VSX Vector 8-bit Signed/Unsigned Integer GER with
+		   Saturate Positive multiply, Positive accumulate,
+		   xvi8ger4spp */
+
+    case 35:	/* VSX Vector 4-bit Signed Integer GER, xvi4ger8 */
+    case 34:	/* VSX Vector 4-bit Signed Integer GER Positive multiply,
+		   Positive accumulate, xvi4ger8pp */
+
+    case 75:	/* VSX Vector 16-bit Signed Integer GER, xvi16ger2 */
+    case 107:	/* VSX Vector 16-bit Signed Integer GER  Positive multiply,
+		   Positive accumulate, xvi16ger2pp */
+
+    case 43:	/* VSX Vector 16-bit Signed Integer GER with Saturation,
+		   xvi16ger2s */
+    case 42:	/* VSX Vector 16-bit Signed Integer GER with Saturation
+		   Positive multiply, Positive accumulate, xvi16ger2spp */
+      ppc_record_ACC_fpscr (regcache, tdep, at, DO_NOT_RECORD_FPSCR);
+      return 0;
+
+    case 19:	/* VSX Vector 16-bit Floating-Point GER, xvf16ger2 */
+    case 18:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf16ger2pp */
+    case 146:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf16ger2pn */
+    case 82:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf16ger2np */
+    case 210:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
+		   Negative accumulate, xvf16ger2nn */
+
+    case 27:	/* VSX Vector 32-bit Floating-Point GER, xvf32ger */
+    case 26:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf32gerpp */
+    case 154:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf32gerpn */
+    case 90:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf32gernp */
+    case 218:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
+		   Negative accumulate, xvf32gernn */
+
+    case 59:	/* VSX Vector 64-bit Floating-Point GER, pmxvf64ger */
+    case 58:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf64gerpp */
+    case 186:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf64gerpn */
+    case 122:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf64gernp */
+    case 250:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
+		   Negative accumulate, pmxvf64gernn */
+
+    case 51:	/* VSX Vector bfloat16 GER, xvbf16ger2 */
+    case 50:	/* VSX Vector bfloat16 GER Positive multiply,
+		   Positive accumulate, xvbf16ger2pp */
+    case 178:	/* VSX Vector bfloat16 GER Positive multiply,
+		   Negative accumulate, xvbf16ger2pn */
+    case 114:	/* VSX Vector bfloat16 GER Negative multiply,
+		   Positive accumulate, xvbf16ger2np */
+    case 242:	/* VSX Vector bfloat16 GER Negative multiply,
+		   Negative accumulate, xvbf16ger2nn */
+      ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
+      return 0;
+    }
+
   switch (ext)
     {
     case 2:		/* DFP Add */
@@ -5268,6 +5697,48 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record an XX2-Form instruction with opcode 60 at ADDR.  The
+   word instruction is an argument insn.  Return 0 if successful.  */
+
+static int
+ppc_process_record_op60_XX2 (struct gdbarch *gdbarch,
+			     struct regcache *regcache,
+			     CORE_ADDR addr, uint32_t insn)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int RA_opcode = PPC_RA(insn);
+
+  switch (RA_opcode)
+    {
+    case 2:	/* VSX Vector Test Least-Significant Bit by Byte */
+    case 25:	/* VSX Vector round and Convert Single-Precision format
+		   to Half-Precision format.  Only changes the CR
+		   field.  */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+    case 17:	/* VSX Vector Convert with round Single-Precision
+		   to bfloat16 format */
+    case 24:	/* VSX Vector Convert Half-Precision format to
+		   Single-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 16:	/* VSX Vector Convert bfloat16 to Single-Precision
+		   format Non-signaling */
+    case 23:	/* VSX Vector Byte-Reverse Doubleword */
+    case 31:	/* VSX Vector Byte-Reverse Quadword */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
+    }
+
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-60 at ADDR.
    Return 0 if successful.  */
 
@@ -5583,37 +6054,30 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
       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;
+      if (ppc_process_record_op60_XX2 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      return 0;
     }
 
   switch (ext)
     {
-    case 360:		/* VSX Vector Splat Immediate Byte */
-      if (PPC_FIELD (insn, 11, 2) == 0)
+    case 360:
+      if (PPC_FIELD (insn, 11, 2) == 0)  /* VSX Vector Splat Immediate Byte */
+	{
+	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+	  return 0;
+	}
+      if (PPC_FIELD (insn, 11, 5) == 31)  /* Load VSX Vector Special Value
+					     Quadword */
 	{
 	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
 	  return 0;
 	}
       break;
+    case 916:		/* VSX Vector Generate PCV from Byte Mask */
+    case 917:		/* VSX Vector Generate PCV from Halfword Mask */
+    case 948:		/* VSX Vector Generate PCV from Word Mask */
+    case 949:		/* VSX Vector Generate PCV from Doubleword Mask */
     case 918:		/* VSX Scalar Insert Exponent Double-Precision */
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
@@ -5894,6 +6358,35 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
 			   Quad-Precision */
     case 516:		/* VSX Scalar Subtract Quad-Precision */
     case 548:		/* VSX Scalar Divide Quad-Precision */
+    case 994:
+      {
+      switch (PPC_FIELD (insn, 11, 5))
+	{
+	case 0:	/* DFP Convert From Fixed Quadword Quad */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_fp0_regnum
+					 + PPC_FRT (insn));
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_fp0_regnum
+					 + PPC_FRT (insn) + 1);
+	  return 0;
+	case 1:	/* DFP Convert To Fixed Quadword Quad */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+	  return 0;
+	}
+      }
+
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
+    case 68:		/* VSX Scalar Compare Equal Quad-Precision */
+    case 196:		/* VSX Scalar Compare Greater Than or Equal
+			   Quad-Precision */
+    case 228:		/* VSX Scalar Compare Greater Than Quad-Precision */
+    case 676:		/* VSX Scalar Maximum Type-C Quad-Precision */
+    case 740:		/* VSX Scalar Minimum Type-C Quad-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       /* FALL-THROUGH */
     case 100:		/* VSX Scalar Copy Sign Quad-Precision */
@@ -5920,14 +6413,22 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 836:
       switch (PPC_FIELD (insn, 11, 5))
 	{
+	case 0:		/* VSX Scalar Convert with round to zero
+			   Quad-Precision to Unsigned Quadword  */
 	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 3:		/* VSX Scalar Convert with round
+			   Unsigned Quadword to Quad-Precision  */
+	case 8:		/* VSX Scalar Convert with round to zero
+			   Quad-Precision to Signed Quadword  */
 	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 11:	/* VSX Scalar Convert with round
+			   Signed Quadword to Quad-Precision */
 	case 17:	/* VSX Scalar truncate & Convert Quad-Precision format
 			   to Unsigned Doubleword format */
 	case 20:	/* VSX Scalar round & Convert Quad-Precision format to
@@ -5947,17 +6448,651 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Record the prefixed instructions with primary opcode 32.  The arguments are
+   the first 32-bits of the instruction (insn_prefix), and the second 32-bits
+   of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op42 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if (ST1 != 0)
+    return -1;
+
+  switch (type)
+    {
+    case 0:  /* Prefixed Load VSX Scalar Doubleword, plxsd */
+      ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
+      break;
+    case 2:  /* Prefixed Load Halfword Algebraic, plha */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum
+				     + PPC_RT (insn_suffix));
+      break;
+    default:
+      return -1;
+    }
+  return 0;
+}
+
+/* Record the prefixed XX3-Form instructions with primary opcode 59.  The
+   arguments are the first 32-bits of the instruction (insn_prefix), and the
+   second 32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op59_XX3 (struct gdbarch *gdbarch,
+				    struct regcache *regcache,
+				    uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int opcode = PPC_FIELD (insn_suffix, 21, 8);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  int at = PPC_FIELD (insn_suffix, 6, 3);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 3)
+    {
+      if (ST4 == 9)
+	switch (opcode)
+	  {
+	  case 35:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
+			   MMIRR, pmxvi4ger8 */
+	  case 34:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
+			   MMIRR, pmxvi4ger8pp */
+
+	  case 99:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER with Saturate Positive multiply,
+			   Positive accumulate, xvi8ger4spp */
+
+	  case 3:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER MMIRR, pmxvi8ger4 */
+	  case 2:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER Positive multiply, Positive accumulate
+			   MMIRR, pmxvi8ger4pp */
+
+	  case 75:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER MMIRR, pmxvi16ger2 */
+	  case 107:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER  Positive multiply, Positive accumulate,
+			   pmxvi16ger2pp */
+
+	  case 43:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER with Saturation MMIRR, pmxvi16ger2s */
+	  case 42:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER with Saturation Positive multiply, Positive
+			   accumulate MMIRR, pmxvi16ger2spp */
+	    ppc_record_ACC_fpscr (regcache, tdep, at, DO_NOT_RECORD_FPSCR);
+	    return 0;
+
+	  case 19:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER MMIRR, pmxvf16ger2 */
+	  case 18:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Positive multiply, Positive accumulate MMIRR,
+			   pmxvf16ger2pp */
+	  case 146:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf16ger2pn */
+	  case 82:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf16ger2np */
+	  case 210:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf16ger2nn */
+
+	  case 27:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER MMIRR, pmxvf32ger */
+	  case 26:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Positive multiply, Positive accumulate MMIRR,
+			   pmxvf32gerpp */
+	  case 154:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf32gerpn */
+	  case 90:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf32gernp */
+	  case 218:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf32gernn */
+
+	  case 59:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER MMIRR, pmxvf64ger */
+	  case 58:	/* Floating-Point GER Positive multiply, Positive
+			   accumulate MMIRR, pmxvf64gerpp */
+	  case 186:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf64gerpn */
+	  case 122:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf64gernp */
+	  case 250:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf64gernn */
+
+	  case 51:	/* Prefixed Masked VSX Vector bfloat16 GER MMIRR,
+			   pmxvbf16ger2 */
+	  case 50:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
+			   multiply, Positive accumulate MMIRR,
+			   pmxvbf16ger2pp */
+	  case 178:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
+			   multiply, Negative accumulate MMIRR,
+			   pmxvbf16ger2pn */
+	  case 114:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
+			   multiply, Positive accumulate MMIRR,
+			   pmxvbf16ger2np */
+	  case 242:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
+			   multiply, Negative accumulate MMIRR,
+			   pmxvbf16ger2nn */
+	    ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
+	    return 0;
+	  }
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed store instructions.  The arguments are the instruction
+   address, the first 32-bits of the instruction(insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_store (struct gdbarch *gdbarch,
+				 struct regcache *regcache,
+				 CORE_ADDR addr, uint32_t insn_prefix,
+				 uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST iaddr = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int op6 = PPC_OP6 (insn_suffix);
+
+  if (R == 0)
+    {
+      if (PPC_RA (insn_suffix) != 0)
+	regcache_raw_read_unsigned (regcache, tdep->ppc_gp0_regnum
+				    + PPC_RA (insn_suffix), &iaddr);
+    }
+  else
+    {
+      iaddr = addr;     /* PC relative */
+    }
+
+  switch (op6)
+    {
+    case 38:
+      size =  1;    /* store byte, pstb */
+      break;
+    case 44:
+      size =  2;    /* store halfword, psth */
+      break;
+    case 36:
+    case 52:
+      size =  4;    /* store word, pstw, pstfs */
+      break;
+    case 54:
+    case 61:
+      size =  8;    /* store double word, pstd, pstfd */
+      break;
+    case 60:
+      size = 16;    /* store quadword, pstq */
+      break;
+    default: return -1;
+    }
+
+  iaddr += P_PPC_D (insn_prefix, insn_suffix);
+  record_full_arch_list_add_mem (iaddr, size);
+  return 0;
+}
+
+/* Record the prefixed instructions with primary op code 32.  The arguments
+   are the first 32-bits of the instruction (insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op32 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1)
+    {
+      if (ST4 == 0)
+	{
+	  switch (PPC_FIELD (insn_suffix, 11, 3))
+	    {
+	    case 0:  	/* VSX Vector Splat Immediate Word 8RR, xxsplti32dx */
+	      ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
+	      return 0;
+	    }
+
+	  switch (PPC_FIELD (insn_suffix, 11, 4))
+	    {
+	    case 2:  	/* VSX Vector Splat Immediate Double-Precision
+			   8RR, xxspltidp */
+	    case 3:  	/* VSX Vector Splat Immediate Word 8RR, xxspltiw */
+	      ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
+	      return 0;
+	    default:
+	      return -1;
+	    }
+	}
+      else
+	return -1;
+
+    }
+  else if (type == 2)
+    {
+      if (ST1 == 0)  		/* Prefixed Load Word and Zero, plwz */
+	record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	return -1;
+
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed instructions with primary op code 33.  The arguments
+   are the first 32-bits of the instruction(insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op33 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1)
+    {
+      if (ST4 == 0)
+	switch (PPC_FIELD (insn_suffix, 26, 2))
+	  {
+	  case 0:  	/* VSX Vector Blend Variable Byte 8RR, xxblendvb */
+	  case 1:  	/* VSX Vector Blend Variable Halfword, xxblendvh */
+	  case 2:  	/* VSX Vector Blend Variable Word, xxblendvw */
+	  case 3:  	/* VSX Vector Blend Variable Doubleword, xxblendvd */
+	    ppc_record_vsr (regcache, tdep, PPC_XT (insn_suffix));
+	  break;
+	  default:
+	    return -1;
+	  }
+      else
+	return -1;
+
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed instructions with primary op code 34.  The arguments
+   are the first 32-bits of the instruction(insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op34 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1)
+    {
+      if (ST4 == 0)
+	switch (PPC_FIELD (insn_suffix, 26, 2))
+	  {
+	  case 0:  	/* VSX Vector Permute Extended 8RR, xxpermx */
+	  case 1:  	/* VSX Vector Evaluate 8RR, xxeval */
+	    ppc_record_vsr (regcache, tdep, P_PPC_XT (insn_suffix));
+	    break;
+	  default:
+	    return -1;
+	  }
+      else
+	return -1;
+
+    }
+  else if (type == 2)
+    {
+      if (ST1 == 0)  		/* Prefixed Load Word and Zero, plbz */
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	return -1;
+
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed VSX store, form DS, instructions.  The arguments are the
+   instruction address (addr), the first 32-bits of the instruction
+   (insn_prefix) followed by the 32-bit instruction suffix (insn_suffix).
+   Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_store_vsx_ds_form (struct gdbarch *gdbarch,
+					     struct regcache *regcache,
+					     CORE_ADDR addr,
+					     uint32_t insn_prefix,
+					     uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST ea = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if ((type == 0) && (ST1 == 0))
+    {
+      if (R == 0)
+	{
+	  if (PPC_RA (insn_suffix) != 0)
+	    regcache_raw_read_unsigned (regcache,
+					tdep->ppc_gp0_regnum
+					+ PPC_RA (insn_suffix),
+					&ea);
+	}
+      else
+	{
+	  ea = addr;     /* PC relative */
+	}
+
+      ea += P_PPC_D (insn_prefix, insn_suffix);
+      switch (PPC_FIELD (insn_suffix, 0, 6))
+	{
+	case 46:    /* Prefixed Store VSX Scalar Doubleword, pstxsd */
+	  size = 8;
+	  break;
+	case 47:    /* Prefixed,Store VSX Scalar Single-Precision, pstxssp */
+	  size = 4;
+	  break;
+	default:
+	  return -1;
+	}
+      record_full_arch_list_add_mem (ea, size);
+      return 0;
+  }
+  else
+    return -1;
+}
+
+/* Record the prefixed VSX, form D, instructions.  The arguments are the
+   instruction address for PC-relative addresss (addr), the first 32-bits of
+   the instruction (insn_prefix) and the following 32-bits of the instruction
+   (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_vsx_d_form (struct gdbarch *gdbarch,
+				      struct regcache *regcache,
+				      CORE_ADDR addr,
+				      uint32_t insn_prefix,
+				      uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST ea = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if ((type == 0) && (ST1 == 0))
+    {
+      switch (PPC_FIELD (insn_suffix, 0, 5))
+	{
+	case 25:	/* Prefixed Load VSX Vector, plxv */
+	  ppc_record_vsr (regcache, tdep, P_PPC_XT5 (insn_prefix));
+	  return 0;
+	case 27:	/* Prefixed Store VSX Vector 8LS, pstxv */
+	  {
+	    size = 16;
+	    if (R == 0)
+	      {
+		if (PPC_RA (insn_suffix) != 0)
+		  regcache_raw_read_unsigned (regcache,
+					      tdep->ppc_gp0_regnum
+					      + PPC_RA (insn_suffix),
+					      &ea);
+	      }
+	    else
+	      {
+		ea = addr;     /* PC relative */
+	      }
+
+	    ea += P_PPC_D (insn_prefix, insn_suffix);
+	    record_full_arch_list_add_mem (ea, size);
+	    return 0;
+	  }
+	}
+      return -1;
+    }
+  else
+    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.  */
 
+/* This handles the recording of the various prefix instructions.  It takes
+   the instruction address, the first 32-bits of the instruction (insn_prefix)
+   and the following 32-bits of the instruction (insn_suffix).  Return 0 on
+   success.  */
+
+static int
+ppc_process_prefix_instruction (int insn_prefix, int insn_suffix,
+				CORE_ADDR addr,	struct gdbarch *gdbarch,
+				struct regcache *regcache)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int op6;
+
+  /* D-form has uses a 5-bit opcode in the instruction suffix */
+  if (ppc_process_record_prefix_vsx_d_form ( gdbarch, regcache, addr,
+					     insn_prefix, insn_suffix) == 0)
+    goto SUCCESS;
+
+  op6 = PPC_OP6 (insn_suffix);  /* 6-bit opcode in the instruction suffix */
+
+  switch (op6)
+    {
+    case 14:		/* Prefixed Add Immediate, paddi */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 32:
+      if (ppc_process_record_prefix_op32 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 33:
+      if (ppc_process_record_prefix_op33 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 34:		/* Prefixed Load Byte and Zero, plbz */
+      if (ppc_process_record_prefix_op34 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+    case 40:		/* Prefixed Load Halfword and Zero, plhz */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+      break;
+
+    case 36:		/* Prefixed Store Word, pstw */
+    case 38:		/* Prefixed Store Byte, pstb */
+    case 44:		/* Prefixed Store Halfword, psth */
+    case 52:		/* Prefixed Store Floating-Point Single, pstfs */
+    case 54:		/* Prefixed Store Floating-Point Double, pstfd */
+    case 60:		/* Prefixed Store Quadword, pstq */
+    case 61:		/* Prefixed Store Doubleword, pstd */
+      if (ppc_process_record_prefix_store (gdbarch, regcache, addr,
+					   insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 42:
+      if (ppc_process_record_prefix_op42 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 43:          /* Prefixed Load VSX Scalar Single-Precision, plxssp */
+      if ((type == 0) && (ST1 == 0))
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
+      else
+	  goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 46:
+    case 47:
+      if (ppc_process_record_prefix_store_vsx_ds_form (gdbarch, regcache, addr,
+					       insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 56:		/* Prefixed Load Quadword, plq */
+      {
+	if ((type == 0) && (ST1 == 0))
+	  {
+	    int tmp;
+	    tmp = tdep->ppc_gp0_regnum + (PPC_RT (insn_suffix) & ~1);
+	    record_full_arch_list_add_reg (regcache, tmp);
+	    record_full_arch_list_add_reg (regcache, tmp + 1);
+	  }
+	else
+	  goto UNKNOWN_PREFIX_OP;
+	break;
+      }
+
+    case 41:		/* Prefixed Load Word Algebraic, plwa */
+    case 57:  		/* Prefixed Load Doubleword, pld */
+      if ((type == 0) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 48:		/* Prefixed Load Floating-Point Single, plfs */
+    case 50:		/* Prefixed Load Floating-Point Double, plfd */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_fp0_regnum
+				       + PPC_FRT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 58:		/* Prefixed Load VSX Vector Paired, plxvp */
+      if ((type == 0) && (ST1 == 0))
+	{
+	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix));
+	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix) + 1);
+	}
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 59:
+      if (ppc_process_record_prefix_op59_XX3 (gdbarch, regcache, insn_prefix,
+					      insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 62:	    /* Prefixed Store VSX Vector Paired 8LS, pstxvp */
+      if ((type == 0) && (ST1 == 0))
+	{
+	  int R = PPC_BIT (insn_prefix, 11);
+	  CORE_ADDR ea = 0;
+
+	  if (R == 0)
+	    {
+	      if (PPC_RA (insn_suffix) != 0)
+		regcache_raw_read_unsigned (regcache,
+					    tdep->ppc_gp0_regnum
+					    + PPC_RA (insn_suffix), &ea);
+	    }
+	  else
+	    {
+	      ea = addr;     /* PC relative */
+	    }
+
+	  ea += P_PPC_D (insn_prefix, insn_suffix) << 4;
+	  record_full_arch_list_add_mem (ea, 32);
+	}
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    default:
+UNKNOWN_PREFIX_OP:
+      gdb_printf (gdb_stdlog,
+		  "Warning: Don't know how to record prefix instruction "
+		  "%08x %08x at %s, %d.\n",
+		  insn_prefix, insn_suffix, paddress (gdbarch, addr),
+		  op6);
+      return -1;
+    }
+
+ SUCCESS:
+  if (record_full_arch_list_add_reg (regcache, PPC_PC_REGNUM))
+    return -1;
+
+  if (record_full_arch_list_add_end ())
+    return -1;
+  return 0;
+}
+
 int
 ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 		      CORE_ADDR addr)
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  uint32_t insn;
+  uint32_t insn, insn_suffix;
   int op6, tmp, i;
 
   insn = read_memory_unsigned_integer (addr, 4, byte_order);
@@ -5965,16 +7100,28 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 
   switch (op6)
     {
+    case 1:		/* prefixed instruction */
+      {
+	/* Get the lower 32-bits of the prefixed instruction. */
+	insn_suffix = read_memory_unsigned_integer (addr+4, 4, byte_order);
+	return ppc_process_prefix_instruction (insn, insn_suffix, addr,
+					       gdbarch, regcache);
+      }
     case 2:		/* Trap Doubleword Immediate */
     case 3:		/* Trap Word Immediate */
       /* Do nothing.  */
       break;
 
-    case 4:
+    case 4:             /* Vector Integer, Compare, Logical, Shift, etc.  */  
       if (ppc_process_record_op4 (gdbarch, regcache, addr, insn) != 0)
 	return -1;
       break;
 
+    case 6:             /* Vector Load and Store */
+      if (ppc_process_record_op6 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      break;
+
     case 17:		/* System call */
       if (PPC_LEV (insn) != 0)
 	goto UNKNOWN_OP;
-- 
2.31.1



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/2 Version 3] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-13 14:12       ` will schmidt
@ 2022-04-13 21:38         ` Carl Love
  2022-04-14 13:05           ` Pedro Alves
  0 siblings, 1 reply; 25+ messages in thread
From: Carl Love @ 2022-04-13 21:38 UTC (permalink / raw)
  To: will schmidt, Joel Brobecker, gdb-patches
  Cc: Ulrich Weigand, Tulio Magno, Rogerio Alves, cel


Will, Joel, GDB maintainers:

Version 2 updated the test cases per the comments from Joel.

Version 3 updated the test cases and source code files per the comments
from Will.

I have retested the testcases with version 3 of the gdb source code
patch on Power 9 and Power 10 to verify the tests still work.

Please let me know if you see any additional issues with the patch. 
Thanks.

                   Carl Love
--------------------------------------------------------
GDB Powerpc record test cases for ISA 2.06 and ISA 3.1

This patch adds Powerpc specific tests to verify recording of various
instructions.  The first test case checks the ISA 2.06 lxvd2x instruction.
The second test case tests several of the ISA 3.01 instructions.  Specifically,
it checks the word and prefixed instructions and some of the Matrix
Multiply Assist (MMA) instructions.

The patch has been run on both Power 10 and Power 9 to verify the ISA
2.06 test case runs on both platforms without errors.  The ISA 3.1 test
runs without errors on Power 10 and is skipped as expected on Power 9.
---
 .../gdb.reverse/ppc_record_test_isa_2_06.c    |  46 ++
 .../gdb.reverse/ppc_record_test_isa_2_06.exp  | 122 +++++
 .../gdb.reverse/ppc_record_test_isa_3_1.c     | 102 ++++
 .../gdb.reverse/ppc_record_test_isa_3_1.exp   | 494 ++++++++++++++++++
 4 files changed, 764 insertions(+)
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp

diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
new file mode 100644
index 00000000000..e9c3eb1c659
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
@@ -0,0 +1,46 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <ctype.h>     // isspace
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>    // getopt
+#include <altivec.h>   // vector
+
+/* globals used for vector tests */
+static vector unsigned long vec_xb;
+static unsigned long ra, rb, rs;
+
+int main ()
+{
+  ra = 0xABCDEF012;
+  rb = 0;
+  rs = 0x012345678;
+
+  /* 9.0, 16.0, 25.0, 36.0 */
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+
+  /* Test 1 ISA 2.06 instructions.  Load source into vs1, result of sqrt
+     put into vs0.  */
+  ra = (unsigned long) & vec_xb;        /* stop 1 */
+  __asm__ __volatile__ ("lxvd2x 1, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("xvsqrtsp 0, 1");
+  ra = 0;                               /* stop 2 */
+}
+
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
new file mode 100644
index 00000000000..adb5a08278e
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
@@ -0,0 +1,122 @@
+# Copyright 2008-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# This file is part of the GDB testsuite.  It tests reverse stepping.
+# Lots of code borrowed from "step-reverse.exp".
+#
+# Test instruction record for Powerpc, ISA 2.06.
+#
+
+# The basic flow of the record tests are:
+#    1) Stop before executing the instructions of interest. Record
+#       the initial value of the registers that the instruction will
+#       change, i.e. the destination register.
+#    2) Execute the instructions.  Record the new value of the
+#       registers that changed.
+#    3) Reverse the direction of the execution and execute back to
+#       just before the instructions of interest.  Record the final
+#       value of the registers of interest.
+#    4) Check that the initial and new values of the registers are
+#       different, i.e. the instruction changed the registers as expected.
+#    5) Check that the initial and final values of the registers are
+#       the same, i.e. gdb record restored the registers to their
+#       original values.
+
+standard_testfile
+
+set gen_src record_test_isa_2_06.c
+set executable record_test_isa_2_06
+set options [list debug]
+
+if {![istarget "powerpc*"]} then  {
+    verbose "Skipping Powerpc ISA 2.06 instruction record_test_2_06."
+    return
+}
+
+if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
+    return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] then {
+    untested "could not run to main"
+    continue
+}
+
+gdb_test_no_output "record"
+
+###### Test 1:  Test an ISA 2.06 load (lxvd2x) and square root instruction
+###### (xvsqrtsp).  The load instruction will load vs1.  The sqrt instruction
+###### will put its result into vs0.
+
+set stop1  [gdb_get_line_number "stop 1"]
+set stop2  [gdb_get_line_number "stop 2"]
+
+gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test 1"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 1"
+
+# Record the initial values in vs0, vs1.
+set vs0_initial [capture_command_output "info register vs0" ""]
+set vs1_initial [capture_command_output "info register vs1" ""]
+
+gdb_test "break $stop2" ".*Breakpoint .*" "executed lxvd2x, xvsqrtsp"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 2"
+
+# Record the new values of vs0 and vs1.
+set vs0_new [capture_command_output "info register vs0" ""]
+set vs1_new [capture_command_output "info register vs1" ""]
+
+# Reverse the execution direction. 
+gdb_test_no_output "set exec-direction reverse"
+gdb_test "break $stop1" ".*Breakpoint .*" "un executed lxvd2x, xvsqrtsp"
+
+# Execute in reverse to before the lxvd2x instruction.
+gdb_test "continue"  ".*Breakpoint.*" "At stop 1 in reverse"
+
+# Record the final values of vs0, vs1.
+set vs0_final [capture_command_output "info register vs0" ""]
+set vs1_final [capture_command_output "info register vs1" ""]
+
+# Check initial and new of vs0 are different.
+set test_vs0_init_new "check vs0 initial versus vs0 new"
+if {[string compare $vs0_initial  $vs0_new ] == 0} {
+    fail $test_vs0_init_new
+} else {
+    pass $test_vs0_init_new
+}
+
+# Check initial and new of vs1 are different.
+set test_vs1_init_new "check vs0 initial versus vs1 new"
+if {[string compare $vs1_initial  $vs1_new ] == 0} {
+    fail $test_vs1_init_new
+} else {
+    pass $test_vs1_init_new
+}
+
+# Check initial and final are the same.
+set test_vs0_init_final "check vs0 initial versus vs0 final"
+if {[string compare $vs0_initial  $vs0_final ] == 0} {
+    pass $test_vs0_init_final
+} else {
+    fail $test_vs0_init_final
+}
+
+# Check initial and final are the same.
+set test_vs1_init_final "check vs1 initial versus vs1 final"
+if {[string compare $vs1_initial  $vs1_final ] == 0} {
+    pass $test_vs1_init_final
+} else {
+    fail $test_vs1_init_final
+}
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
new file mode 100644
index 00000000000..e02c3daaed3
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
@@ -0,0 +1,102 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <ctype.h>     // isspace
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>    // getopt
+#include <altivec.h>   // vector
+
+/* globals used for vector tests */
+static vector unsigned long vec_xa, vec_xb, vec_xt;
+static unsigned long ra, rb, rs;
+
+int main ()
+{
+  ra = 0xABCDEF012;
+  rb = 0;
+  rs = 0x012345678;
+
+  /* 9.0, 16.0, 25.0, 36.0 */
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+
+  vec_xt = (vector unsigned long){0xFF00FF00FF00FF00, 0xAA00AA00AA00AA00};
+
+  /* Test 1, ISA 3.1 word instructions. Load source into r1, result of brh
+     put in r0.  */
+  ra = 0xABCDEF012;                     /* stop 1 */
+  __asm__ __volatile__ ("pld 1, %0" :: "r" (ra ));
+  __asm__ __volatile__ ("brh 0, 1" );
+  ra = 0;                               /* stop 2 */
+
+  /* Test 2, ISA 3.1 MMA instructions with results in various ACC entries
+     xxsetaccz    - ACC[3]
+     xvi4ger8     - ACC[4]
+     xvf16ger2pn  - ACC[5]
+     pmxvi8ger4   - ACC[6]
+     pmxvf32gerpp - ACC[7] and fpscr */
+  /* Need to initialize the vs registers to a non zero value.  */
+  ra = (unsigned long) & vec_xb;
+  __asm__ __volatile__ ("lxvd2x 12, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 13, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 14, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 15, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xa = (vector unsigned long){0x333134343987601, 0x9994bbbc9983307};
+  vec_xb = (vector unsigned long){0x411234041898760, 0x41c833042103400};
+  __asm__ __volatile__ ("lxvd2x 16, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x123456789987650, 0x235676546989807};
+  __asm__ __volatile__ ("lxvd2x 17, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x878363439823470, 0x413434c99839870};
+  __asm__ __volatile__ ("lxvd2x 18, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x043765434398760, 0x419876555558850};
+  __asm__ __volatile__ ("lxvd2x 19, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x33313434398760, 0x9994bbbc99899330};
+  __asm__ __volatile__ ("lxvd2x 20, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 21, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 22, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 23, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 24, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 25, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 26, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 27, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xa = (vector unsigned long){0x33313434398760, 0x9994bbbc998330};
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+  __asm__ __volatile__ ("lxvd2x 28, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x4567000046800000, 0x4458000048700000};
+  __asm__ __volatile__ ("lxvd2x 29, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x41dd000041e00000, 0x41c8000046544400};
+  __asm__ __volatile__ ("lxvd2x 30, %0, %1" :: "r" (ra ), "r" (rb));
+
+  /* SNAN */
+  vec_xb = (vector unsigned long){0x7F8F00007F8F0000, 0x7F8F00007F8F0000};
+
+  __asm__ __volatile__ ("lxvd2x 31, %0, %1" :: "r" (ra ), "r" (rb));
+
+  ra = 0xAB;                            /* stop 3 */
+  __asm__ __volatile__ ("xxsetaccz 3");
+  __asm__ __volatile__ ("xvi4ger8 4, %x0, %x1" :: "wa" (vec_xa), \
+			"wa" (vec_xb) );
+  __asm__ __volatile__ ("xvf16ger2pn 5, %x0, %x1" :: "wa" (vec_xa),\
+			"wa" (vec_xb) );
+  __asm__ __volatile__ ("pmxvi8ger4spp  6, %x0, %x1, 11, 13, 5"
+                                :: "wa" (vec_xa), "wa" (vec_xb) );
+  __asm__ __volatile__ ("pmxvf32gerpp  7, %x0, %x1, 11, 13"
+                                :: "wa" (vec_xa), "wa" (vec_xb) );
+  ra = 0;                               /* stop 4 */
+}
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
new file mode 100644
index 00000000000..00187de547a
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
@@ -0,0 +1,494 @@
+# Copyright 2008-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# This file is part of the GDB testsuite.  It tests reverse stepping.
+# Lots of code borrowed from "step-reverse.exp".
+#
+# Test instruction record for Powerpc, ISA 3.1.
+#
+
+# The basic flow of the record tests are:
+#    1) Stop before executing the instructions of interest.  Record
+#       the initial value of the registers that the instruction will
+#       change, i.e. the destination register.
+#    2) Execute the instructions.  Record the new value of the
+#       registers that changed.
+#    3) Reverse the direction of the execution and execute back to
+#       just before the instructions of interest.  Record the final
+#       value of the registers of interest.
+#    4) Check that the initial and new values of the registers are
+#       different, i.e. the instruction changed the registers as expected.
+#    5) Check that the initial and final values of the registers are
+#       the same, i.e. gdb record restored the registers to their
+#       original values.
+
+
+standard_testfile
+
+set gen_src record_test_isa_3_1.c
+set executable record_test_isa_3_1
+
+if {![istarget "powerpc*"] || [skip_power_isa_3_1_tests] } then  {
+    verbose "Skipping Powerpc ISA 3.1 instruction record_test."
+    return
+}
+
+set options [list additional_flags=-mcpu=power10  debug]
+if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
+    return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] then {
+    untested "could not run to main"
+    continue
+}
+
+gdb_test_no_output "record"
+
+######  Test 1:  Test an ISA 3.1 byte reverse word instruction (brd) and a
+######   prefixed load double (pld) instruction.
+set stop1  [gdb_get_line_number "stop 1"]
+set stop2  [gdb_get_line_number "stop 2"]
+
+gdb_test "break $stop1" ".*Breakpoint .*" "about to execute Test 1"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 1"
+
+# Record the initial values in r0, r1
+# Load the argument into r1, result of byte reverse is put into r0.
+set r0_initial [capture_command_output "info register r0" ""]
+set r1_initial [capture_command_output "info register r1" ""]
+
+gdb_test "break $stop2" ".*Breakpoint .*" "executed Test 1"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 2"
+
+# Record the new values of r0 and r1
+set r0_new [capture_command_output "info register r0" ""]
+set r1_new [capture_command_output "info register r1" ""]
+
+# Execute in reverse to before test 1
+gdb_test "set exec-direction reverse" "" "Reverse to start of Test 1"
+#gdb_test_no_output "set exec-direction reverse"
+
+gdb_test "break $stop1" ".*Breakpoint .*" "reverse stop at test 1 start"
+gdb_test "continue"  ".*Breakpoint.*" "At stop 1 in reverse"
+
+# Record the final values of r0, r1
+set r0_final [capture_command_output "info register r0" ""]
+set r1_final [capture_command_output "info register r1" ""]
+
+# Check initial and new of r0 are different.
+set test_r0_init_new "check r0 initial versus r0 new"
+if {[string compare $r0_initial  $r0_new ] == 0} {
+    fail $test_r0_init_new
+} else {
+    pass $test_r0_init_new
+}
+
+# Check initial and new of r1 are different.
+set test_r1_init_new "check r0 initial versus r1 new"
+if {[string compare $r1_initial  $r1_new ] == 0} {
+    fail $test_r1_init_new
+} else {
+    pass $test_r1_init_new
+}
+
+# Check initial and final are the same.
+set test_r0_init_final "check r0 initial versus r0 final"
+if {[string compare $r0_initial  $r0_final ] == 0} {
+    pass $test_r0_init_final
+} else {
+    fail $test_r0_init_final
+}
+
+# Check initial and final are the same.
+set test_r1_init_final "check r1 initial versus r1 final"
+if {[string compare $r1_initial  $r1_final ] == 0} {
+    pass $test_r1_init_final
+} else {
+    fail $test_r1_init_final
+}
+
+
+# Change execution direction to forward for next test.
+gdb_test "set exec-direction forward" "" "Start forward test3"
+gdb_test "record stop" ".*Process record is stopped.*" "Stopped recording 2"
+set test_del_bkpts "delete breakpoints, answer prompt 2"
+
+# Delete all breakpoints and catchpoints.
+delete_breakpoints
+
+gdb_test "record" "" "Start recording test2"
+
+
+######  Test 2:  Test the ISA 3.1 MMA instructions xxsetaccz, xvi4ger8,
+######  xvf16ger2pn, pmxvi8ger4, and pmxvf32gerpp.  Goal here is to hit all
+######  the places where ppc_record_ACC_fpscr() gets called.
+##
+##       xxsetaccz    - ACC[3], vs[12] to vs[15]
+##       xvi4ger8     - ACC[4], vs[16] to vs[19]
+##       xvf16ger2pn  - ACC[5], vs[20] to vs[23]
+##       pmxvi8ger4   - ACC[6], vs[21] to vs[27]
+##       pmxvf32gerpp - ACC[7], vs[28] to vs[31] and fpscr
+
+set stop3  [gdb_get_line_number "stop 3"]
+set stop4  [gdb_get_line_number "stop 4"]
+
+gdb_test "break $stop3" ".*Breakpoint .*" "about to execute Test 2"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 3"
+
+# Record the initial values of vs's that correspond to the ACC entries,
+# and fpscr.
+set acc_3_0_initial [capture_command_output "info register vs12" ""]
+set acc_3_1_initial [capture_command_output "info register vs13" ""]
+set acc_3_2_initial [capture_command_output "info register vs14" ""]
+set acc_3_3_initial [capture_command_output "info register vs15" ""]
+set acc_4_0_initial [capture_command_output "info register vs16" ""]
+set acc_4_1_initial [capture_command_output "info register vs17" ""]
+set acc_4_2_initial [capture_command_output "info register vs18" ""]
+set acc_4_3_initial [capture_command_output "info register vs19" ""]
+set acc_5_0_initial [capture_command_output "info register vs20" ""]
+set acc_5_1_initial [capture_command_output "info register vs21" ""]
+set acc_5_2_initial [capture_command_output "info register vs22" ""]
+set acc_5_3_initial [capture_command_output "info register vs23" ""]
+set acc_6_0_initial [capture_command_output "info register vs24" ""]
+set acc_6_1_initial [capture_command_output "info register vs25" ""]
+set acc_6_2_initial [capture_command_output "info register vs26" ""]
+set acc_6_3_initial [capture_command_output "info register vs27" ""]
+set acc_7_0_initial [capture_command_output "info register vs28" ""]
+set acc_7_1_initial [capture_command_output "info register vs29" ""]
+set acc_7_2_initial [capture_command_output "info register vs30" ""]
+set acc_7_3_initial [capture_command_output "info register vs31" ""]
+set fpscr_initial [capture_command_output "info register fpscr" ""]
+
+gdb_test "break $stop4" ".*Breakpoint .*" "executed test 2"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 4"
+
+# Record the new values of the ACC entries and fpscr.
+set acc_3_0_new [capture_command_output "info register vs12" ""]
+set acc_3_1_new [capture_command_output "info register vs13" ""]
+set acc_3_2_new [capture_command_output "info register vs14" ""]
+set acc_3_3_new [capture_command_output "info register vs15" ""]
+set acc_4_0_new [capture_command_output "info register vs16" ""]
+set acc_4_1_new [capture_command_output "info register vs17" ""]
+set acc_4_2_new [capture_command_output "info register vs18" ""]
+set acc_4_3_new [capture_command_output "info register vs19" ""]
+set acc_5_0_new [capture_command_output "info register vs20" ""]
+set acc_5_1_new [capture_command_output "info register vs21" ""]
+set acc_5_2_new [capture_command_output "info register vs22" ""]
+set acc_5_3_new [capture_command_output "info register vs23" ""]
+set acc_6_0_new [capture_command_output "info register vs24" ""]
+set acc_6_1_new [capture_command_output "info register vs25" ""]
+set acc_6_2_new [capture_command_output "info register vs26" ""]
+set acc_6_3_new [capture_command_output "info register vs27" ""]
+set acc_7_0_new [capture_command_output "info register vs28" ""]
+set acc_7_1_new [capture_command_output "info register vs29" ""]
+set acc_7_2_new [capture_command_output "info register vs30" ""]
+set acc_7_3_new [capture_command_output "info register vs31" ""]
+set fpscr_new [capture_command_output "info register fpscr" ""]
+
+# Execute in reverse to before test 2.
+gdb_test "set exec-direction reverse" "" "Reverse to start of Test 2"
+
+gdb_test "break $stop3" ".*Breakpoint .*" "reverse stop at test 2 start"
+gdb_test "continue"  ".*Breakpoint.*" "At stop 3 in reverse"
+
+# Record the final values of the ACC entries and fpscr.
+set acc_3_0_final [capture_command_output "info register vs12" ""]
+set acc_3_1_final [capture_command_output "info register vs13" ""]
+set acc_3_2_final [capture_command_output "info register vs14" ""]
+set acc_3_3_final [capture_command_output "info register vs15" ""]
+set acc_4_0_final [capture_command_output "info register vs16" ""]
+set acc_4_1_final [capture_command_output "info register vs17" ""]
+set acc_4_2_final [capture_command_output "info register vs18" ""]
+set acc_4_3_final [capture_command_output "info register vs19" ""]
+set acc_5_0_final [capture_command_output "info register vs20" ""]
+set acc_5_1_final [capture_command_output "info register vs21" ""]
+set acc_5_2_final [capture_command_output "info register vs22" ""]
+set acc_5_3_final [capture_command_output "info register vs23" ""]
+set acc_6_0_final [capture_command_output "info register vs24" ""]
+set acc_6_1_final [capture_command_output "info register vs25" ""]
+set acc_6_2_final [capture_command_output "info register vs26" ""]
+set acc_6_3_final [capture_command_output "info register vs27" ""]
+set acc_7_0_final [capture_command_output "info register vs28" ""]
+set acc_7_1_final [capture_command_output "info register vs29" ""]
+set acc_7_2_final [capture_command_output "info register vs30" ""]
+set acc_7_3_final [capture_command_output "info register vs31" ""]
+set fpscr_final [capture_command_output "info register fpscr" ""]
+
+# check initial and new ACC entries.
+set test_acc_3_0_init_new "check vs12 initial versus new"
+if {[string compare $acc_3_0_initial  $acc_3_0_new ] == 0} {
+    fail $test_acc_3_0_init_new
+} else {
+    pass $test_acc_3_0_init_new
+}
+set test_acc_3_1_init_new "check vs13 initial versus new"
+if {[string compare $acc_3_1_initial  $acc_3_1_new ] == 0} {
+    fail $test_acc_3_1_init_new
+} else {
+    pass $test_acc_3_1_init_new
+}
+set test_acc_3_2_init_new "check vs14 initial versus new"
+if {[string compare $acc_3_2_initial  $acc_3_2_new ] == 0} {
+    fail $test_acc_3_2_init_new
+} else {
+    pass $test_acc_3_2_init_new
+}
+set test_acc_3_3_init_new "check vs15 initial versus new"
+if {[string compare $acc_3_3_initial  $acc_3_3_new ] == 0} {
+    fail $test_acc_3_3_init_new
+} else {
+    pass $test_acc_3_3_init_new
+}
+
+set test_acc_4_0_init_new "check vs16 initial versus new"
+if {[string compare $acc_4_0_initial  $acc_4_0_new ] == 0} {
+    fail $test_acc_4_0_init_new
+} else {
+    pass $test_acc_4_0_init_new
+}
+set test_acc_4_1_init_new "check vs17 initial versus new"
+if {[string compare $acc_4_1_initial  $acc_4_1_new ] == 0} {
+    fail $test_acc_4_1_init_new
+} else {
+    pass $test_acc_4_1_init_new
+}
+set test_acc_4_2_init_new "check vs18 initial versus new"
+if {[string compare $acc_4_2_initial  $acc_4_2_new ] == 0} {
+    fail $test_acc_4_2_init_new
+} else {
+    pass $test_acc_4_2_init_new
+}
+set test_acc_4_3_init_new "check vs19 initial versus new"
+if {[string compare $acc_4_3_initial  $acc_4_3_new ] == 0} {
+    fail $test_acc_4_3_init_new
+} else {
+    pass $test_acc_4_3_init_new
+}
+
+set test_acc_5_0_init_new "check vs20 initial versus new"
+if {[string compare $acc_5_0_initial  $acc_5_0_new ] == 0} {
+    fail $test_acc_5_0_init_new
+} else {
+    pass $test_acc_5_0_init_new
+}
+set test_acc_5_1_init_new "check vs21 initial versus new"
+if {[string compare $acc_5_1_initial  $acc_5_1_new ] == 0} {
+    fail $test_acc_5_1_init_new
+} else {
+    pass $test_acc_5_1_init_new
+}
+set test_acc_5_2_init_new "check vs22 initial versus new"
+if {[string compare $acc_5_2_initial  $acc_5_2_new ] == 0} {
+    fail $test_acc_5_2_init_new
+} else {
+    pass $test_acc_5_2_init_new
+}
+set test_acc_5_3_init_new "check vs23 initial versus new"
+if {[string compare $acc_5_3_initial  $acc_5_3_new ] == 0} {
+    fail $test_acc_5_3_init_new
+} else {
+    pass $test_acc_5_3_init_new
+}
+
+set test_acc_6_0_init_new "check vs24 initial versus new"
+if {[string compare $acc_6_0_initial  $acc_6_0_new ] == 0} {
+    fail $test_acc_6_0_init_new
+} else {
+    pass $test_acc_6_0_init_new
+}
+set test_acc_6_1_init_new "check vs25 initial versus new"
+if {[string compare $acc_6_1_initial  $acc_6_1_new ] == 0} {
+    fail $test_acc_6_1_init_new
+} else {
+    pass $test_acc_6_1_init_new
+}
+set test_acc_6_2_init_new "check vs26 initial versus new"
+if {[string compare $acc_6_2_initial  $acc_6_2_new ] == 0} {
+    fail $test_acc_6_2_init_new
+} else {
+    pass $test_acc_6_2_init_new
+}
+set test_acc_6_3_init_new "check vs27 initial versus new"
+if {[string compare $acc_6_3_initial  $acc_6_3_new ] == 0} {
+    fail $test_acc_6_3_init_new
+} else {
+    pass $test_acc_6_3_init_new
+}
+
+set test_acc_7_0_init_new "check vs28 initial versus new"
+if {[string compare $acc_7_0_initial  $acc_7_0_new ] == 0} {
+    fail $test_acc_7_0_init_new
+} else {
+    pass $test_acc_7_0_init_new
+}
+set test_acc_7_1_init_new "check vs29 initial versus new"
+if {[string compare $acc_7_1_initial  $acc_7_1_new ] == 0} {
+    fail $test_acc_7_1_init_new
+} else {
+    pass $test_acc_7_1_init_new
+}
+set test_acc_7_2_init_new "check vs30 initial versus new"
+if {[string compare $acc_7_2_initial  $acc_7_2_new ] == 0} {
+    fail $test_acc_7_2_init_new
+} else {
+    pass $test_acc_7_2_init_new
+}
+set test_acc_7_3_init_new "check vs31 initial versus new"
+if {[string compare $acc_7_3_initial  $acc_7_3_new ] == 0} {
+    fail $test_acc_7_3_init_new
+} else {
+    pass $test_acc_7_3_init_new
+}
+set test_fpscr_init_new "check fpscr initial versus new"
+if {[string compare $fpscr_initial  $fpscr_new ] == 0} {
+    fail $test_fpscr_init_new
+} else {
+    pass $test_fpscr_init_new
+}
+
+# Check initial and new ACC entries are different.
+set test_acc_3_0_init_final "check vs12 initial versus final"
+if {[string compare $acc_3_0_initial  $acc_3_0_final ] == 0} {
+    pass $test_acc_3_0_init_final
+} else {
+    fail $test_acc_3_0_init_final
+}
+set test_acc_3_1_init_final "check vs13 initial versus final"
+if {[string compare $acc_3_1_initial  $acc_3_1_final ] == 0} {
+    pass $test_acc_3_1_init_final
+} else {
+    fail $test_acc_3_0_init_final
+}
+set test_acc_3_2_init_final "check vs14 initial versus final"
+if {[string compare $acc_3_2_initial  $acc_3_2_final ] == 0} {
+    pass $test_acc_3_2_init_final
+} else {
+    fail $test_acc_3_2_init_final
+}
+set test_acc_3_3_init_final "check vs15 initial versus final"
+if {[string compare $acc_3_3_initial  $acc_3_3_final ] == 0} {
+    pass $test_acc_3_3_init_final
+} else {
+    new $test_acc_3_3_init_final
+}
+
+set test_acc_4_0_init_final "check vs16 initial versus final"
+if {[string compare $acc_4_0_initial  $acc_4_0_final ] == 0} {
+    pass $test_acc_4_0_init_final
+} else {
+    new $test_acc_4_0_init_final
+}
+set test_acc_4_1_init_final "check vs17 initial versus final"
+if {[string compare $acc_4_1_initial  $acc_4_1_final ] == 0} {
+    pass $test_acc_4_1_init_final
+} else {
+    new $test_acc_4_0_init_final
+}
+set test_acc_4_2_init_final "check vs18 initial versus final"
+if {[string compare $acc_4_2_initial  $acc_4_2_final ] == 0} {
+    pass $test_acc_4_2_init_final
+} else {
+    new $test_acc_4_2_init_final
+}
+set test_acc_4_3_init_final "check vs19 initial versus final"
+if {[string compare $acc_4_3_initial  $acc_4_3_final ] == 0} {
+    pass $test_acc_4_3_init_final
+} else {
+    fail $test_acc_4_3_init_final
+}
+
+set test_acc_5_0_init_final "check vs20 initial versus final"
+if {[string compare $acc_5_0_initial  $acc_5_0_final ] == 0} {
+    pass $test_acc_5_0_init_final
+} else {
+    fail $test_acc_5_0_init_final
+}
+set test_acc_5_1_init_final "check vs21 initial versus final"
+if {[string compare $acc_5_1_initial  $acc_5_1_final ] == 0} {
+    pass $test_acc_5_1_init_final
+} else {
+    fail $test_acc_5_0_init_final
+}
+set test_acc_5_2_init_final "check vs22 initial versus final"
+if {[string compare $acc_5_2_initial  $acc_5_2_final ] == 0} {
+    pass $test_acc_5_2_init_final
+} else {
+    fail $test_acc_5_2_init_final
+}
+set test_acc_5_3_init_final "check vs23 initial versus final"
+if {[string compare $acc_5_3_initial  $acc_5_3_final ] == 0} {
+    pass $test_acc_5_3_init_final
+} else {
+    fail $test_acc_5_3_init_final
+}
+
+set test_acc_6_0_init_final "check vs24 initial versus final"
+if {[string compare $acc_6_0_initial  $acc_6_0_final ] == 0} {
+    pass $test_acc_6_0_init_final
+} else {
+    fail $test_acc_6_0_init_final
+}
+set test_acc_6_1_init_final "check vs25 initial versus final"
+if {[string compare $acc_6_1_initial  $acc_6_1_final ] == 0} {
+    pass $test_acc_6_1_init_final
+} else {
+    fail $test_acc_6_0_init_final
+}
+set test_acc_6_2_init_final "check vs26 initial versus final"
+if {[string compare $acc_6_2_initial  $acc_6_2_final ] == 0} {
+    pass $test_acc_6_2_init_final
+} else {
+    fail $test_acc_6_2_init_final
+}
+set test_acc_6_3_init_final "check vs27 initial versus final"
+if {[string compare $acc_6_3_initial  $acc_6_3_final ] == 0} {
+    pass $test_acc_6_3_init_final
+} else {
+    fail $test_acc_6_3_init_final
+}
+
+set test_acc_7_0_init_final "check vs28 initial versus final"
+if {[string compare $acc_7_0_initial  $acc_7_0_final ] == 0} {
+    pass $test_acc_7_0_init_final
+} else {
+    fail $test_acc_7_0_init_final
+}
+set test_acc_7_1_init_final "check vs29 initial versus final"
+if {[string compare $acc_7_1_initial  $acc_7_1_final ] == 0} {
+    pass $test_acc_7_1_init_final
+} else {
+    fail $test_acc_7_0_init_final
+}
+set test_acc_7_2_init_final "check vs30 initial versus final"
+if {[string compare $acc_7_2_initial  $acc_7_2_final ] == 0} {
+    pass $test_acc_7_2_init_final
+} else {
+    fail $test_acc_7_2_init_final
+}
+set test_acc_7_3_init_final "check vs31 initial versus final"
+if {[string compare $acc_7_3_initial  $acc_7_3_final ] == 0} {
+    pass $test_acc_7_3_init_final
+} else {
+    fail $test_acc_7_3_init_final
+}
+set test_fpscr_init_final "check fpscr initial versus final"
+if {[string compare $fpscr_initial  $fpscr_final ] == 0} {
+    pass $test_fpscr_init_final
+} else {
+    fail $test_fpscr_init_final
+}
+
-- 
2.31.1



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/2 Version 3] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-13 21:38         ` [PATCH 2/2 Version 3] " Carl Love
@ 2022-04-14 13:05           ` Pedro Alves
  2022-04-14 20:20             ` [PATCH 2/2 Version 4] " Carl Love
  0 siblings, 1 reply; 25+ messages in thread
From: Pedro Alves @ 2022-04-14 13:05 UTC (permalink / raw)
  To: Carl Love, will schmidt, Joel Brobecker, gdb-patches
  Cc: Ulrich Weigand, Tulio Magno, Rogerio Alves

Hi Carl,

Some nits below.

On 2022-04-13 22:38, Carl Love via Gdb-patches wrote:
> 
> Will, Joel, GDB maintainers:
> 
> Version 2 updated the test cases per the comments from Joel.
> 
> Version 3 updated the test cases and source code files per the comments
> from Will.
> 
> I have retested the testcases with version 3 of the gdb source code
> patch on Power 9 and Power 10 to verify the tests still work.
> 
> Please let me know if you see any additional issues with the patch. 
> Thanks.
> 
>                    Carl Love
> --------------------------------------------------------
> GDB Powerpc record test cases for ISA 2.06 and ISA 3.1
> 
> This patch adds Powerpc specific tests to verify recording of various

ISTR that the right spelling was "PowerPC".

> instructions.  The first test case checks the ISA 2.06 lxvd2x instruction.
> The second test case tests several of the ISA 3.01 instructions.  Specifically,
> it checks the word and prefixed instructions and some of the Matrix
> Multiply Assist (MMA) instructions.
> 
> The patch has been run on both Power 10 and Power 9 to verify the ISA
> 2.06 test case runs on both platforms without errors.  The ISA 3.1 test
> runs without errors on Power 10 and is skipped as expected on Power 9.
> ---
>  .../gdb.reverse/ppc_record_test_isa_2_06.c    |  46 ++
>  .../gdb.reverse/ppc_record_test_isa_2_06.exp  | 122 +++++
>  .../gdb.reverse/ppc_record_test_isa_3_1.c     | 102 ++++
>  .../gdb.reverse/ppc_record_test_isa_3_1.exp   | 494 ++++++++++++++++++
>  4 files changed, 764 insertions(+)
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> 
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
> new file mode 100644
> index 00000000000..e9c3eb1c659
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
> @@ -0,0 +1,46 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2012-2022 Free Software Foundation, Inc.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#include <stdio.h>

Is this really needed?  The reason I ask is that we try to avoid having
tests depend on I/O because that doesn't work on all targets.

> +#include <stdint.h>
> +#include <ctype.h>     // isspace
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>    // getopt
> +#include <altivec.h>   // vector
> +

The test doesn't seem to use isspace nor vector.  Can you trim this
to the minimum necessary set, and remove the // comments, please?

> +/* globals used for vector tests */

Upperspace, period at end, and double-space:

/* Globals used for vector tests.  */

> +static vector unsigned long vec_xb;
> +static unsigned long ra, rb, rs;
> +
> +int main ()

Break before "main".

> +{
> +  ra = 0xABCDEF012;
> +  rb = 0;
> +  rs = 0x012345678;
> +
> +  /* 9.0, 16.0, 25.0, 36.0 */
> +  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
> +
> +  /* Test 1 ISA 2.06 instructions.  Load source into vs1, result of sqrt
> +     put into vs0.  */
> +  ra = (unsigned long) & vec_xb;        /* stop 1 */
> +  __asm__ __volatile__ ("lxvd2x 1, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("xvsqrtsp 0, 1");
> +  ra = 0;                               /* stop 2 */
> +}
> +
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
> new file mode 100644
> index 00000000000..adb5a08278e
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
> @@ -0,0 +1,122 @@
> +# Copyright 2008-2022 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +# This file is part of the GDB testsuite.  It tests reverse stepping.
> +# Lots of code borrowed from "step-reverse.exp".

Is the:

"It tests reverse stepping.  Lots of code borrowed from "step-reverse.exp".

part true, or relevant?  You have a description of the test just below, which
leads me to think that this might be stale.

> +#
> +# Test instruction record for Powerpc, ISA 2.06.
> +#
> +
> +# The basic flow of the record tests are:
> +#    1) Stop before executing the instructions of interest. Record

Double space after period.

> +#       the initial value of the registers that the instruction will
> +#       change, i.e. the destination register.
> +#    2) Execute the instructions.  Record the new value of the
> +#       registers that changed.
> +#    3) Reverse the direction of the execution and execute back to
> +#       just before the instructions of interest.  Record the final
> +#       value of the registers of interest.
> +#    4) Check that the initial and new values of the registers are
> +#       different, i.e. the instruction changed the registers as expected.
> +#    5) Check that the initial and final values of the registers are
> +#       the same, i.e. gdb record restored the registers to their
> +#       original values.
> +
> +standard_testfile
> +
> +set gen_src record_test_isa_2_06.c
> +set executable record_test_isa_2_06
> +set options [list debug]
> +
> +if {![istarget "powerpc*"]} then  {
> +    verbose "Skipping Powerpc ISA 2.06 instruction record_test_2_06."
> +    return
> +}
> +

Since the .c file included altivec.c, I wonder whether the .exp file should
use skip_altivec_tests.

> +if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
> +    return -1
> +}
> +
> +clean_restart $executable
> +
> +if ![runto_main] then {
> +    untested "could not run to main"
> +    continue
> +}
> +
> +gdb_test_no_output "record"
> +
> +###### Test 1:  Test an ISA 2.06 load (lxvd2x) and square root instruction
> +###### (xvsqrtsp).  The load instruction will load vs1.  The sqrt instruction
> +###### will put its result into vs0.

Theres's no "Test 2" in the file, so this "Test 1" looks odd.  IOW, why the need to think
of these tests as "1" ?  BTW, if there's some natural grouping between tests, it's
most often better to use with_test_prefix than to use comments to separate sections.

> +
> +set stop1  [gdb_get_line_number "stop 1"]
> +set stop2  [gdb_get_line_number "stop 2"]

Spurious double space.

> +
> +gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test 1"
> +gdb_test "continue"  ".*Breakpoint .*" "At stop 1"

Use lowercase for test messages.

> +
> +# Record the initial values in vs0, vs1.
> +set vs0_initial [capture_command_output "info register vs0" ""]
> +set vs1_initial [capture_command_output "info register vs1" ""]
> +
> +gdb_test "break $stop2" ".*Breakpoint .*" "executed lxvd2x, xvsqrtsp"
> +gdb_test "continue"  ".*Breakpoint .*" "At stop 2"
> +
> +# Record the new values of vs0 and vs1.
> +set vs0_new [capture_command_output "info register vs0" ""]
> +set vs1_new [capture_command_output "info register vs1" ""]
> +
> +# Reverse the execution direction. 
> +gdb_test_no_output "set exec-direction reverse"
> +gdb_test "break $stop1" ".*Breakpoint .*" "un executed lxvd2x, xvsqrtsp"
> +
> +# Execute in reverse to before the lxvd2x instruction.
> +gdb_test "continue"  ".*Breakpoint.*" "At stop 1 in reverse"
> +
> +# Record the final values of vs0, vs1.
> +set vs0_final [capture_command_output "info register vs0" ""]
> +set vs1_final [capture_command_output "info register vs1" ""]
> +
> +# Check initial and new of vs0 are different.
> +set test_vs0_init_new "check vs0 initial versus vs0 new"
> +if {[string compare $vs0_initial  $vs0_new ] == 0} {
> +    fail $test_vs0_init_new
> +} else {
> +    pass $test_vs0_init_new
> +}
> +
> +# Check initial and new of vs1 are different.
> +set test_vs1_init_new "check vs0 initial versus vs1 new"
> +if {[string compare $vs1_initial  $vs1_new ] == 0} {
> +    fail $test_vs1_init_new
> +} else {
> +    pass $test_vs1_init_new
> +}
> +
> +# Check initial and final are the same.
> +set test_vs0_init_final "check vs0 initial versus vs0 final"
> +if {[string compare $vs0_initial  $vs0_final ] == 0} {
> +    pass $test_vs0_init_final
> +} else {
> +    fail $test_vs0_init_final
> +}
> +
> +# Check initial and final are the same.
> +set test_vs1_init_final "check vs1 initial versus vs1 final"
> +if {[string compare $vs1_initial  $vs1_final ] == 0} {

spurious double space in all these string compares.  You could also
use gdb_assert instead of explicit pass/fail.

> +    pass $test_vs1_init_final
> +} else {
> +    fail $test_vs1_init_final
> +}
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
> new file mode 100644
> index 00000000000..e02c3daaed3
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
> @@ -0,0 +1,102 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2012-2022 Free Software Foundation, Inc.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <ctype.h>     // isspace
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>    // getopt
> +#include <altivec.h>   // vector
> +

Same comments as the other file.

> +/* globals used for vector tests */
> +static vector unsigned long vec_xa, vec_xb, vec_xt;
> +static unsigned long ra, rb, rs;
> +
> +int main ()
> +{
> +  ra = 0xABCDEF012;
> +  rb = 0;
> +  rs = 0x012345678;
> +
> +  /* 9.0, 16.0, 25.0, 36.0 */
> +  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
> +
> +  vec_xt = (vector unsigned long){0xFF00FF00FF00FF00, 0xAA00AA00AA00AA00};
> +
> +  /* Test 1, ISA 3.1 word instructions. Load source into r1, result of brh
> +     put in r0.  */
> +  ra = 0xABCDEF012;                     /* stop 1 */
> +  __asm__ __volatile__ ("pld 1, %0" :: "r" (ra ));
> +  __asm__ __volatile__ ("brh 0, 1" );
> +  ra = 0;                               /* stop 2 */
> +
> +  /* Test 2, ISA 3.1 MMA instructions with results in various ACC entries
> +     xxsetaccz    - ACC[3]
> +     xvi4ger8     - ACC[4]
> +     xvf16ger2pn  - ACC[5]
> +     pmxvi8ger4   - ACC[6]
> +     pmxvf32gerpp - ACC[7] and fpscr */
> +  /* Need to initialize the vs registers to a non zero value.  */
> +  ra = (unsigned long) & vec_xb;
> +  __asm__ __volatile__ ("lxvd2x 12, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 13, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 14, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 15, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xa = (vector unsigned long){0x333134343987601, 0x9994bbbc9983307};
> +  vec_xb = (vector unsigned long){0x411234041898760, 0x41c833042103400};
> +  __asm__ __volatile__ ("lxvd2x 16, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x123456789987650, 0x235676546989807};
> +  __asm__ __volatile__ ("lxvd2x 17, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x878363439823470, 0x413434c99839870};
> +  __asm__ __volatile__ ("lxvd2x 18, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x043765434398760, 0x419876555558850};
> +  __asm__ __volatile__ ("lxvd2x 19, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x33313434398760, 0x9994bbbc99899330};
> +  __asm__ __volatile__ ("lxvd2x 20, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 21, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 22, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 23, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 24, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 25, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 26, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 27, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xa = (vector unsigned long){0x33313434398760, 0x9994bbbc998330};
> +  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
> +  __asm__ __volatile__ ("lxvd2x 28, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x4567000046800000, 0x4458000048700000};
> +  __asm__ __volatile__ ("lxvd2x 29, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x41dd000041e00000, 0x41c8000046544400};
> +  __asm__ __volatile__ ("lxvd2x 30, %0, %1" :: "r" (ra ), "r" (rb));
> +
> +  /* SNAN */
> +  vec_xb = (vector unsigned long){0x7F8F00007F8F0000, 0x7F8F00007F8F0000};
> +
> +  __asm__ __volatile__ ("lxvd2x 31, %0, %1" :: "r" (ra ), "r" (rb));
> +
> +  ra = 0xAB;                            /* stop 3 */
> +  __asm__ __volatile__ ("xxsetaccz 3");
> +  __asm__ __volatile__ ("xvi4ger8 4, %x0, %x1" :: "wa" (vec_xa), \
> +			"wa" (vec_xb) );
> +  __asm__ __volatile__ ("xvf16ger2pn 5, %x0, %x1" :: "wa" (vec_xa),\
> +			"wa" (vec_xb) );
> +  __asm__ __volatile__ ("pmxvi8ger4spp  6, %x0, %x1, 11, 13, 5"
> +                                :: "wa" (vec_xa), "wa" (vec_xb) );
> +  __asm__ __volatile__ ("pmxvf32gerpp  7, %x0, %x1, 11, 13"
> +                                :: "wa" (vec_xa), "wa" (vec_xb) );
> +  ra = 0;                               /* stop 4 */
> +}
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> new file mode 100644
> index 00000000000..00187de547a
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> @@ -0,0 +1,494 @@
> +# Copyright 2008-2022 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +# This file is part of the GDB testsuite.  It tests reverse stepping.
> +# Lots of code borrowed from "step-reverse.exp".

Ditto.

> +#
> +# Test instruction record for Powerpc, ISA 3.1.
> +#
> +
> +# The basic flow of the record tests are:
> +#    1) Stop before executing the instructions of interest.  Record
> +#       the initial value of the registers that the instruction will
> +#       change, i.e. the destination register.
> +#    2) Execute the instructions.  Record the new value of the
> +#       registers that changed.
> +#    3) Reverse the direction of the execution and execute back to
> +#       just before the instructions of interest.  Record the final
> +#       value of the registers of interest.
> +#    4) Check that the initial and new values of the registers are
> +#       different, i.e. the instruction changed the registers as expected.
> +#    5) Check that the initial and final values of the registers are
> +#       the same, i.e. gdb record restored the registers to their
> +#       original values.
> +
> +
> +standard_testfile
> +
> +set gen_src record_test_isa_3_1.c
> +set executable record_test_isa_3_1
> +
> +if {![istarget "powerpc*"] || [skip_power_isa_3_1_tests] } then  {
> +    verbose "Skipping Powerpc ISA 3.1 instruction record_test."
> +    return
> +}
> +
> +set options [list additional_flags=-mcpu=power10  debug]

Spurious double space.

> +if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
> +    return -1
> +}
> +
> +clean_restart $executable
> +
> +if ![runto_main] then {
> +    untested "could not run to main"
> +    continue
> +}
> +
> +gdb_test_no_output "record"
> +

Comments to the other file apply to this one as well.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH 2/2 Version 4] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-14 13:05           ` Pedro Alves
@ 2022-04-14 20:20             ` Carl Love
  2022-04-14 20:43               ` Carl Love
  0 siblings, 1 reply; 25+ messages in thread
From: Carl Love @ 2022-04-14 20:20 UTC (permalink / raw)
  To: Pedro Alves, will schmidt, Joel Brobecker, gdb-patches
  Cc: Ulrich Weigand, Tulio Magno, Rogerio Alves

Pedro, Will, Joel:
On Thu, 2022-04-14 at 14:05 +0100, Pedro Alves wrote:
> Hi Carl,
> 
> Some nits below.

Thanks for point out the typos.  I have fixed the typos in both files. 
None of the include files are actually needed, I removed them in both
files. 

Please let me know is you see anything else.  Thanks.

I re-ran the tests on Power 10 to make sure I didn't break anything.

                    Carl Love

---------------------------------------------------------

GDB Powerpc record test cases for ISA 2.06 and ISA 3.1

This patch adds Powerpc specific tests to verify recording of various
instructions.  The first test case checks the ISA 2.06 lxvd2x instruction.
The second test case tests several of the ISA 3.01 instructions.  Specifically,
it checks the word and prefixed instructions and some of the Matrix
Multiply Assist (MMA) instructions.

The patch has been run on both Power 10 and Power 9 to verify the ISA
2.06 test case runs on both platforms without errors.  The ISA 3.1 test
runs without errors on Power 10 and is skipped as expected on Power 9.
---
 .../gdb.reverse/ppc_record_test_isa_2_06.c    |  46 ++
 .../gdb.reverse/ppc_record_test_isa_2_06.exp  | 122 +++++
 .../gdb.reverse/ppc_record_test_isa_3_1.c     | 102 ++++
 .../gdb.reverse/ppc_record_test_isa_3_1.exp   | 494 ++++++++++++++++++
 4 files changed, 764 insertions(+)
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp

diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
new file mode 100644
index 00000000000..e9c3eb1c659
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
@@ -0,0 +1,46 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <ctype.h>     // isspace
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>    // getopt
+#include <altivec.h>   // vector
+
+/* globals used for vector tests */
+static vector unsigned long vec_xb;
+static unsigned long ra, rb, rs;
+
+int main ()
+{
+  ra = 0xABCDEF012;
+  rb = 0;
+  rs = 0x012345678;
+
+  /* 9.0, 16.0, 25.0, 36.0 */
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+
+  /* Test 1 ISA 2.06 instructions.  Load source into vs1, result of sqrt
+     put into vs0.  */
+  ra = (unsigned long) & vec_xb;        /* stop 1 */
+  __asm__ __volatile__ ("lxvd2x 1, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("xvsqrtsp 0, 1");
+  ra = 0;                               /* stop 2 */
+}
+
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
new file mode 100644
index 00000000000..adb5a08278e
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
@@ -0,0 +1,122 @@
+# Copyright 2008-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# This file is part of the GDB testsuite.  It tests reverse stepping.
+# Lots of code borrowed from "step-reverse.exp".
+#
+# Test instruction record for Powerpc, ISA 2.06.
+#
+
+# The basic flow of the record tests are:
+#    1) Stop before executing the instructions of interest. Record
+#       the initial value of the registers that the instruction will
+#       change, i.e. the destination register.
+#    2) Execute the instructions.  Record the new value of the
+#       registers that changed.
+#    3) Reverse the direction of the execution and execute back to
+#       just before the instructions of interest.  Record the final
+#       value of the registers of interest.
+#    4) Check that the initial and new values of the registers are
+#       different, i.e. the instruction changed the registers as expected.
+#    5) Check that the initial and final values of the registers are
+#       the same, i.e. gdb record restored the registers to their
+#       original values.
+
+standard_testfile
+
+set gen_src record_test_isa_2_06.c
+set executable record_test_isa_2_06
+set options [list debug]
+
+if {![istarget "powerpc*"]} then  {
+    verbose "Skipping Powerpc ISA 2.06 instruction record_test_2_06."
+    return
+}
+
+if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
+    return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] then {
+    untested "could not run to main"
+    continue
+}
+
+gdb_test_no_output "record"
+
+###### Test 1:  Test an ISA 2.06 load (lxvd2x) and square root instruction
+###### (xvsqrtsp).  The load instruction will load vs1.  The sqrt instruction
+###### will put its result into vs0.
+
+set stop1  [gdb_get_line_number "stop 1"]
+set stop2  [gdb_get_line_number "stop 2"]
+
+gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test 1"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 1"
+
+# Record the initial values in vs0, vs1.
+set vs0_initial [capture_command_output "info register vs0" ""]
+set vs1_initial [capture_command_output "info register vs1" ""]
+
+gdb_test "break $stop2" ".*Breakpoint .*" "executed lxvd2x, xvsqrtsp"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 2"
+
+# Record the new values of vs0 and vs1.
+set vs0_new [capture_command_output "info register vs0" ""]
+set vs1_new [capture_command_output "info register vs1" ""]
+
+# Reverse the execution direction. 
+gdb_test_no_output "set exec-direction reverse"
+gdb_test "break $stop1" ".*Breakpoint .*" "un executed lxvd2x, xvsqrtsp"
+
+# Execute in reverse to before the lxvd2x instruction.
+gdb_test "continue"  ".*Breakpoint.*" "At stop 1 in reverse"
+
+# Record the final values of vs0, vs1.
+set vs0_final [capture_command_output "info register vs0" ""]
+set vs1_final [capture_command_output "info register vs1" ""]
+
+# Check initial and new of vs0 are different.
+set test_vs0_init_new "check vs0 initial versus vs0 new"
+if {[string compare $vs0_initial  $vs0_new ] == 0} {
+    fail $test_vs0_init_new
+} else {
+    pass $test_vs0_init_new
+}
+
+# Check initial and new of vs1 are different.
+set test_vs1_init_new "check vs0 initial versus vs1 new"
+if {[string compare $vs1_initial  $vs1_new ] == 0} {
+    fail $test_vs1_init_new
+} else {
+    pass $test_vs1_init_new
+}
+
+# Check initial and final are the same.
+set test_vs0_init_final "check vs0 initial versus vs0 final"
+if {[string compare $vs0_initial  $vs0_final ] == 0} {
+    pass $test_vs0_init_final
+} else {
+    fail $test_vs0_init_final
+}
+
+# Check initial and final are the same.
+set test_vs1_init_final "check vs1 initial versus vs1 final"
+if {[string compare $vs1_initial  $vs1_final ] == 0} {
+    pass $test_vs1_init_final
+} else {
+    fail $test_vs1_init_final
+}
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
new file mode 100644
index 00000000000..e02c3daaed3
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
@@ -0,0 +1,102 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <ctype.h>     // isspace
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>    // getopt
+#include <altivec.h>   // vector
+
+/* globals used for vector tests */
+static vector unsigned long vec_xa, vec_xb, vec_xt;
+static unsigned long ra, rb, rs;
+
+int main ()
+{
+  ra = 0xABCDEF012;
+  rb = 0;
+  rs = 0x012345678;
+
+  /* 9.0, 16.0, 25.0, 36.0 */
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+
+  vec_xt = (vector unsigned long){0xFF00FF00FF00FF00, 0xAA00AA00AA00AA00};
+
+  /* Test 1, ISA 3.1 word instructions. Load source into r1, result of brh
+     put in r0.  */
+  ra = 0xABCDEF012;                     /* stop 1 */
+  __asm__ __volatile__ ("pld 1, %0" :: "r" (ra ));
+  __asm__ __volatile__ ("brh 0, 1" );
+  ra = 0;                               /* stop 2 */
+
+  /* Test 2, ISA 3.1 MMA instructions with results in various ACC entries
+     xxsetaccz    - ACC[3]
+     xvi4ger8     - ACC[4]
+     xvf16ger2pn  - ACC[5]
+     pmxvi8ger4   - ACC[6]
+     pmxvf32gerpp - ACC[7] and fpscr */
+  /* Need to initialize the vs registers to a non zero value.  */
+  ra = (unsigned long) & vec_xb;
+  __asm__ __volatile__ ("lxvd2x 12, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 13, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 14, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 15, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xa = (vector unsigned long){0x333134343987601, 0x9994bbbc9983307};
+  vec_xb = (vector unsigned long){0x411234041898760, 0x41c833042103400};
+  __asm__ __volatile__ ("lxvd2x 16, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x123456789987650, 0x235676546989807};
+  __asm__ __volatile__ ("lxvd2x 17, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x878363439823470, 0x413434c99839870};
+  __asm__ __volatile__ ("lxvd2x 18, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x043765434398760, 0x419876555558850};
+  __asm__ __volatile__ ("lxvd2x 19, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x33313434398760, 0x9994bbbc99899330};
+  __asm__ __volatile__ ("lxvd2x 20, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 21, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 22, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 23, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 24, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 25, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 26, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 27, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xa = (vector unsigned long){0x33313434398760, 0x9994bbbc998330};
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+  __asm__ __volatile__ ("lxvd2x 28, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x4567000046800000, 0x4458000048700000};
+  __asm__ __volatile__ ("lxvd2x 29, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x41dd000041e00000, 0x41c8000046544400};
+  __asm__ __volatile__ ("lxvd2x 30, %0, %1" :: "r" (ra ), "r" (rb));
+
+  /* SNAN */
+  vec_xb = (vector unsigned long){0x7F8F00007F8F0000, 0x7F8F00007F8F0000};
+
+  __asm__ __volatile__ ("lxvd2x 31, %0, %1" :: "r" (ra ), "r" (rb));
+
+  ra = 0xAB;                            /* stop 3 */
+  __asm__ __volatile__ ("xxsetaccz 3");
+  __asm__ __volatile__ ("xvi4ger8 4, %x0, %x1" :: "wa" (vec_xa), \
+			"wa" (vec_xb) );
+  __asm__ __volatile__ ("xvf16ger2pn 5, %x0, %x1" :: "wa" (vec_xa),\
+			"wa" (vec_xb) );
+  __asm__ __volatile__ ("pmxvi8ger4spp  6, %x0, %x1, 11, 13, 5"
+                                :: "wa" (vec_xa), "wa" (vec_xb) );
+  __asm__ __volatile__ ("pmxvf32gerpp  7, %x0, %x1, 11, 13"
+                                :: "wa" (vec_xa), "wa" (vec_xb) );
+  ra = 0;                               /* stop 4 */
+}
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
new file mode 100644
index 00000000000..00187de547a
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
@@ -0,0 +1,494 @@
+# Copyright 2008-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# This file is part of the GDB testsuite.  It tests reverse stepping.
+# Lots of code borrowed from "step-reverse.exp".
+#
+# Test instruction record for Powerpc, ISA 3.1.
+#
+
+# The basic flow of the record tests are:
+#    1) Stop before executing the instructions of interest.  Record
+#       the initial value of the registers that the instruction will
+#       change, i.e. the destination register.
+#    2) Execute the instructions.  Record the new value of the
+#       registers that changed.
+#    3) Reverse the direction of the execution and execute back to
+#       just before the instructions of interest.  Record the final
+#       value of the registers of interest.
+#    4) Check that the initial and new values of the registers are
+#       different, i.e. the instruction changed the registers as expected.
+#    5) Check that the initial and final values of the registers are
+#       the same, i.e. gdb record restored the registers to their
+#       original values.
+
+
+standard_testfile
+
+set gen_src record_test_isa_3_1.c
+set executable record_test_isa_3_1
+
+if {![istarget "powerpc*"] || [skip_power_isa_3_1_tests] } then  {
+    verbose "Skipping Powerpc ISA 3.1 instruction record_test."
+    return
+}
+
+set options [list additional_flags=-mcpu=power10  debug]
+if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
+    return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] then {
+    untested "could not run to main"
+    continue
+}
+
+gdb_test_no_output "record"
+
+######  Test 1:  Test an ISA 3.1 byte reverse word instruction (brd) and a
+######   prefixed load double (pld) instruction.
+set stop1  [gdb_get_line_number "stop 1"]
+set stop2  [gdb_get_line_number "stop 2"]
+
+gdb_test "break $stop1" ".*Breakpoint .*" "about to execute Test 1"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 1"
+
+# Record the initial values in r0, r1
+# Load the argument into r1, result of byte reverse is put into r0.
+set r0_initial [capture_command_output "info register r0" ""]
+set r1_initial [capture_command_output "info register r1" ""]
+
+gdb_test "break $stop2" ".*Breakpoint .*" "executed Test 1"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 2"
+
+# Record the new values of r0 and r1
+set r0_new [capture_command_output "info register r0" ""]
+set r1_new [capture_command_output "info register r1" ""]
+
+# Execute in reverse to before test 1
+gdb_test "set exec-direction reverse" "" "Reverse to start of Test 1"
+#gdb_test_no_output "set exec-direction reverse"
+
+gdb_test "break $stop1" ".*Breakpoint .*" "reverse stop at test 1 start"
+gdb_test "continue"  ".*Breakpoint.*" "At stop 1 in reverse"
+
+# Record the final values of r0, r1
+set r0_final [capture_command_output "info register r0" ""]
+set r1_final [capture_command_output "info register r1" ""]
+
+# Check initial and new of r0 are different.
+set test_r0_init_new "check r0 initial versus r0 new"
+if {[string compare $r0_initial  $r0_new ] == 0} {
+    fail $test_r0_init_new
+} else {
+    pass $test_r0_init_new
+}
+
+# Check initial and new of r1 are different.
+set test_r1_init_new "check r0 initial versus r1 new"
+if {[string compare $r1_initial  $r1_new ] == 0} {
+    fail $test_r1_init_new
+} else {
+    pass $test_r1_init_new
+}
+
+# Check initial and final are the same.
+set test_r0_init_final "check r0 initial versus r0 final"
+if {[string compare $r0_initial  $r0_final ] == 0} {
+    pass $test_r0_init_final
+} else {
+    fail $test_r0_init_final
+}
+
+# Check initial and final are the same.
+set test_r1_init_final "check r1 initial versus r1 final"
+if {[string compare $r1_initial  $r1_final ] == 0} {
+    pass $test_r1_init_final
+} else {
+    fail $test_r1_init_final
+}
+
+
+# Change execution direction to forward for next test.
+gdb_test "set exec-direction forward" "" "Start forward test3"
+gdb_test "record stop" ".*Process record is stopped.*" "Stopped recording 2"
+set test_del_bkpts "delete breakpoints, answer prompt 2"
+
+# Delete all breakpoints and catchpoints.
+delete_breakpoints
+
+gdb_test "record" "" "Start recording test2"
+
+
+######  Test 2:  Test the ISA 3.1 MMA instructions xxsetaccz, xvi4ger8,
+######  xvf16ger2pn, pmxvi8ger4, and pmxvf32gerpp.  Goal here is to hit all
+######  the places where ppc_record_ACC_fpscr() gets called.
+##
+##       xxsetaccz    - ACC[3], vs[12] to vs[15]
+##       xvi4ger8     - ACC[4], vs[16] to vs[19]
+##       xvf16ger2pn  - ACC[5], vs[20] to vs[23]
+##       pmxvi8ger4   - ACC[6], vs[21] to vs[27]
+##       pmxvf32gerpp - ACC[7], vs[28] to vs[31] and fpscr
+
+set stop3  [gdb_get_line_number "stop 3"]
+set stop4  [gdb_get_line_number "stop 4"]
+
+gdb_test "break $stop3" ".*Breakpoint .*" "about to execute Test 2"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 3"
+
+# Record the initial values of vs's that correspond to the ACC entries,
+# and fpscr.
+set acc_3_0_initial [capture_command_output "info register vs12" ""]
+set acc_3_1_initial [capture_command_output "info register vs13" ""]
+set acc_3_2_initial [capture_command_output "info register vs14" ""]
+set acc_3_3_initial [capture_command_output "info register vs15" ""]
+set acc_4_0_initial [capture_command_output "info register vs16" ""]
+set acc_4_1_initial [capture_command_output "info register vs17" ""]
+set acc_4_2_initial [capture_command_output "info register vs18" ""]
+set acc_4_3_initial [capture_command_output "info register vs19" ""]
+set acc_5_0_initial [capture_command_output "info register vs20" ""]
+set acc_5_1_initial [capture_command_output "info register vs21" ""]
+set acc_5_2_initial [capture_command_output "info register vs22" ""]
+set acc_5_3_initial [capture_command_output "info register vs23" ""]
+set acc_6_0_initial [capture_command_output "info register vs24" ""]
+set acc_6_1_initial [capture_command_output "info register vs25" ""]
+set acc_6_2_initial [capture_command_output "info register vs26" ""]
+set acc_6_3_initial [capture_command_output "info register vs27" ""]
+set acc_7_0_initial [capture_command_output "info register vs28" ""]
+set acc_7_1_initial [capture_command_output "info register vs29" ""]
+set acc_7_2_initial [capture_command_output "info register vs30" ""]
+set acc_7_3_initial [capture_command_output "info register vs31" ""]
+set fpscr_initial [capture_command_output "info register fpscr" ""]
+
+gdb_test "break $stop4" ".*Breakpoint .*" "executed test 2"
+gdb_test "continue"  ".*Breakpoint .*" "At stop 4"
+
+# Record the new values of the ACC entries and fpscr.
+set acc_3_0_new [capture_command_output "info register vs12" ""]
+set acc_3_1_new [capture_command_output "info register vs13" ""]
+set acc_3_2_new [capture_command_output "info register vs14" ""]
+set acc_3_3_new [capture_command_output "info register vs15" ""]
+set acc_4_0_new [capture_command_output "info register vs16" ""]
+set acc_4_1_new [capture_command_output "info register vs17" ""]
+set acc_4_2_new [capture_command_output "info register vs18" ""]
+set acc_4_3_new [capture_command_output "info register vs19" ""]
+set acc_5_0_new [capture_command_output "info register vs20" ""]
+set acc_5_1_new [capture_command_output "info register vs21" ""]
+set acc_5_2_new [capture_command_output "info register vs22" ""]
+set acc_5_3_new [capture_command_output "info register vs23" ""]
+set acc_6_0_new [capture_command_output "info register vs24" ""]
+set acc_6_1_new [capture_command_output "info register vs25" ""]
+set acc_6_2_new [capture_command_output "info register vs26" ""]
+set acc_6_3_new [capture_command_output "info register vs27" ""]
+set acc_7_0_new [capture_command_output "info register vs28" ""]
+set acc_7_1_new [capture_command_output "info register vs29" ""]
+set acc_7_2_new [capture_command_output "info register vs30" ""]
+set acc_7_3_new [capture_command_output "info register vs31" ""]
+set fpscr_new [capture_command_output "info register fpscr" ""]
+
+# Execute in reverse to before test 2.
+gdb_test "set exec-direction reverse" "" "Reverse to start of Test 2"
+
+gdb_test "break $stop3" ".*Breakpoint .*" "reverse stop at test 2 start"
+gdb_test "continue"  ".*Breakpoint.*" "At stop 3 in reverse"
+
+# Record the final values of the ACC entries and fpscr.
+set acc_3_0_final [capture_command_output "info register vs12" ""]
+set acc_3_1_final [capture_command_output "info register vs13" ""]
+set acc_3_2_final [capture_command_output "info register vs14" ""]
+set acc_3_3_final [capture_command_output "info register vs15" ""]
+set acc_4_0_final [capture_command_output "info register vs16" ""]
+set acc_4_1_final [capture_command_output "info register vs17" ""]
+set acc_4_2_final [capture_command_output "info register vs18" ""]
+set acc_4_3_final [capture_command_output "info register vs19" ""]
+set acc_5_0_final [capture_command_output "info register vs20" ""]
+set acc_5_1_final [capture_command_output "info register vs21" ""]
+set acc_5_2_final [capture_command_output "info register vs22" ""]
+set acc_5_3_final [capture_command_output "info register vs23" ""]
+set acc_6_0_final [capture_command_output "info register vs24" ""]
+set acc_6_1_final [capture_command_output "info register vs25" ""]
+set acc_6_2_final [capture_command_output "info register vs26" ""]
+set acc_6_3_final [capture_command_output "info register vs27" ""]
+set acc_7_0_final [capture_command_output "info register vs28" ""]
+set acc_7_1_final [capture_command_output "info register vs29" ""]
+set acc_7_2_final [capture_command_output "info register vs30" ""]
+set acc_7_3_final [capture_command_output "info register vs31" ""]
+set fpscr_final [capture_command_output "info register fpscr" ""]
+
+# check initial and new ACC entries.
+set test_acc_3_0_init_new "check vs12 initial versus new"
+if {[string compare $acc_3_0_initial  $acc_3_0_new ] == 0} {
+    fail $test_acc_3_0_init_new
+} else {
+    pass $test_acc_3_0_init_new
+}
+set test_acc_3_1_init_new "check vs13 initial versus new"
+if {[string compare $acc_3_1_initial  $acc_3_1_new ] == 0} {
+    fail $test_acc_3_1_init_new
+} else {
+    pass $test_acc_3_1_init_new
+}
+set test_acc_3_2_init_new "check vs14 initial versus new"
+if {[string compare $acc_3_2_initial  $acc_3_2_new ] == 0} {
+    fail $test_acc_3_2_init_new
+} else {
+    pass $test_acc_3_2_init_new
+}
+set test_acc_3_3_init_new "check vs15 initial versus new"
+if {[string compare $acc_3_3_initial  $acc_3_3_new ] == 0} {
+    fail $test_acc_3_3_init_new
+} else {
+    pass $test_acc_3_3_init_new
+}
+
+set test_acc_4_0_init_new "check vs16 initial versus new"
+if {[string compare $acc_4_0_initial  $acc_4_0_new ] == 0} {
+    fail $test_acc_4_0_init_new
+} else {
+    pass $test_acc_4_0_init_new
+}
+set test_acc_4_1_init_new "check vs17 initial versus new"
+if {[string compare $acc_4_1_initial  $acc_4_1_new ] == 0} {
+    fail $test_acc_4_1_init_new
+} else {
+    pass $test_acc_4_1_init_new
+}
+set test_acc_4_2_init_new "check vs18 initial versus new"
+if {[string compare $acc_4_2_initial  $acc_4_2_new ] == 0} {
+    fail $test_acc_4_2_init_new
+} else {
+    pass $test_acc_4_2_init_new
+}
+set test_acc_4_3_init_new "check vs19 initial versus new"
+if {[string compare $acc_4_3_initial  $acc_4_3_new ] == 0} {
+    fail $test_acc_4_3_init_new
+} else {
+    pass $test_acc_4_3_init_new
+}
+
+set test_acc_5_0_init_new "check vs20 initial versus new"
+if {[string compare $acc_5_0_initial  $acc_5_0_new ] == 0} {
+    fail $test_acc_5_0_init_new
+} else {
+    pass $test_acc_5_0_init_new
+}
+set test_acc_5_1_init_new "check vs21 initial versus new"
+if {[string compare $acc_5_1_initial  $acc_5_1_new ] == 0} {
+    fail $test_acc_5_1_init_new
+} else {
+    pass $test_acc_5_1_init_new
+}
+set test_acc_5_2_init_new "check vs22 initial versus new"
+if {[string compare $acc_5_2_initial  $acc_5_2_new ] == 0} {
+    fail $test_acc_5_2_init_new
+} else {
+    pass $test_acc_5_2_init_new
+}
+set test_acc_5_3_init_new "check vs23 initial versus new"
+if {[string compare $acc_5_3_initial  $acc_5_3_new ] == 0} {
+    fail $test_acc_5_3_init_new
+} else {
+    pass $test_acc_5_3_init_new
+}
+
+set test_acc_6_0_init_new "check vs24 initial versus new"
+if {[string compare $acc_6_0_initial  $acc_6_0_new ] == 0} {
+    fail $test_acc_6_0_init_new
+} else {
+    pass $test_acc_6_0_init_new
+}
+set test_acc_6_1_init_new "check vs25 initial versus new"
+if {[string compare $acc_6_1_initial  $acc_6_1_new ] == 0} {
+    fail $test_acc_6_1_init_new
+} else {
+    pass $test_acc_6_1_init_new
+}
+set test_acc_6_2_init_new "check vs26 initial versus new"
+if {[string compare $acc_6_2_initial  $acc_6_2_new ] == 0} {
+    fail $test_acc_6_2_init_new
+} else {
+    pass $test_acc_6_2_init_new
+}
+set test_acc_6_3_init_new "check vs27 initial versus new"
+if {[string compare $acc_6_3_initial  $acc_6_3_new ] == 0} {
+    fail $test_acc_6_3_init_new
+} else {
+    pass $test_acc_6_3_init_new
+}
+
+set test_acc_7_0_init_new "check vs28 initial versus new"
+if {[string compare $acc_7_0_initial  $acc_7_0_new ] == 0} {
+    fail $test_acc_7_0_init_new
+} else {
+    pass $test_acc_7_0_init_new
+}
+set test_acc_7_1_init_new "check vs29 initial versus new"
+if {[string compare $acc_7_1_initial  $acc_7_1_new ] == 0} {
+    fail $test_acc_7_1_init_new
+} else {
+    pass $test_acc_7_1_init_new
+}
+set test_acc_7_2_init_new "check vs30 initial versus new"
+if {[string compare $acc_7_2_initial  $acc_7_2_new ] == 0} {
+    fail $test_acc_7_2_init_new
+} else {
+    pass $test_acc_7_2_init_new
+}
+set test_acc_7_3_init_new "check vs31 initial versus new"
+if {[string compare $acc_7_3_initial  $acc_7_3_new ] == 0} {
+    fail $test_acc_7_3_init_new
+} else {
+    pass $test_acc_7_3_init_new
+}
+set test_fpscr_init_new "check fpscr initial versus new"
+if {[string compare $fpscr_initial  $fpscr_new ] == 0} {
+    fail $test_fpscr_init_new
+} else {
+    pass $test_fpscr_init_new
+}
+
+# Check initial and new ACC entries are different.
+set test_acc_3_0_init_final "check vs12 initial versus final"
+if {[string compare $acc_3_0_initial  $acc_3_0_final ] == 0} {
+    pass $test_acc_3_0_init_final
+} else {
+    fail $test_acc_3_0_init_final
+}
+set test_acc_3_1_init_final "check vs13 initial versus final"
+if {[string compare $acc_3_1_initial  $acc_3_1_final ] == 0} {
+    pass $test_acc_3_1_init_final
+} else {
+    fail $test_acc_3_0_init_final
+}
+set test_acc_3_2_init_final "check vs14 initial versus final"
+if {[string compare $acc_3_2_initial  $acc_3_2_final ] == 0} {
+    pass $test_acc_3_2_init_final
+} else {
+    fail $test_acc_3_2_init_final
+}
+set test_acc_3_3_init_final "check vs15 initial versus final"
+if {[string compare $acc_3_3_initial  $acc_3_3_final ] == 0} {
+    pass $test_acc_3_3_init_final
+} else {
+    new $test_acc_3_3_init_final
+}
+
+set test_acc_4_0_init_final "check vs16 initial versus final"
+if {[string compare $acc_4_0_initial  $acc_4_0_final ] == 0} {
+    pass $test_acc_4_0_init_final
+} else {
+    new $test_acc_4_0_init_final
+}
+set test_acc_4_1_init_final "check vs17 initial versus final"
+if {[string compare $acc_4_1_initial  $acc_4_1_final ] == 0} {
+    pass $test_acc_4_1_init_final
+} else {
+    new $test_acc_4_0_init_final
+}
+set test_acc_4_2_init_final "check vs18 initial versus final"
+if {[string compare $acc_4_2_initial  $acc_4_2_final ] == 0} {
+    pass $test_acc_4_2_init_final
+} else {
+    new $test_acc_4_2_init_final
+}
+set test_acc_4_3_init_final "check vs19 initial versus final"
+if {[string compare $acc_4_3_initial  $acc_4_3_final ] == 0} {
+    pass $test_acc_4_3_init_final
+} else {
+    fail $test_acc_4_3_init_final
+}
+
+set test_acc_5_0_init_final "check vs20 initial versus final"
+if {[string compare $acc_5_0_initial  $acc_5_0_final ] == 0} {
+    pass $test_acc_5_0_init_final
+} else {
+    fail $test_acc_5_0_init_final
+}
+set test_acc_5_1_init_final "check vs21 initial versus final"
+if {[string compare $acc_5_1_initial  $acc_5_1_final ] == 0} {
+    pass $test_acc_5_1_init_final
+} else {
+    fail $test_acc_5_0_init_final
+}
+set test_acc_5_2_init_final "check vs22 initial versus final"
+if {[string compare $acc_5_2_initial  $acc_5_2_final ] == 0} {
+    pass $test_acc_5_2_init_final
+} else {
+    fail $test_acc_5_2_init_final
+}
+set test_acc_5_3_init_final "check vs23 initial versus final"
+if {[string compare $acc_5_3_initial  $acc_5_3_final ] == 0} {
+    pass $test_acc_5_3_init_final
+} else {
+    fail $test_acc_5_3_init_final
+}
+
+set test_acc_6_0_init_final "check vs24 initial versus final"
+if {[string compare $acc_6_0_initial  $acc_6_0_final ] == 0} {
+    pass $test_acc_6_0_init_final
+} else {
+    fail $test_acc_6_0_init_final
+}
+set test_acc_6_1_init_final "check vs25 initial versus final"
+if {[string compare $acc_6_1_initial  $acc_6_1_final ] == 0} {
+    pass $test_acc_6_1_init_final
+} else {
+    fail $test_acc_6_0_init_final
+}
+set test_acc_6_2_init_final "check vs26 initial versus final"
+if {[string compare $acc_6_2_initial  $acc_6_2_final ] == 0} {
+    pass $test_acc_6_2_init_final
+} else {
+    fail $test_acc_6_2_init_final
+}
+set test_acc_6_3_init_final "check vs27 initial versus final"
+if {[string compare $acc_6_3_initial  $acc_6_3_final ] == 0} {
+    pass $test_acc_6_3_init_final
+} else {
+    fail $test_acc_6_3_init_final
+}
+
+set test_acc_7_0_init_final "check vs28 initial versus final"
+if {[string compare $acc_7_0_initial  $acc_7_0_final ] == 0} {
+    pass $test_acc_7_0_init_final
+} else {
+    fail $test_acc_7_0_init_final
+}
+set test_acc_7_1_init_final "check vs29 initial versus final"
+if {[string compare $acc_7_1_initial  $acc_7_1_final ] == 0} {
+    pass $test_acc_7_1_init_final
+} else {
+    fail $test_acc_7_0_init_final
+}
+set test_acc_7_2_init_final "check vs30 initial versus final"
+if {[string compare $acc_7_2_initial  $acc_7_2_final ] == 0} {
+    pass $test_acc_7_2_init_final
+} else {
+    fail $test_acc_7_2_init_final
+}
+set test_acc_7_3_init_final "check vs31 initial versus final"
+if {[string compare $acc_7_3_initial  $acc_7_3_final ] == 0} {
+    pass $test_acc_7_3_init_final
+} else {
+    fail $test_acc_7_3_init_final
+}
+set test_fpscr_init_final "check fpscr initial versus final"
+if {[string compare $fpscr_initial  $fpscr_final ] == 0} {
+    pass $test_fpscr_init_final
+} else {
+    fail $test_fpscr_init_final
+}
+
-- 
2.31.1



^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH 2/2 Version 4] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-14 20:20             ` [PATCH 2/2 Version 4] " Carl Love
@ 2022-04-14 20:43               ` Carl Love
  2022-04-17 16:48                 ` Joel Brobecker
  0 siblings, 1 reply; 25+ messages in thread
From: Carl Love @ 2022-04-14 20:43 UTC (permalink / raw)
  To: Pedro Alves, will schmidt, Joel Brobecker, gdb-patches
  Cc: Ulrich Weigand, Tulio Magno, Rogerio Alves, cel

Pedro, Will, Joel:

Ignore previous email.  The changes didn't get added to the file
correctly.

On Thu, 2022-04-14 at 13:20 -0700, Carl Love wrote:
> Pedro, Will, Joel:
> On Thu, 2022-04-14 at 14:05 +0100, Pedro Alves wrote:
> > Hi Carl,
> > 
> > Some nits below.
> 
> Thanks for point out the typos.  I have fixed the typos in both
> files. 
> None of the include files are actually needed, I removed them in both
> files. 
> 
> Please let me know is you see anything else.  Thanks.
> 
> I re-ran the tests on Power 10 to make sure I didn't break anything.

The following is the updated patch.  Sorry for the confusion.

                     Carl 

-------------------------------------------------------
GDB Powerpc record test cases for ISA 2.06 and ISA 3.1

This patch adds Powerpc specific tests to verify recording of various
instructions.  The first test case checks the ISA 2.06 lxvd2x instruction.
The second test case tests several of the ISA 3.01 instructions.  Specifically,
it checks the word and prefixed instructions and some of the Matrix
Multiply Assist (MMA) instructions.

The patch has been run on both Power 10 and Power 9 to verify the ISA
2.06 test case runs on both platforms without errors.  The ISA 3.1 test
runs without errors on Power 10 and is skipped as expected on Power 9.
---
 .../gdb.reverse/ppc_record_test_isa_2_06.c    |  39 ++
 .../gdb.reverse/ppc_record_test_isa_2_06.exp  | 120 +++++
 .../gdb.reverse/ppc_record_test_isa_3_1.c     |  95 ++++
 .../gdb.reverse/ppc_record_test_isa_3_1.exp   | 492 ++++++++++++++++++
 4 files changed, 746 insertions(+)
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp

diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
new file mode 100644
index 00000000000..45e58413da2
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
@@ -0,0 +1,39 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* globals used for vector tests */
+static vector unsigned long vec_xb;
+static unsigned long ra, rb, rs;
+
+int
+main ()
+{
+  ra = 0xABCDEF012;
+  rb = 0;
+  rs = 0x012345678;
+
+  /* 9.0, 16.0, 25.0, 36.0 */
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+
+  /* Test ISA 2.06 instructions.  Load source into vs1, result of sqrt
+     put into vs0.  */
+  ra = (unsigned long) & vec_xb;        /* stop 1 */
+  __asm__ __volatile__ ("lxvd2x 1, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("xvsqrtsp 0, 1");
+  ra = 0;                               /* stop 2 */
+}
+
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
new file mode 100644
index 00000000000..8ba8c1720ec
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
@@ -0,0 +1,120 @@
+# Copyright 2008-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Test instruction record for PowerPC, ISA 2.06.
+#
+
+# The basic flow of the record tests are:
+#    1) Stop before executing the instructions of interest.  Record
+#       the initial value of the registers that the instruction will
+#       change, i.e. the destination register.
+#    2) Execute the instructions.  Record the new value of the
+#       registers that changed.
+#    3) Reverse the direction of the execution and execute back to
+#       just before the instructions of interest.  Record the final
+#       value of the registers of interest.
+#    4) Check that the initial and new values of the registers are
+#       different, i.e. the instruction changed the registers as expected.
+#    5) Check that the initial and final values of the registers are
+#       the same, i.e. gdb record restored the registers to their
+#       original values.
+
+standard_testfile
+
+set gen_src record_test_isa_2_06.c
+set executable record_test_isa_2_06
+set options [list debug]
+
+if {![istarget "powerpc*"]} then  {
+    verbose "Skipping PowerPC ISA 2.06 instruction record_test_2_06."
+    return
+}
+
+if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
+    return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] then {
+    untested "could not run to main"
+    continue
+}
+
+gdb_test_no_output "record"
+
+###### Test: Test an ISA 2.06 load (lxvd2x) and square root instruction
+###### (xvsqrtsp).  The load instruction will load vs1.  The sqrt instruction
+###### will put its result into vs0.
+
+set stop1 [gdb_get_line_number "stop 1"]
+set stop2 [gdb_get_line_number "stop 2"]
+
+gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test"
+gdb_test "continue"  ".*Breakpoint .*" "at stop 1"
+
+# Record the initial values in vs0, vs1.
+set vs0_initial [capture_command_output "info register vs0" ""]
+set vs1_initial [capture_command_output "info register vs1" ""]
+
+gdb_test "break $stop2" ".*Breakpoint .*" "executed lxvd2x, xvsqrtsp"
+gdb_test "continue"  ".*Breakpoint .*" "at stop 2"
+
+# Record the new values of vs0 and vs1.
+set vs0_new [capture_command_output "info register vs0" ""]
+set vs1_new [capture_command_output "info register vs1" ""]
+
+# Reverse the execution direction. 
+gdb_test_no_output "set exec-direction reverse"
+gdb_test "break $stop1" ".*Breakpoint .*" "un executed lxvd2x, xvsqrtsp"
+
+# Execute in reverse to before the lxvd2x instruction.
+gdb_test "continue"  ".*Breakpoint.*" "at stop 1 in reverse"
+
+# Record the final values of vs0, vs1.
+set vs0_final [capture_command_output "info register vs0" ""]
+set vs1_final [capture_command_output "info register vs1" ""]
+
+# Check initial and new of vs0 are different.
+set test_vs0_init_new "check vs0 initial versus vs0 new"
+if {[string compare $vs0_initial $vs0_new] == 0} {
+    fail $test_vs0_init_new
+} else {
+    pass $test_vs0_init_new
+}
+
+# Check initial and new of vs1 are different.
+set test_vs1_init_new "check vs0 initial versus vs1 new"
+if {[string compare $vs1_initial $vs1_new] == 0} {
+    fail $test_vs1_init_new
+} else {
+    pass $test_vs1_init_new
+}
+
+# Check initial and final are the same.
+set test_vs0_init_final "check vs0 initial versus vs0 final"
+if {[string compare $vs0_initial $vs0_final] == 0} {
+    pass $test_vs0_init_final
+} else {
+    fail $test_vs0_init_final
+}
+
+# Check initial and final are the same.
+set test_vs1_init_final "check vs1 initial versus vs1 final"
+if {[string compare $vs1_initial $vs1_final] == 0} {
+    pass $test_vs1_init_final
+} else {
+    fail $test_vs1_init_final
+}
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
new file mode 100644
index 00000000000..c0d65d944af
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
@@ -0,0 +1,95 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Globals used for vector tests.  */
+static vector unsigned long vec_xa, vec_xb, vec_xt;
+static unsigned long ra, rb, rs;
+
+int
+main ()
+{
+  ra = 0xABCDEF012;
+  rb = 0;
+  rs = 0x012345678;
+
+  /* 9.0, 16.0, 25.0, 36.0 */
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+
+  vec_xt = (vector unsigned long){0xFF00FF00FF00FF00, 0xAA00AA00AA00AA00};
+
+  /* Test 1, ISA 3.1 word instructions. Load source into r1, result of brh
+     put in r0.  */
+  ra = 0xABCDEF012;                     /* stop 1 */
+  __asm__ __volatile__ ("pld 1, %0" :: "r" (ra ));
+  __asm__ __volatile__ ("brh 0, 1" );
+  ra = 0;                               /* stop 2 */
+
+  /* Test 2, ISA 3.1 MMA instructions with results in various ACC entries
+     xxsetaccz    - ACC[3]
+     xvi4ger8     - ACC[4]
+     xvf16ger2pn  - ACC[5]
+     pmxvi8ger4   - ACC[6]
+     pmxvf32gerpp - ACC[7] and fpscr */
+  /* Need to initialize the vs registers to a non zero value.  */
+  ra = (unsigned long) & vec_xb;
+  __asm__ __volatile__ ("lxvd2x 12, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 13, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 14, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 15, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xa = (vector unsigned long){0x333134343987601, 0x9994bbbc9983307};
+  vec_xb = (vector unsigned long){0x411234041898760, 0x41c833042103400};
+  __asm__ __volatile__ ("lxvd2x 16, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x123456789987650, 0x235676546989807};
+  __asm__ __volatile__ ("lxvd2x 17, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x878363439823470, 0x413434c99839870};
+  __asm__ __volatile__ ("lxvd2x 18, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x043765434398760, 0x419876555558850};
+  __asm__ __volatile__ ("lxvd2x 19, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x33313434398760, 0x9994bbbc99899330};
+  __asm__ __volatile__ ("lxvd2x 20, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 21, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 22, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 23, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 24, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 25, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 26, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 27, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xa = (vector unsigned long){0x33313434398760, 0x9994bbbc998330};
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+  __asm__ __volatile__ ("lxvd2x 28, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x4567000046800000, 0x4458000048700000};
+  __asm__ __volatile__ ("lxvd2x 29, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x41dd000041e00000, 0x41c8000046544400};
+  __asm__ __volatile__ ("lxvd2x 30, %0, %1" :: "r" (ra ), "r" (rb));
+
+  /* SNAN */
+  vec_xb = (vector unsigned long){0x7F8F00007F8F0000, 0x7F8F00007F8F0000};
+
+  __asm__ __volatile__ ("lxvd2x 31, %0, %1" :: "r" (ra ), "r" (rb));
+
+  ra = 0xAB;                            /* stop 3 */
+  __asm__ __volatile__ ("xxsetaccz 3");
+  __asm__ __volatile__ ("xvi4ger8 4, %x0, %x1" :: "wa" (vec_xa), \
+			"wa" (vec_xb) );
+  __asm__ __volatile__ ("xvf16ger2pn 5, %x0, %x1" :: "wa" (vec_xa),\
+			"wa" (vec_xb) );
+  __asm__ __volatile__ ("pmxvi8ger4spp  6, %x0, %x1, 11, 13, 5"
+                                :: "wa" (vec_xa), "wa" (vec_xb) );
+  __asm__ __volatile__ ("pmxvf32gerpp  7, %x0, %x1, 11, 13"
+                                :: "wa" (vec_xa), "wa" (vec_xb) );
+  ra = 0;                               /* stop 4 */
+}
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
new file mode 100644
index 00000000000..07133c094ea
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
@@ -0,0 +1,492 @@
+# Copyright 2008-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Test instruction record for PowerPC, ISA 3.1.
+#
+
+# The basic flow of the record tests are:
+#    1) Stop before executing the instructions of interest.  Record
+#       the initial value of the registers that the instruction will
+#       change, i.e. the destination register.
+#    2) Execute the instructions.  Record the new value of the
+#       registers that changed.
+#    3) Reverse the direction of the execution and execute back to
+#       just before the instructions of interest.  Record the final
+#       value of the registers of interest.
+#    4) Check that the initial and new values of the registers are
+#       different, i.e. the instruction changed the registers as expected.
+#    5) Check that the initial and final values of the registers are
+#       the same, i.e. gdb record restored the registers to their
+#       original values.
+
+
+standard_testfile
+
+set gen_src record_test_isa_3_1.c
+set executable record_test_isa_3_1
+
+if {![istarget "powerpc*"] || [skip_power_isa_3_1_tests] } then  {
+    verbose "Skipping Powerpc ISA 3.1 instruction record_test."
+    return
+}
+
+set options [list additional_flags=-mcpu=power10 debug]
+if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
+    return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] then {
+    untested "could not run to main"
+    continue
+}
+
+gdb_test_no_output "record"
+
+######  Test 1:  Test an ISA 3.1 byte reverse word instruction (brd) and a
+######   prefixed load double (pld) instruction.
+set stop1 [gdb_get_line_number "stop 1"]
+set stop2 [gdb_get_line_number "stop 2"]
+
+gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test 1"
+gdb_test "continue"  ".*Breakpoint .*" "at stop 1"
+
+# Record the initial values in r0, r1
+# Load the argument into r1, result of byte reverse is put into r0.
+set r0_initial [capture_command_output "info register r0" ""]
+set r1_initial [capture_command_output "info register r1" ""]
+
+gdb_test "break $stop2" ".*Breakpoint .*" "executed test 1"
+gdb_test "continue"  ".*Breakpoint .*" "at stop 2"
+
+# Record the new values of r0 and r1
+set r0_new [capture_command_output "info register r0" ""]
+set r1_new [capture_command_output "info register r1" ""]
+
+# Execute in reverse to before test 1
+gdb_test "set exec-direction reverse" "" "reverse to start of test 1"
+#gdb_test_no_output "set exec-direction reverse"
+
+gdb_test "break $stop1" ".*Breakpoint .*" "reverse stop at test 1 start"
+gdb_test "continue"  ".*Breakpoint.*" "at stop 1 in reverse"
+
+# Record the final values of r0, r1
+set r0_final [capture_command_output "info register r0" ""]
+set r1_final [capture_command_output "info register r1" ""]
+
+# Check initial and new of r0 are different.
+set test_r0_init_new "check r0 initial versus r0 new"
+if {[string compare $r0_initial $r0_new] == 0} {
+    fail $test_r0_init_new
+} else {
+    pass $test_r0_init_new
+}
+
+# Check initial and new of r1 are different.
+set test_r1_init_new "check r0 initial versus r1 new"
+if {[string compare $r1_initial $r1_new] == 0} {
+    fail $test_r1_init_new
+} else {
+    pass $test_r1_init_new
+}
+
+# Check initial and final are the same.
+set test_r0_init_final "check r0 initial versus r0 final"
+if {[string compare $r0_initial $r0_final] == 0} {
+    pass $test_r0_init_final
+} else {
+    fail $test_r0_init_final
+}
+
+# Check initial and final are the same.
+set test_r1_init_final "check r1 initial versus r1 final"
+if {[string compare $r1_initial $r1_final] == 0} {
+    pass $test_r1_init_final
+} else {
+    fail $test_r1_init_final
+}
+
+
+# Change execution direction to forward for next test.
+gdb_test "set exec-direction forward" "" "start forward test3"
+gdb_test "record stop" ".*Process record is stopped.*" "stopped recording 2"
+set test_del_bkpts "delete breakpoints, answer prompt 2"
+
+# Delete all breakpoints and catchpoints.
+delete_breakpoints
+
+gdb_test "record" "" "start recording test2"
+
+
+######  Test 2:  Test the ISA 3.1 MMA instructions xxsetaccz, xvi4ger8,
+######  xvf16ger2pn, pmxvi8ger4, and pmxvf32gerpp.  Goal here is to hit all
+######  the places where ppc_record_ACC_fpscr() gets called.
+##
+##       xxsetaccz    - ACC[3], vs[12] to vs[15]
+##       xvi4ger8     - ACC[4], vs[16] to vs[19]
+##       xvf16ger2pn  - ACC[5], vs[20] to vs[23]
+##       pmxvi8ger4   - ACC[6], vs[21] to vs[27]
+##       pmxvf32gerpp - ACC[7], vs[28] to vs[31] and fpscr
+
+set stop3 [gdb_get_line_number "stop 3"]
+set stop4 [gdb_get_line_number "stop 4"]
+
+gdb_test "break $stop3" ".*Breakpoint .*" "about to execute test 2"
+gdb_test "continue"  ".*Breakpoint .*" "at stop 3"
+
+# Record the initial values of vs's that correspond to the ACC entries,
+# and fpscr.
+set acc_3_0_initial [capture_command_output "info register vs12" ""]
+set acc_3_1_initial [capture_command_output "info register vs13" ""]
+set acc_3_2_initial [capture_command_output "info register vs14" ""]
+set acc_3_3_initial [capture_command_output "info register vs15" ""]
+set acc_4_0_initial [capture_command_output "info register vs16" ""]
+set acc_4_1_initial [capture_command_output "info register vs17" ""]
+set acc_4_2_initial [capture_command_output "info register vs18" ""]
+set acc_4_3_initial [capture_command_output "info register vs19" ""]
+set acc_5_0_initial [capture_command_output "info register vs20" ""]
+set acc_5_1_initial [capture_command_output "info register vs21" ""]
+set acc_5_2_initial [capture_command_output "info register vs22" ""]
+set acc_5_3_initial [capture_command_output "info register vs23" ""]
+set acc_6_0_initial [capture_command_output "info register vs24" ""]
+set acc_6_1_initial [capture_command_output "info register vs25" ""]
+set acc_6_2_initial [capture_command_output "info register vs26" ""]
+set acc_6_3_initial [capture_command_output "info register vs27" ""]
+set acc_7_0_initial [capture_command_output "info register vs28" ""]
+set acc_7_1_initial [capture_command_output "info register vs29" ""]
+set acc_7_2_initial [capture_command_output "info register vs30" ""]
+set acc_7_3_initial [capture_command_output "info register vs31" ""]
+set fpscr_initial [capture_command_output "info register fpscr" ""]
+
+gdb_test "break $stop4" ".*Breakpoint .*" "executed test 2"
+gdb_test "continue"  ".*Breakpoint .*" "at stop 4"
+
+# Record the new values of the ACC entries and fpscr.
+set acc_3_0_new [capture_command_output "info register vs12" ""]
+set acc_3_1_new [capture_command_output "info register vs13" ""]
+set acc_3_2_new [capture_command_output "info register vs14" ""]
+set acc_3_3_new [capture_command_output "info register vs15" ""]
+set acc_4_0_new [capture_command_output "info register vs16" ""]
+set acc_4_1_new [capture_command_output "info register vs17" ""]
+set acc_4_2_new [capture_command_output "info register vs18" ""]
+set acc_4_3_new [capture_command_output "info register vs19" ""]
+set acc_5_0_new [capture_command_output "info register vs20" ""]
+set acc_5_1_new [capture_command_output "info register vs21" ""]
+set acc_5_2_new [capture_command_output "info register vs22" ""]
+set acc_5_3_new [capture_command_output "info register vs23" ""]
+set acc_6_0_new [capture_command_output "info register vs24" ""]
+set acc_6_1_new [capture_command_output "info register vs25" ""]
+set acc_6_2_new [capture_command_output "info register vs26" ""]
+set acc_6_3_new [capture_command_output "info register vs27" ""]
+set acc_7_0_new [capture_command_output "info register vs28" ""]
+set acc_7_1_new [capture_command_output "info register vs29" ""]
+set acc_7_2_new [capture_command_output "info register vs30" ""]
+set acc_7_3_new [capture_command_output "info register vs31" ""]
+set fpscr_new [capture_command_output "info register fpscr" ""]
+
+# Execute in reverse to before test 2.
+gdb_test "set exec-direction reverse" "" "reverse to start of test 2"
+
+gdb_test "break $stop3" ".*Breakpoint .*" "reverse stop at test 2 start"
+gdb_test "continue"  ".*Breakpoint.*" "at stop 3 in reverse"
+
+# Record the final values of the ACC entries and fpscr.
+set acc_3_0_final [capture_command_output "info register vs12" ""]
+set acc_3_1_final [capture_command_output "info register vs13" ""]
+set acc_3_2_final [capture_command_output "info register vs14" ""]
+set acc_3_3_final [capture_command_output "info register vs15" ""]
+set acc_4_0_final [capture_command_output "info register vs16" ""]
+set acc_4_1_final [capture_command_output "info register vs17" ""]
+set acc_4_2_final [capture_command_output "info register vs18" ""]
+set acc_4_3_final [capture_command_output "info register vs19" ""]
+set acc_5_0_final [capture_command_output "info register vs20" ""]
+set acc_5_1_final [capture_command_output "info register vs21" ""]
+set acc_5_2_final [capture_command_output "info register vs22" ""]
+set acc_5_3_final [capture_command_output "info register vs23" ""]
+set acc_6_0_final [capture_command_output "info register vs24" ""]
+set acc_6_1_final [capture_command_output "info register vs25" ""]
+set acc_6_2_final [capture_command_output "info register vs26" ""]
+set acc_6_3_final [capture_command_output "info register vs27" ""]
+set acc_7_0_final [capture_command_output "info register vs28" ""]
+set acc_7_1_final [capture_command_output "info register vs29" ""]
+set acc_7_2_final [capture_command_output "info register vs30" ""]
+set acc_7_3_final [capture_command_output "info register vs31" ""]
+set fpscr_final [capture_command_output "info register fpscr" ""]
+
+# check initial and new ACC entries.
+set test_acc_3_0_init_new "check vs12 initial versus new"
+if {[string compare $acc_3_0_initial $acc_3_0_new] == 0} {
+    fail $test_acc_3_0_init_new
+} else {
+    pass $test_acc_3_0_init_new
+}
+set test_acc_3_1_init_new "check vs13 initial versus new"
+if {[string compare $acc_3_1_initial $acc_3_1_new] == 0} {
+    fail $test_acc_3_1_init_new
+} else {
+    pass $test_acc_3_1_init_new
+}
+set test_acc_3_2_init_new "check vs14 initial versus new"
+if {[string compare $acc_3_2_initial $acc_3_2_new] == 0} {
+    fail $test_acc_3_2_init_new
+} else {
+    pass $test_acc_3_2_init_new
+}
+set test_acc_3_3_init_new "check vs15 initial versus new"
+if {[string compare $acc_3_3_initial $acc_3_3_new] == 0} {
+    fail $test_acc_3_3_init_new
+} else {
+    pass $test_acc_3_3_init_new
+}
+
+set test_acc_4_0_init_new "check vs16 initial versus new"
+if {[string compare $acc_4_0_initial $acc_4_0_new] == 0} {
+    fail $test_acc_4_0_init_new
+} else {
+    pass $test_acc_4_0_init_new
+}
+set test_acc_4_1_init_new "check vs17 initial versus new"
+if {[string compare $acc_4_1_initial $acc_4_1_new] == 0} {
+    fail $test_acc_4_1_init_new
+} else {
+    pass $test_acc_4_1_init_new
+}
+set test_acc_4_2_init_new "check vs18 initial versus new"
+if {[string compare $acc_4_2_initial $acc_4_2_new] == 0} {
+    fail $test_acc_4_2_init_new
+} else {
+    pass $test_acc_4_2_init_new
+}
+set test_acc_4_3_init_new "check vs19 initial versus new"
+if {[string compare $acc_4_3_initial $acc_4_3_new] == 0} {
+    fail $test_acc_4_3_init_new
+} else {
+    pass $test_acc_4_3_init_new
+}
+
+set test_acc_5_0_init_new "check vs20 initial versus new"
+if {[string compare $acc_5_0_initial $acc_5_0_new] == 0} {
+    fail $test_acc_5_0_init_new
+} else {
+    pass $test_acc_5_0_init_new
+}
+set test_acc_5_1_init_new "check vs21 initial versus new"
+if {[string compare $acc_5_1_initial $acc_5_1_new] == 0} {
+    fail $test_acc_5_1_init_new
+} else {
+    pass $test_acc_5_1_init_new
+}
+set test_acc_5_2_init_new "check vs22 initial versus new"
+if {[string compare $acc_5_2_initial $acc_5_2_new] == 0} {
+    fail $test_acc_5_2_init_new
+} else {
+    pass $test_acc_5_2_init_new
+}
+set test_acc_5_3_init_new "check vs23 initial versus new"
+if {[string compare $acc_5_3_initial $acc_5_3_new] == 0} {
+    fail $test_acc_5_3_init_new
+} else {
+    pass $test_acc_5_3_init_new
+}
+
+set test_acc_6_0_init_new "check vs24 initial versus new"
+if {[string compare $acc_6_0_initial $acc_6_0_new] == 0} {
+    fail $test_acc_6_0_init_new
+} else {
+    pass $test_acc_6_0_init_new
+}
+set test_acc_6_1_init_new "check vs25 initial versus new"
+if {[string compare $acc_6_1_initial $acc_6_1_new] == 0} {
+    fail $test_acc_6_1_init_new
+} else {
+    pass $test_acc_6_1_init_new
+}
+set test_acc_6_2_init_new "check vs26 initial versus new"
+if {[string compare $acc_6_2_initial $acc_6_2_new] == 0} {
+    fail $test_acc_6_2_init_new
+} else {
+    pass $test_acc_6_2_init_new
+}
+set test_acc_6_3_init_new "check vs27 initial versus new"
+if {[string compare $acc_6_3_initial $acc_6_3_new] == 0} {
+    fail $test_acc_6_3_init_new
+} else {
+    pass $test_acc_6_3_init_new
+}
+
+set test_acc_7_0_init_new "check vs28 initial versus new"
+if {[string compare $acc_7_0_initial $acc_7_0_new] == 0} {
+    fail $test_acc_7_0_init_new
+} else {
+    pass $test_acc_7_0_init_new
+}
+set test_acc_7_1_init_new "check vs29 initial versus new"
+if {[string compare $acc_7_1_initial $acc_7_1_new] == 0} {
+    fail $test_acc_7_1_init_new
+} else {
+    pass $test_acc_7_1_init_new
+}
+set test_acc_7_2_init_new "check vs30 initial versus new"
+if {[string compare $acc_7_2_initial $acc_7_2_new] == 0} {
+    fail $test_acc_7_2_init_new
+} else {
+    pass $test_acc_7_2_init_new
+}
+set test_acc_7_3_init_new "check vs31 initial versus new"
+if {[string compare $acc_7_3_initial $acc_7_3_new] == 0} {
+    fail $test_acc_7_3_init_new
+} else {
+    pass $test_acc_7_3_init_new
+}
+set test_fpscr_init_new "check fpscr initial versus new"
+if {[string compare $fpscr_initial $fpscr_new] == 0} {
+    fail $test_fpscr_init_new
+} else {
+    pass $test_fpscr_init_new
+}
+
+# Check initial and new ACC entries are different.
+set test_acc_3_0_init_final "check vs12 initial versus final"
+if {[string compare $acc_3_0_initial $acc_3_0_final] == 0} {
+    pass $test_acc_3_0_init_final
+} else {
+    fail $test_acc_3_0_init_final
+}
+set test_acc_3_1_init_final "check vs13 initial versus final"
+if {[string compare $acc_3_1_initial $acc_3_1_final] == 0} {
+    pass $test_acc_3_1_init_final
+} else {
+    fail $test_acc_3_0_init_final
+}
+set test_acc_3_2_init_final "check vs14 initial versus final"
+if {[string compare $acc_3_2_initial $acc_3_2_final] == 0} {
+    pass $test_acc_3_2_init_final
+} else {
+    fail $test_acc_3_2_init_final
+}
+set test_acc_3_3_init_final "check vs15 initial versus final"
+if {[string compare $acc_3_3_initial $acc_3_3_final] == 0} {
+    pass $test_acc_3_3_init_final
+} else {
+    new $test_acc_3_3_init_final
+}
+
+set test_acc_4_0_init_final "check vs16 initial versus final"
+if {[string compare $acc_4_0_initial $acc_4_0_final] == 0} {
+    pass $test_acc_4_0_init_final
+} else {
+    new $test_acc_4_0_init_final
+}
+set test_acc_4_1_init_final "check vs17 initial versus final"
+if {[string compare $acc_4_1_initial $acc_4_1_final] == 0} {
+    pass $test_acc_4_1_init_final
+} else {
+    new $test_acc_4_0_init_final
+}
+set test_acc_4_2_init_final "check vs18 initial versus final"
+if {[string compare $acc_4_2_initial $acc_4_2_final] == 0} {
+    pass $test_acc_4_2_init_final
+} else {
+    new $test_acc_4_2_init_final
+}
+set test_acc_4_3_init_final "check vs19 initial versus final"
+if {[string compare $acc_4_3_initial $acc_4_3_final] == 0} {
+    pass $test_acc_4_3_init_final
+} else {
+    fail $test_acc_4_3_init_final
+}
+
+set test_acc_5_0_init_final "check vs20 initial versus final"
+if {[string compare $acc_5_0_initial $acc_5_0_final] == 0} {
+    pass $test_acc_5_0_init_final
+} else {
+    fail $test_acc_5_0_init_final
+}
+set test_acc_5_1_init_final "check vs21 initial versus final"
+if {[string compare $acc_5_1_initial $acc_5_1_final] == 0} {
+    pass $test_acc_5_1_init_final
+} else {
+    fail $test_acc_5_0_init_final
+}
+set test_acc_5_2_init_final "check vs22 initial versus final"
+if {[string compare $acc_5_2_initial $acc_5_2_final] == 0} {
+    pass $test_acc_5_2_init_final
+} else {
+    fail $test_acc_5_2_init_final
+}
+set test_acc_5_3_init_final "check vs23 initial versus final"
+if {[string compare $acc_5_3_initial $acc_5_3_final] == 0} {
+    pass $test_acc_5_3_init_final
+} else {
+    fail $test_acc_5_3_init_final
+}
+
+set test_acc_6_0_init_final "check vs24 initial versus final"
+if {[string compare $acc_6_0_initial $acc_6_0_final] == 0} {
+    pass $test_acc_6_0_init_final
+} else {
+    fail $test_acc_6_0_init_final
+}
+set test_acc_6_1_init_final "check vs25 initial versus final"
+if {[string compare $acc_6_1_initial $acc_6_1_final] == 0} {
+    pass $test_acc_6_1_init_final
+} else {
+    fail $test_acc_6_0_init_final
+}
+set test_acc_6_2_init_final "check vs26 initial versus final"
+if {[string compare $acc_6_2_initial $acc_6_2_final] == 0} {
+    pass $test_acc_6_2_init_final
+} else {
+    fail $test_acc_6_2_init_final
+}
+set test_acc_6_3_init_final "check vs27 initial versus final"
+if {[string compare $acc_6_3_initial $acc_6_3_final] == 0} {
+    pass $test_acc_6_3_init_final
+} else {
+    fail $test_acc_6_3_init_final
+}
+
+set test_acc_7_0_init_final "check vs28 initial versus final"
+if {[string compare $acc_7_0_initial $acc_7_0_final] == 0} {
+    pass $test_acc_7_0_init_final
+} else {
+    fail $test_acc_7_0_init_final
+}
+set test_acc_7_1_init_final "check vs29 initial versus final"
+if {[string compare $acc_7_1_initial $acc_7_1_final] == 0} {
+    pass $test_acc_7_1_init_final
+} else {
+    fail $test_acc_7_0_init_final
+}
+set test_acc_7_2_init_final "check vs30 initial versus final"
+if {[string compare $acc_7_2_initial $acc_7_2_final] == 0} {
+    pass $test_acc_7_2_init_final
+} else {
+    fail $test_acc_7_2_init_final
+}
+set test_acc_7_3_init_final "check vs31 initial versus final"
+if {[string compare $acc_7_3_initial $acc_7_3_final] == 0} {
+    pass $test_acc_7_3_init_final
+} else {
+    fail $test_acc_7_3_init_final
+}
+set test_fpscr_init_final "check fpscr initial versus final"
+if {[string compare $fpscr_initial $fpscr_final] == 0} {
+    pass $test_fpscr_init_final
+} else {
+    fail $test_fpscr_init_final
+}
+
-- 
2.31.1



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/2  Version 3] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-13 17:26         ` [PATCH 1/2 Version 3] " Carl Love
@ 2022-04-17 16:23           ` Joel Brobecker
  2022-04-18 19:21             ` [PATCH 1/2 Version 5] " Carl Love
  0 siblings, 1 reply; 25+ messages in thread
From: Joel Brobecker @ 2022-04-17 16:23 UTC (permalink / raw)
  To: Carl Love
  Cc: will schmidt, Joel Brobecker, gdb-patches, Ulrich Weigand,
	Tulio Magno, Rogerio Alves

On Wed, Apr 13, 2022 at 10:26:47AM -0700, Carl Love wrote:

> Add recording support for the ISA 3.1 Powerpc instructions.

Thanks for the updated version. I have a few more requests of
a trivial natural (Coding Style, and I apologize if this is a bit
frustrating for you - I wish we had a tool like in python that
we could use to just automate the whole thing...).

> diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
> index 44828bcff6d..31a86b902c7 100644
> --- a/gdb/rs6000-tdep.c
> +++ b/gdb/rs6000-tdep.c
> @@ -4123,8 +4123,25 @@ bfd_uses_spe_extensions (bfd *abfd)
>  #define PPC_LEV(insn)	PPC_FIELD (insn, 20, 7)
>  
>  #define PPC_XT(insn)	((PPC_TX (insn) << 5) | PPC_T (insn))
> +#define PPC_XTp(insn)	((PPC_BIT (insn, 10) << 5)	\
> +			 | PPC_FIELD (insn, 6, 4) << 1)
> +#define PPC_XSp(insn)	((PPC_BIT (insn, 10) << 5)	\
> +			 | PPC_FIELD (insn, 6, 4) << 1)
>  #define PPC_XER_NB(xer)	(xer & 0x7f)
>  
> +/* The following macros are for the prefixed instructions.  */
> +#define P_PPC_D(insn_prefix, insn_suffix) \
> +  PPC_SEXT (PPC_FIELD (insn_prefix, 14, 18) << 16 \
> +	    | PPC_FIELD (insn_suffix, 16, 16), 34)
> +#define P_PPC_TX5(insn_sufix)	PPC_BIT (insn_suffix, 5)
> +#define P_PPC_TX15(insn_suffix) PPC_BIT (insn_suffix, 15)
> +#define P_PPC_XT(insn_suffix)	((PPC_TX (insn_suffix) << 5) \
> +				 | PPC_T (insn_suffix))
> +#define P_PPC_XT5(insn_suffix) ((P_PPC_TX5 (insn_suffix) << 5) \
> +				| PPC_T (insn_suffix))
> +#define P_PPC_XT15(insn_suffix) \
> +  ((P_PPC_TX15 (insn_suffix) << 5) | PPC_T (insn_suffix))
> +
>  /* Record Vector-Scalar Registers.
>     For VSR less than 32, it's represented by an FPR and an VSR-upper register.
>     Otherwise, it's just a VR register.  Record them accordingly.  */
> @@ -4152,6 +4169,63 @@ ppc_record_vsr (struct regcache *regcache, ppc_gdbarch_tdep *tdep, int vsr)
>    return 0;
>  }
>  
> +/* The ppc_record_ACC_fpscr() records te changes to the floating point

Small typo: "te" -> "the".

> +   registers modified by a floating point instruction.  Some of the
> +   instructions also update one of the condition code fields in the
> +   "Floating-Point Status and Control Register" (FPSCR).   The RECORD_FPSCR

(small, since we're making changes in this area...) there is one too
many spaces at the end of the period (3 instead of 2).

> +   or DO_NOT_RECORD_FPSCR arguments to the function specifies if the
> +   instruction modifies the FPSCR or not and thus it also needs to be recorded.
> +   Return 0 on success.  */
> +
> +#define RECORD_FPSCR 1
> +#define DO_NOT_RECORD_FPSCR 0
> +
> +static int
> +ppc_record_ACC_fpscr (struct regcache *regcache, ppc_gdbarch_tdep *tdep,
> +		      int at, int save_fpscr)
> +{

The last sentence of the function's description, about RECORD_FPSCR
and DO_NOT_RECORD_FPSCR do not really make sense to me, since those
two are not arguments of the function.

I would simply describe what the values of "at" and "save_fpscr" mean.

> +  int i;
> +  if (at < 0 || at >= 8)
> +    return -1;
> +
> +  /* The ACC register file consists of 8 register entries, each register
> +     entry consist of four 128-bit rows.
> +
> +     The ACC rows map to specific VSR registers.
> +         ACC[0][0] -> VSR[0]
> +         ACC[0][1] -> VSR[1]
> +         ACC[0][2] -> VSR[2]
> +         ACC[0][3] -> VSR[3]
> +              ...
> +         ACC[7][0] -> VSR[28]
> +         ACC[7][1] -> VSR[29]
> +         ACC[7][2] -> VSR[30]
> +         ACC[7][3] -> VSR[31]
> +
> +     NOTE:
> +     In ISA 3.1 the ACC is mapped on top of VSR[0] thru VSR[31].
> +
> +     In the future, the ACC may be implemented as an independent register file
> +     rather than mapping on top of the VSRs.  This will then require the ACC to
> +     be assigned its own register number and the ptrace interface to be able
> +     access the ACC.  Note the ptrace interface for the ACC will also need to
> +     be implemented.  */
> +
> +  /* ACC maps over the same VSR space as the fp registers.  */
> +  for (i = 0; i<4; i++)

Coding style: Can you include spaces around binary operators
(the less-than operator). It should be:

   for (i = 0; i < 4; i++)


> +    {
> +      record_full_arch_list_add_reg (regcache, tdep->ppc_fp0_regnum
> +				     + at*4 + i);

Same here, for the multiply operator: + at * 4 + i

(can you check the rest of your patch for more instances of this,
please?)

No further comments past this point.

> +      record_full_arch_list_add_reg (regcache,
> +				     tdep->ppc_vsr0_upper_regnum + at*4 + i);
> +    }
> +
> +  if (save_fpscr)
> +    record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
> +
> +  return 0;
> +}
> +
>  /* Parse and record instructions primary opcode-4 at ADDR.
>     Return 0 if successful.  */
>  
> @@ -4171,9 +4245,34 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 41:		/* Vector Multiply-Sum Signed Halfword Saturate */
>        record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
>        /* FALL-THROUGH */
> +    case 20:		/* Move To VSR Byte Mask Immediate opcode, b2 = 0,
> +			   ignore bit 31 */
> +    case 21:		/* Move To VSR Byte Mask Immediate opcode, b2 = 1,
> +			   ignore bit 31 */
> +    case 23:		/* Vector Multiply-Sum & write Carry-out Unsigned
> +			   Doubleword */
> +    case 24:		/* Vector Extract Double Unsigned Byte to VSR
> +			   using GPR-specified Left-Index */
> +    case 25:		/* Vector Extract Double Unsigned Byte to VSR
> +			   using GPR-specified Right-Index */
> +    case 26:		/* Vector Extract Double Unsigned Halfword to VSR
> +			   using GPR-specified Left-Index */
> +    case 27:		/* Vector Extract Double Unsigned Halfword to VSR
> +			   using GPR-specified Right-Index */
> +    case 28:		/* Vector Extract Double Unsigned Word to VSR
> +			   using GPR-specified Left-Index */
> +    case 29:		/* Vector Extract Double Unsigned Word to VSR
> +			   using GPR-specified Right-Index */
> +    case 30:		/* Vector Extract Double Unsigned Doubleword to VSR
> +			   using GPR-specified Left-Index */
> +    case 31:		/* Vector Extract Double Unsigned Doubleword to VSR
> +			   using GPR-specified Right-Index */
>      case 42:		/* Vector Select */
>      case 43:		/* Vector Permute */
>      case 59:		/* Vector Permute Right-indexed */
> +    case 22: 		/* Vector Shift
> +			      Left  Double by Bit Immediate if insn[21] = 0
> +			      Right Double by Bit Immediate if insn[21] = 1 */
>      case 44:		/* Vector Shift Left Double by Octet Immediate */
>      case 45:		/* Vector Permute and Exclusive-OR */
>      case 60:		/* Vector Add Extended Unsigned Quadword Modulo */
> @@ -4236,6 +4335,9 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>    /* Bit-21 is used for RC */
>    switch (ext & 0x3ff)
>      {
> +    case 5:		/* Vector Rotate Left Quadword */
> +    case 69:		/* Vector Rotate Left Quadword then Mask Insert */
> +    case 325:		/* Vector Rotate Left Quadword then AND with Mask */
>      case 6:		/* Vector Compare Equal To Unsigned Byte */
>      case 70:		/* Vector Compare Equal To Unsigned Halfword */
>      case 134:		/* Vector Compare Equal To Unsigned Word */
> @@ -4244,13 +4346,16 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      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 903:		/* Vector Compare Greater Than Signed Quadword */
>      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 647:		/* Vector Compare Greater Than Unsigned Quadword */
>      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 455:		/* Vector Compare Equal Quadword */
>      case 710:		/* Vector Compare Greater Than Single-Precision */
>      case 7:		/* Vector Compare Not Equal Byte */
>      case 71:		/* Vector Compare Not Equal Halfword */
> @@ -4263,6 +4368,21 @@ 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 13:
> +      switch (vra)    /* Bit-21 is used for RC */
> +	{
> +	case 0:       /* Vector String Isolate Byte Left-justified */
> +	case 1:       /* Vector String Isolate Byte Right-justified */
> +	case 2:       /* Vector String Isolate Halfword Left-justified */
> +	case 3:       /* Vector String Isolate Halfword Right-justified */
> +	  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;
> +	}
>      }
>  
>    if (ext  == 1538)
> @@ -4287,6 +4407,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>  	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 27:	/* Vector Extend Sign Doubleword To Quadword */
>  	case 28:	/* Vector Count Trailing Zeros Byte */
>  	case 29:	/* Vector Count Trailing Zeros Halfword */
>  	case 30:	/* Vector Count Trailing Zeros Word */
> @@ -4297,8 +4418,57 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>  	}
>      }
>  
> +  if (ext == 1602)
> +    {
> +      switch (vra)
> +	{
> +	case 0: 	/* Vector Expand Byte Mask */
> +	case 1: 	/* Vector Expand Halfword Mask */
> +	case 2: 	/* Vector Expand Word Mask */
> +	case 3: 	/* Vector Expand Doubleword Mask */
> +	case 4: 	/* Vector Expand Quadword Mask */
> +	case 16:	/* Move to VSR Byte Mask */
> +	case 17:	/* Move to VSR Halfword Mask */
> +	case 18:	/* Move to VSR Word Mask */
> +	case 19:	/* Move to VSR Doubleword Mask */
> +	case 20:	/* Move to VSR Quadword Mask */
> +	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
> +	  return 0;
> +
> +	case 8: 	/* Vector Extract Byte Mask */
> +	case 9: 	/* Vector Extract Halfword Mask */
> +	case 10: 	/* Vector Extract Word Mask */
> +	case 11: 	/* Vector Extract Doubleword Mask */
> +	case 12: 	/* Vector Extract Quadword Mask */
> +
> +	/* Ignore the MP bit in the LSB position of the vra value. */
> +	case 24:	/* Vector Count Mask Bits Byte, MP = 0 */
> +	case 25:	/* Vector Count Mask Bits Byte, MP = 1 */
> +	case 26:	/* Vector Count Mask Bits Halfword, MP = 0 */
> +	case 27:	/* Vector Count Mask Bits Halfword, MP = 1 */
> +	case 28:	/* Vector Count Mask Bits Word, MP = 0 */
> +	case 29:	/* Vector Count Mask Bits Word, MP = 1 */
> +	case 30:	/* Vector Count Mask Bits Doubleword, MP = 0 */
> +	case 31:	/* Vector Count Mask Bits Doubleword, MP = 1 */
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_gp0_regnum + PPC_RT (insn));
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_gp0_regnum + PPC_RT (insn));
> +	  return 0;
> +	}
> +    }
> +
>    switch (ext)
>      {
> +
> +    case 257:		/* Vector Compare Unsigned Quadword */
> +    case 321:		/* Vector Compare Signed Quadword */
> +      /* Comparison tests that always set CR field BF */
> +      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;
> +
>      case 142:		/* Vector Pack Unsigned Halfword Unsigned Saturate */
>      case 206:		/* Vector Pack Unsigned Word Unsigned Saturate */
>      case 270:		/* Vector Pack Signed Halfword Unsigned Saturate */
> @@ -4338,6 +4508,8 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 268:		/* Vector Merge Low Byte */
>      case 332:		/* Vector Merge Low Halfword */
>      case 396:		/* Vector Merge Low Word */
> +    case 397:		/* Vector Clear Leftmost Bytes */
> +    case 461:		/* Vector Clear Rightmost Bytes */
>      case 526:		/* Vector Unpack High Signed Byte */
>      case 590:		/* Vector Unpack High Signed Halfword */
>      case 654:		/* Vector Unpack Low Signed Byte */
> @@ -4356,8 +4528,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 780:		/* Vector Splat Immediate Signed Byte */
>      case 844:		/* Vector Splat Immediate Signed Halfword */
>      case 908:		/* Vector Splat Immediate Signed Word */
> +    case 261:		/* Vector Shift Left Quadword */
>      case 452:		/* Vector Shift Left */
> +    case 517:		/* Vector Shift Right Quadword */
>      case 708:		/* Vector Shift Right */
> +    case 773:		/* Vector Shift Right Algebraic Quadword */
>      case 1036:		/* Vector Shift Left by Octet */
>      case 1100:		/* Vector Shift Right by Octet */
>      case 0:		/* Vector Add Unsigned Byte Modulo */
> @@ -4370,15 +4545,43 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 8:		/* Vector Multiply Odd Unsigned Byte */
>      case 72:		/* Vector Multiply Odd Unsigned Halfword */
>      case 136:		/* Vector Multiply Odd Unsigned Word */
> +    case 200:		/* Vector Multiply Odd Unsigned Doubleword */
>      case 264:		/* Vector Multiply Odd Signed Byte */
>      case 328:		/* Vector Multiply Odd Signed Halfword */
>      case 392:		/* Vector Multiply Odd Signed Word */
> +    case 456:		/* Vector Multiply Odd Signed Doubleword */
>      case 520:		/* Vector Multiply Even Unsigned Byte */
>      case 584:		/* Vector Multiply Even Unsigned Halfword */
>      case 648:		/* Vector Multiply Even Unsigned Word */
> +    case 712:		/* Vector Multiply Even Unsigned Doubleword */
>      case 776:		/* Vector Multiply Even Signed Byte */
>      case 840:		/* Vector Multiply Even Signed Halfword */
>      case 904:		/* Vector Multiply Even Signed Word */
> +    case 968:		/* Vector Multiply Even Signed Doubleword */
> +    case 457:		/* Vector Multiply Low Doubleword */
> +    case 649:		/* Vector Multiply High Unsigned Word */
> +    case 713:		/* Vector Multiply High Unsigned Doubleword */
> +    case 905:		/* Vector Multiply High Signed Word */
> +    case 969:		/* Vector Multiply High Signed Doubleword */
> +    case 11:		/* Vector Divide Unsigned Quadword */
> +    case 203:		/* Vector Divide Unsigned Doubleword */
> +    case 139:		/* Vector Divide Unsigned Word */
> +    case 267:		/* Vector Divide Signed Quadword */
> +    case 459:		/* Vector Divide Signed Doubleword */
> +    case 395:		/* Vector Divide Signed Word */
> +    case 523:		/* Vector Divide Extended Unsigned Quadword */
> +    case 715:		/* Vector Divide Extended Unsigned Doubleword */
> +    case 651:		/* Vector Divide Extended Unsigned Word */
> +    case 779:		/* Vector Divide Extended Signed Quadword */
> +    case 971:		/* Vector Divide Extended Signed Doubleword */
> +    case 907:		/* Vector Divide Extended Unsigned Word */
> +    case 1547:		/* Vector Modulo Unsigned Quadword */
> +    case 1675:		/* Vector Modulo Unsigned Word */
> +    case 1739:		/* Vector Modulo Unsigned Doubleword */
> +    case 1803:		/* Vector Modulo Signed Quadword */
> +    case 1931:		/* Vector Modulo Signed Word */
> +    case 1995:		/* Vector Modulo Signed Doubleword */
> +
>      case 137:		/* Vector Multiply Unsigned Word Modulo */
>      case 1024:		/* Vector Subtract Unsigned Byte Modulo */
>      case 1088:		/* Vector Subtract Unsigned Halfword Modulo */
> @@ -4462,7 +4665,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 1794:		/* Vector Count Leading Zeros Byte */
>      case 1858:		/* Vector Count Leading Zeros Halfword */
>      case 1922:		/* Vector Count Leading Zeros Word */
> +    case 1924:		/* Vector Count Leading Zeros Doubleword under
> +			   bit Mask*/
>      case 1986:		/* Vector Count Leading Zeros Doubleword */
> +    case 1988:		/* Vector Count Trailing Zeros Doubleword under bit
> +			   Mask */
>      case 1795:		/* Vector Population Count Byte */
>      case 1859:		/* Vector Population Count Halfword */
>      case 1923:		/* Vector Population Count Word */
> @@ -4488,14 +4695,50 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 589:		/* Vector Extract Unsigned Halfword */
>      case 653:		/* Vector Extract Unsigned Word */
>      case 717:		/* Vector Extract Doubleword */
> +    case 15:		/* Vector Insert Byte from VSR using GPR-specified
> +			   Left-Index */
> +    case 79:		/* Vector Insert Halfword from VSR using GPR-specified
> +			   Left-Index */
> +    case 143:		/* Vector Insert Word from VSR using GPR-specified
> +			   Left-Index */
> +    case 207:		/* Vector Insert Word from GPR using
> +			   immediate-specified index */
> +    case 463:		/* Vector Insert Doubleword from GPR using
> +			   immediate-specified index */
> +    case 271:		/* Vector Insert Byte from VSR using GPR-specified
> +			   Right-Index */
> +    case 335:		/* Vector Insert Halfword from VSR using GPR-specified
> +			   Right-Index */
> +    case 399:		/* Vector Insert Word from VSR using GPR-specified
> +			   Right-Index */
> +    case 527:		/* Vector Insert Byte from GPR using GPR-specified
> +			   Left-Index */
> +    case 591:		/* Vector Insert Halfword from GPR using GPR-specified
> +			   Left-Index */
> +    case 655:		/* Vector Insert Word from GPR using GPR-specified
> +			   Left-Index */
> +    case 719:		/* Vector Insert Doubleword from GPR using
> +			    GPR-specified Left-Index */
> +    case 783:		/* Vector Insert Byte from GPR using GPR-specified
> +			   Right-Index */
> +    case 847:		/* Vector Insert Halfword from GPR using GPR-specified
> +			   Left-Index */
> +    case 911:		/* Vector Insert Word from GPR using GPR-specified
> +			   Left-Index */
> +    case 975:		/* Vector Insert Doubleword from GPR using
> +			    GPR-specified Right-Index */
>      case 781:		/* Vector Insert Byte */
>      case 845:		/* Vector Insert Halfword */
>      case 909:		/* Vector Insert Word */
>      case 973:		/* Vector Insert Doubleword */
> +    case 1357:		/* Vector Centrifuge Doubleword */
> +    case 1421:		/* Vector Parallel Bits Extract Doubleword */
> +    case 1485:		/* Vector Parallel Bits Deposit Doubleword */
>        record_full_arch_list_add_reg (regcache,
>  				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
>        return 0;
>  
> +    case 1228:		/* Vector Gather every Nth Bit */
>      case 1549:		/* Vector Extract Unsigned Byte Left-Indexed */
>      case 1613:		/* Vector Extract Unsigned Halfword Left-Indexed */
>      case 1677:		/* Vector Extract Unsigned Word Left-Indexed */
> @@ -4525,6 +4768,34 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>    return -1;
>  }
>  
> +/* Parse and record instructions of primary opcode 6 at ADDR.
> +   Return 0 if successful.  */
> +
> +static int
> +ppc_process_record_op6 (struct gdbarch *gdbarch, struct regcache *regcache,
> +			CORE_ADDR addr, uint32_t insn)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  int subtype = PPC_FIELD (insn, 28, 4);
> +  CORE_ADDR ea = 0;
> +
> +  switch (subtype)
> +    {
> +    case 0:    /* Load VSX Vector Paired */
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
> +      return 0;
> +    case 1:    /* Store VSX Vector Paired */
> +      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, 32);
> +      return 0;
> +    }
> +  return -1;
> +}
> +
>  /* Parse and record instructions of primary opcode-19 at ADDR.
>     Return 0 if successful.  */
>  
> @@ -4577,6 +4848,30 @@ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
>    return -1;
>  }
>  
> +/* Parse and record instructions of primary opcode-31 with the extended opcode
> +   177.  The argument is the word instruction (insn).  Return 0 if successful.
> +*/
> +
> +static int
> +ppc_process_record_op31_177 (struct gdbarch *gdbarch,
> +			     struct regcache *regcache,
> +			     uint32_t insn)
> +{
> +  int RA_opcode = PPC_RA(insn);
> +  int as = PPC_FIELD (insn, 6, 3);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  switch (RA_opcode)
> +    {
> +    case 0: 		/* VSX Move From Accumulator, xxmfacc */
> +    case 1: 		/* VSX Move To Accumulator, xxmtacc */
> +    case 3: 		/* VSX Set Accumulator to Zero, xxsetaccz */
> +      ppc_record_ACC_fpscr (regcache, tdep, as, DO_NOT_RECORD_FPSCR);
> +      return 0;
> +    }
> +  return -1;
> +}
> +
>  /* Parse and record instructions of primary opcode-31 at ADDR.
>     Return 0 if successful.  */
>  
> @@ -4586,7 +4881,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>  {
>    ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
>    int ext = PPC_EXTOP (insn);
> -  int tmp, nr, nb, i;
> +  int tmp, nr, nb = 0, i;
>    CORE_ADDR at_dcsz, ea = 0;
>    ULONGEST rb, ra, xer;
>    int size = 0;
> @@ -4677,6 +4972,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 371:		/* Move From Time Base [Phased-Out]  */
>      case 309:		/* Load Doubleword Monitored Indexed  */
>      case 128:		/* Set Boolean */
> +    case 384:		/* Set Boolean Condition */
> +    case 416:		/* Set Boolean Condition Reverse */
> +    case 448:		/* Set Negative Boolean Condition */
> +    case 480:		/* Set Negative Boolean Condition Reverse */
>      case 755:		/* Deliver A Random Number */
>        record_full_arch_list_add_reg (regcache,
>  				     tdep->ppc_gp0_regnum + PPC_RT (insn));
> @@ -4684,8 +4983,15 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>  
>      /* These only write to RA.  */
>      case 51:		/* Move From VSR Doubleword */
> +    case 59:		/* Count Leading Zeros Doubleword under bit Mask */
>      case 115:		/* Move From VSR Word and Zero */
>      case 122:		/* Population count bytes */
> +    case 155:		/* Byte-Reverse Word */
> +    case 156:		/* Parallel Bits Deposit Doubleword */
> +    case 187:		/* Byte-Reverse Doubleword */
> +    case 188:		/* Parallel Bits Extract Doubleword */
> +    case 219:		/* Byte-Reverse Halfword */
> +    case 220:		/* Centrifuge Doubleword */
>      case 378:		/* Population count words */
>      case 506:		/* Population count doublewords */
>      case 154:		/* Parity Word */
> @@ -4695,6 +5001,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 314:		/* Convert Binary Coded Decimal To Declets */
>      case 508:		/* Compare bytes */
>      case 307:		/* Move From VSR Lower Doubleword */
> +    case 571:		/* Count Trailing Zeros Doubleword under bit Mask */
>        record_full_arch_list_add_reg (regcache,
>  				     tdep->ppc_gp0_regnum + PPC_RA (insn));
>        return 0;
> @@ -4819,6 +5126,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>        record_full_arch_list_add_reg (regcache, tmp + 1);
>        return 0;
>  
> +    /* These write to destination register PPC_XT. */
>      case 179:		/* Move To VSR Doubleword */
>      case 211:		/* Move To VSR Word Algebraic */
>      case 243:		/* Move To VSR Word and Zero */
> @@ -4826,6 +5134,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>      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 13:		/* Load VSX Vector Rightmost Byte Indexed */
> +    case 45:		/* Load VSX Vector Rightmost Halfword Indexed */
> +    case 77:		/* Load VSX Vector Rightmost Word Indexed */
> +    case 109:		/* Load VSX Vector Rightmost Doubleword 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 */
> @@ -4842,6 +5154,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>        ppc_record_vsr (regcache, tdep, PPC_XT (insn));
>        return 0;
>  
> +    case 333:		/* Load VSX Vector Paired Indexed */
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
> +      return 0;
> +
>      /* These write RA.  Update CR if RC is set.  */
>      case 24:		/* Shift Left Word */
>      case 26:		/* Count Leading Zeros Word */
> @@ -5006,6 +5323,31 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>        record_full_arch_list_add_mem (ea, size);
>        return 0;
>  
> +    case 141:		/* Store VSX Vector Rightmost Byte Indexed */
> +    case 173:		/* Store VSX Vector Rightmost Halfword Indexed */
> +    case 205:		/* Store VSX Vector Rightmost Word Indexed */
> +    case 237:		/* Store VSX Vector Rightmost Doubleword Indexed */
> +      switch(ext)
> +	{
> +	  case 141: nb = 1;
> +	  break;
> +	  case 173: nb = 2;
> +	  break;
> +	  case 205: nb = 4;
> +	  break;
> +	  case 237: nb = 8;
> +	  break;
> +	}
> +      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;
> +      record_full_arch_list_add_mem (ea, nb);
> +      return 0;
> +
>      case 397:		/* Store VSX Vector with Length */
>      case 429:		/* Store VSX Vector Left-justified with Length */
>        ra = 0;
> @@ -5021,6 +5363,19 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>  	record_full_arch_list_add_mem (ea, nb);
>        return 0;
>  
> +    case 461:		/* Store VSX Vector Paired Indexed */
> +      {
> +	if (PPC_RA (insn) != 0)
> +	  regcache_raw_read_unsigned (regcache,
> +				      tdep->ppc_gp0_regnum
> +				      + PPC_RA (insn), &ea);
> +	regcache_raw_read_unsigned (regcache,
> +				    tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
> +	ea += rb;
> +	record_full_arch_list_add_mem (ea, 32);
> +	return 0;
> +      }
> +
>      case 710:		/* Store Word Atomic */
>      case 742:		/* Store Doubleword Atomic */
>        ra = 0;
> @@ -5166,6 +5521,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>        ea = (ra + rb) & ~((ULONGEST) (at_dcsz - 1));
>        record_full_arch_list_add_mem (ea, at_dcsz);
>        return 0;
> +
> +    case 177:
> +      if (ppc_process_record_op31_177 (gdbarch, regcache, insn) == 0)
> +	return 0;
>      }
>  
>  UNKNOWN_OP:
> @@ -5179,10 +5538,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>  
>  static int
>  ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
> -			   CORE_ADDR addr, uint32_t insn)
> +			 CORE_ADDR addr, uint32_t insn)
>  {
>    ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
>    int ext = PPC_EXTOP (insn);
> +  int at = PPC_FIELD (insn, 6, 3);
>  
>    switch (ext & 0x1f)
>      {
> @@ -5206,6 +5566,75 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
>        return 0;
>      }
>  
> +  /* MMA instructions, keep looking.  */
> +  switch (ext >> 2)    /* Additional opcode field is upper 8-bits of ext */
> +    {
> +    case 3:	/* VSX Vector 8-bit Signed/Unsigned Integer GER, xvi8ger4 */
> +    case 2:	/* VSX Vector 8-bit Signed/Unsigned Integer GER Positive
> +		   multiply, Positive accumulate, xvi8ger4pp */
> +
> +    case 99:	/* VSX Vector 8-bit Signed/Unsigned Integer GER with
> +		   Saturate Positive multiply, Positive accumulate,
> +		   xvi8ger4spp */
> +
> +    case 35:	/* VSX Vector 4-bit Signed Integer GER, xvi4ger8 */
> +    case 34:	/* VSX Vector 4-bit Signed Integer GER Positive multiply,
> +		   Positive accumulate, xvi4ger8pp */
> +
> +    case 75:	/* VSX Vector 16-bit Signed Integer GER, xvi16ger2 */
> +    case 107:	/* VSX Vector 16-bit Signed Integer GER  Positive multiply,
> +		   Positive accumulate, xvi16ger2pp */
> +
> +    case 43:	/* VSX Vector 16-bit Signed Integer GER with Saturation,
> +		   xvi16ger2s */
> +    case 42:	/* VSX Vector 16-bit Signed Integer GER with Saturation
> +		   Positive multiply, Positive accumulate, xvi16ger2spp */
> +      ppc_record_ACC_fpscr (regcache, tdep, at, DO_NOT_RECORD_FPSCR);
> +      return 0;
> +
> +    case 19:	/* VSX Vector 16-bit Floating-Point GER, xvf16ger2 */
> +    case 18:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
> +		   Positive accumulate, xvf16ger2pp */
> +    case 146:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
> +		   Negative accumulate, xvf16ger2pn */
> +    case 82:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
> +		   Positive accumulate, xvf16ger2np */
> +    case 210:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
> +		   Negative accumulate, xvf16ger2nn */
> +
> +    case 27:	/* VSX Vector 32-bit Floating-Point GER, xvf32ger */
> +    case 26:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
> +		   Positive accumulate, xvf32gerpp */
> +    case 154:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
> +		   Negative accumulate, xvf32gerpn */
> +    case 90:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
> +		   Positive accumulate, xvf32gernp */
> +    case 218:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
> +		   Negative accumulate, xvf32gernn */
> +
> +    case 59:	/* VSX Vector 64-bit Floating-Point GER, pmxvf64ger */
> +    case 58:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
> +		   Positive accumulate, xvf64gerpp */
> +    case 186:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
> +		   Negative accumulate, xvf64gerpn */
> +    case 122:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
> +		   Positive accumulate, xvf64gernp */
> +    case 250:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
> +		   Negative accumulate, pmxvf64gernn */
> +
> +    case 51:	/* VSX Vector bfloat16 GER, xvbf16ger2 */
> +    case 50:	/* VSX Vector bfloat16 GER Positive multiply,
> +		   Positive accumulate, xvbf16ger2pp */
> +    case 178:	/* VSX Vector bfloat16 GER Positive multiply,
> +		   Negative accumulate, xvbf16ger2pn */
> +    case 114:	/* VSX Vector bfloat16 GER Negative multiply,
> +		   Positive accumulate, xvbf16ger2np */
> +    case 242:	/* VSX Vector bfloat16 GER Negative multiply,
> +		   Negative accumulate, xvbf16ger2nn */
> +      ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
> +      return 0;
> +    }
> +
>    switch (ext)
>      {
>      case 2:		/* DFP Add */
> @@ -5268,6 +5697,48 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
>    return -1;
>  }
>  
> +/* Parse and record an XX2-Form instruction with opcode 60 at ADDR.  The
> +   word instruction is an argument insn.  Return 0 if successful.  */
> +
> +static int
> +ppc_process_record_op60_XX2 (struct gdbarch *gdbarch,
> +			     struct regcache *regcache,
> +			     CORE_ADDR addr, uint32_t insn)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  int RA_opcode = PPC_RA(insn);
> +
> +  switch (RA_opcode)
> +    {
> +    case 2:	/* VSX Vector Test Least-Significant Bit by Byte */
> +    case 25:	/* VSX Vector round and Convert Single-Precision format
> +		   to Half-Precision format.  Only changes the CR
> +		   field.  */
> +      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
> +      return 0;
> +    case 17:	/* VSX Vector Convert with round Single-Precision
> +		   to bfloat16 format */
> +    case 24:	/* VSX Vector Convert Half-Precision format to
> +		   Single-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 16:	/* VSX Vector Convert bfloat16 to Single-Precision
> +		   format Non-signaling */
> +    case 23:	/* VSX Vector Byte-Reverse Doubleword */
> +    case 31:	/* VSX Vector Byte-Reverse Quadword */
> +      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
> +      return 0;
> +    }
> +
> +  return -1;
> +}
> +
>  /* Parse and record instructions of primary opcode-60 at ADDR.
>     Return 0 if successful.  */
>  
> @@ -5583,37 +6054,30 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
>        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;
> +      if (ppc_process_record_op60_XX2 (gdbarch, regcache, addr, insn) != 0)
> +	return -1;
> +      return 0;
>      }
>  
>    switch (ext)
>      {
> -    case 360:		/* VSX Vector Splat Immediate Byte */
> -      if (PPC_FIELD (insn, 11, 2) == 0)
> +    case 360:
> +      if (PPC_FIELD (insn, 11, 2) == 0)  /* VSX Vector Splat Immediate Byte */
> +	{
> +	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
> +	  return 0;
> +	}
> +      if (PPC_FIELD (insn, 11, 5) == 31)  /* Load VSX Vector Special Value
> +					     Quadword */
>  	{
>  	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
>  	  return 0;
>  	}
>        break;
> +    case 916:		/* VSX Vector Generate PCV from Byte Mask */
> +    case 917:		/* VSX Vector Generate PCV from Halfword Mask */
> +    case 948:		/* VSX Vector Generate PCV from Word Mask */
> +    case 949:		/* VSX Vector Generate PCV from Doubleword Mask */
>      case 918:		/* VSX Scalar Insert Exponent Double-Precision */
>        ppc_record_vsr (regcache, tdep, PPC_XT (insn));
>        return 0;
> @@ -5894,6 +6358,35 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
>  			   Quad-Precision */
>      case 516:		/* VSX Scalar Subtract Quad-Precision */
>      case 548:		/* VSX Scalar Divide Quad-Precision */
> +    case 994:
> +      {
> +      switch (PPC_FIELD (insn, 11, 5))
> +	{
> +	case 0:	/* DFP Convert From Fixed Quadword Quad */
> +	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
> +
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_fp0_regnum
> +					 + PPC_FRT (insn));
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_fp0_regnum
> +					 + PPC_FRT (insn) + 1);
> +	  return 0;
> +	case 1:	/* DFP Convert To Fixed Quadword Quad */
> +	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
> +	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
> +	  return 0;
> +	}
> +      }
> +
> +      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
> +      /* FALL-THROUGH */
> +    case 68:		/* VSX Scalar Compare Equal Quad-Precision */
> +    case 196:		/* VSX Scalar Compare Greater Than or Equal
> +			   Quad-Precision */
> +    case 228:		/* VSX Scalar Compare Greater Than Quad-Precision */
> +    case 676:		/* VSX Scalar Maximum Type-C Quad-Precision */
> +    case 740:		/* VSX Scalar Minimum Type-C Quad-Precision */
>        record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
>        /* FALL-THROUGH */
>      case 100:		/* VSX Scalar Copy Sign Quad-Precision */
> @@ -5920,14 +6413,22 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 836:
>        switch (PPC_FIELD (insn, 11, 5))
>  	{
> +	case 0:		/* VSX Scalar Convert with round to zero
> +			   Quad-Precision to Unsigned Quadword  */
>  	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 3:		/* VSX Scalar Convert with round
> +			   Unsigned Quadword to Quad-Precision  */
> +	case 8:		/* VSX Scalar Convert with round to zero
> +			   Quad-Precision to Signed Quadword  */
>  	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 11:	/* VSX Scalar Convert with round
> +			   Signed Quadword to Quad-Precision */
>  	case 17:	/* VSX Scalar truncate & Convert Quad-Precision format
>  			   to Unsigned Doubleword format */
>  	case 20:	/* VSX Scalar round & Convert Quad-Precision format to
> @@ -5947,17 +6448,651 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
>    return -1;
>  }
>  
> +/* Record the prefixed instructions with primary opcode 32.  The arguments are
> +   the first 32-bits of the instruction (insn_prefix), and the second 32-bits
> +   of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_op42 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +
> +  if (ST1 != 0)
> +    return -1;
> +
> +  switch (type)
> +    {
> +    case 0:  /* Prefixed Load VSX Scalar Doubleword, plxsd */
> +      ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
> +      break;
> +    case 2:  /* Prefixed Load Halfword Algebraic, plha */
> +      record_full_arch_list_add_reg (regcache,
> +				     tdep->ppc_gp0_regnum
> +				     + PPC_RT (insn_suffix));
> +      break;
> +    default:
> +      return -1;
> +    }
> +  return 0;
> +}
> +
> +/* Record the prefixed XX3-Form instructions with primary opcode 59.  The
> +   arguments are the first 32-bits of the instruction (insn_prefix), and the
> +   second 32-bits of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_op59_XX3 (struct gdbarch *gdbarch,
> +				    struct regcache *regcache,
> +				    uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  int opcode = PPC_FIELD (insn_suffix, 21, 8);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  int at = PPC_FIELD (insn_suffix, 6, 3);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  if (type == 3)
> +    {
> +      if (ST4 == 9)
> +	switch (opcode)
> +	  {
> +	  case 35:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
> +			   MMIRR, pmxvi4ger8 */
> +	  case 34:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
> +			   MMIRR, pmxvi4ger8pp */
> +
> +	  case 99:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
> +			   Integer GER with Saturate Positive multiply,
> +			   Positive accumulate, xvi8ger4spp */
> +
> +	  case 3:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
> +			   Integer GER MMIRR, pmxvi8ger4 */
> +	  case 2:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
> +			   Integer GER Positive multiply, Positive accumulate
> +			   MMIRR, pmxvi8ger4pp */
> +
> +	  case 75:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
> +			   GER MMIRR, pmxvi16ger2 */
> +	  case 107:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
> +			   GER  Positive multiply, Positive accumulate,
> +			   pmxvi16ger2pp */
> +
> +	  case 43:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
> +			   GER with Saturation MMIRR, pmxvi16ger2s */
> +	  case 42:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
> +			   GER with Saturation Positive multiply, Positive
> +			   accumulate MMIRR, pmxvi16ger2spp */
> +	    ppc_record_ACC_fpscr (regcache, tdep, at, DO_NOT_RECORD_FPSCR);
> +	    return 0;
> +
> +	  case 19:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER MMIRR, pmxvf16ger2 */
> +	  case 18:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER Positive multiply, Positive accumulate MMIRR,
> +			   pmxvf16ger2pp */
> +	  case 146:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER Positive multiply, Negative accumulate MMIRR,
> +			   pmxvf16ger2pn */
> +	  case 82:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER Negative multiply, Positive accumulate MMIRR,
> +			   pmxvf16ger2np */
> +	  case 210:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER Negative multiply, Negative accumulate MMIRR,
> +			   pmxvf16ger2nn */
> +
> +	  case 27:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER MMIRR, pmxvf32ger */
> +	  case 26:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER Positive multiply, Positive accumulate MMIRR,
> +			   pmxvf32gerpp */
> +	  case 154:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER Positive multiply, Negative accumulate MMIRR,
> +			   pmxvf32gerpn */
> +	  case 90:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER Negative multiply, Positive accumulate MMIRR,
> +			   pmxvf32gernp */
> +	  case 218:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER Negative multiply, Negative accumulate MMIRR,
> +			   pmxvf32gernn */
> +
> +	  case 59:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
> +			   GER MMIRR, pmxvf64ger */
> +	  case 58:	/* Floating-Point GER Positive multiply, Positive
> +			   accumulate MMIRR, pmxvf64gerpp */
> +	  case 186:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
> +			   GER Positive multiply, Negative accumulate MMIRR,
> +			   pmxvf64gerpn */
> +	  case 122:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
> +			   GER Negative multiply, Positive accumulate MMIRR,
> +			   pmxvf64gernp */
> +	  case 250:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
> +			   GER Negative multiply, Negative accumulate MMIRR,
> +			   pmxvf64gernn */
> +
> +	  case 51:	/* Prefixed Masked VSX Vector bfloat16 GER MMIRR,
> +			   pmxvbf16ger2 */
> +	  case 50:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
> +			   multiply, Positive accumulate MMIRR,
> +			   pmxvbf16ger2pp */
> +	  case 178:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
> +			   multiply, Negative accumulate MMIRR,
> +			   pmxvbf16ger2pn */
> +	  case 114:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
> +			   multiply, Positive accumulate MMIRR,
> +			   pmxvbf16ger2np */
> +	  case 242:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
> +			   multiply, Negative accumulate MMIRR,
> +			   pmxvbf16ger2nn */
> +	    ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
> +	    return 0;
> +	  }
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed store instructions.  The arguments are the instruction
> +   address, the first 32-bits of the instruction(insn_prefix) and the following
> +   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_store (struct gdbarch *gdbarch,
> +				 struct regcache *regcache,
> +				 CORE_ADDR addr, uint32_t insn_prefix,
> +				 uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  ULONGEST iaddr = 0;
> +  int size;
> +  int R = PPC_BIT (insn_prefix, 11);
> +  int op6 = PPC_OP6 (insn_suffix);
> +
> +  if (R == 0)
> +    {
> +      if (PPC_RA (insn_suffix) != 0)
> +	regcache_raw_read_unsigned (regcache, tdep->ppc_gp0_regnum
> +				    + PPC_RA (insn_suffix), &iaddr);
> +    }
> +  else
> +    {
> +      iaddr = addr;     /* PC relative */
> +    }
> +
> +  switch (op6)
> +    {
> +    case 38:
> +      size =  1;    /* store byte, pstb */
> +      break;
> +    case 44:
> +      size =  2;    /* store halfword, psth */
> +      break;
> +    case 36:
> +    case 52:
> +      size =  4;    /* store word, pstw, pstfs */
> +      break;
> +    case 54:
> +    case 61:
> +      size =  8;    /* store double word, pstd, pstfd */
> +      break;
> +    case 60:
> +      size = 16;    /* store quadword, pstq */
> +      break;
> +    default: return -1;
> +    }
> +
> +  iaddr += P_PPC_D (insn_prefix, insn_suffix);
> +  record_full_arch_list_add_mem (iaddr, size);
> +  return 0;
> +}
> +
> +/* Record the prefixed instructions with primary op code 32.  The arguments
> +   are the first 32-bits of the instruction (insn_prefix) and the following
> +   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_op32 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  if (type == 1)
> +    {
> +      if (ST4 == 0)
> +	{
> +	  switch (PPC_FIELD (insn_suffix, 11, 3))
> +	    {
> +	    case 0:  	/* VSX Vector Splat Immediate Word 8RR, xxsplti32dx */
> +	      ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
> +	      return 0;
> +	    }
> +
> +	  switch (PPC_FIELD (insn_suffix, 11, 4))
> +	    {
> +	    case 2:  	/* VSX Vector Splat Immediate Double-Precision
> +			   8RR, xxspltidp */
> +	    case 3:  	/* VSX Vector Splat Immediate Word 8RR, xxspltiw */
> +	      ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
> +	      return 0;
> +	    default:
> +	      return -1;
> +	    }
> +	}
> +      else
> +	return -1;
> +
> +    }
> +  else if (type == 2)
> +    {
> +      if (ST1 == 0)  		/* Prefixed Load Word and Zero, plwz */
> +	record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	return -1;
> +
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed instructions with primary op code 33.  The arguments
> +   are the first 32-bits of the instruction(insn_prefix) and the following
> +   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_op33 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  if (type == 1)
> +    {
> +      if (ST4 == 0)
> +	switch (PPC_FIELD (insn_suffix, 26, 2))
> +	  {
> +	  case 0:  	/* VSX Vector Blend Variable Byte 8RR, xxblendvb */
> +	  case 1:  	/* VSX Vector Blend Variable Halfword, xxblendvh */
> +	  case 2:  	/* VSX Vector Blend Variable Word, xxblendvw */
> +	  case 3:  	/* VSX Vector Blend Variable Doubleword, xxblendvd */
> +	    ppc_record_vsr (regcache, tdep, PPC_XT (insn_suffix));
> +	  break;
> +	  default:
> +	    return -1;
> +	  }
> +      else
> +	return -1;
> +
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed instructions with primary op code 34.  The arguments
> +   are the first 32-bits of the instruction(insn_prefix) and the following
> +   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_op34 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  if (type == 1)
> +    {
> +      if (ST4 == 0)
> +	switch (PPC_FIELD (insn_suffix, 26, 2))
> +	  {
> +	  case 0:  	/* VSX Vector Permute Extended 8RR, xxpermx */
> +	  case 1:  	/* VSX Vector Evaluate 8RR, xxeval */
> +	    ppc_record_vsr (regcache, tdep, P_PPC_XT (insn_suffix));
> +	    break;
> +	  default:
> +	    return -1;
> +	  }
> +      else
> +	return -1;
> +
> +    }
> +  else if (type == 2)
> +    {
> +      if (ST1 == 0)  		/* Prefixed Load Word and Zero, plbz */
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	return -1;
> +
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed VSX store, form DS, instructions.  The arguments are the
> +   instruction address (addr), the first 32-bits of the instruction
> +   (insn_prefix) followed by the 32-bit instruction suffix (insn_suffix).
> +   Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_store_vsx_ds_form (struct gdbarch *gdbarch,
> +					     struct regcache *regcache,
> +					     CORE_ADDR addr,
> +					     uint32_t insn_prefix,
> +					     uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  ULONGEST ea = 0;
> +  int size;
> +  int R = PPC_BIT (insn_prefix, 11);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +
> +  if ((type == 0) && (ST1 == 0))
> +    {
> +      if (R == 0)
> +	{
> +	  if (PPC_RA (insn_suffix) != 0)
> +	    regcache_raw_read_unsigned (regcache,
> +					tdep->ppc_gp0_regnum
> +					+ PPC_RA (insn_suffix),
> +					&ea);
> +	}
> +      else
> +	{
> +	  ea = addr;     /* PC relative */
> +	}
> +
> +      ea += P_PPC_D (insn_prefix, insn_suffix);
> +      switch (PPC_FIELD (insn_suffix, 0, 6))
> +	{
> +	case 46:    /* Prefixed Store VSX Scalar Doubleword, pstxsd */
> +	  size = 8;
> +	  break;
> +	case 47:    /* Prefixed,Store VSX Scalar Single-Precision, pstxssp */
> +	  size = 4;
> +	  break;
> +	default:
> +	  return -1;
> +	}
> +      record_full_arch_list_add_mem (ea, size);
> +      return 0;
> +  }
> +  else
> +    return -1;
> +}
> +
> +/* Record the prefixed VSX, form D, instructions.  The arguments are the
> +   instruction address for PC-relative addresss (addr), the first 32-bits of
> +   the instruction (insn_prefix) and the following 32-bits of the instruction
> +   (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_vsx_d_form (struct gdbarch *gdbarch,
> +				      struct regcache *regcache,
> +				      CORE_ADDR addr,
> +				      uint32_t insn_prefix,
> +				      uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  ULONGEST ea = 0;
> +  int size;
> +  int R = PPC_BIT (insn_prefix, 11);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +
> +  if ((type == 0) && (ST1 == 0))
> +    {
> +      switch (PPC_FIELD (insn_suffix, 0, 5))
> +	{
> +	case 25:	/* Prefixed Load VSX Vector, plxv */
> +	  ppc_record_vsr (regcache, tdep, P_PPC_XT5 (insn_prefix));
> +	  return 0;
> +	case 27:	/* Prefixed Store VSX Vector 8LS, pstxv */
> +	  {
> +	    size = 16;
> +	    if (R == 0)
> +	      {
> +		if (PPC_RA (insn_suffix) != 0)
> +		  regcache_raw_read_unsigned (regcache,
> +					      tdep->ppc_gp0_regnum
> +					      + PPC_RA (insn_suffix),
> +					      &ea);
> +	      }
> +	    else
> +	      {
> +		ea = addr;     /* PC relative */
> +	      }
> +
> +	    ea += P_PPC_D (insn_prefix, insn_suffix);
> +	    record_full_arch_list_add_mem (ea, size);
> +	    return 0;
> +	  }
> +	}
> +      return -1;
> +    }
> +  else
> +    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.  */
>  
> +/* This handles the recording of the various prefix instructions.  It takes
> +   the instruction address, the first 32-bits of the instruction (insn_prefix)
> +   and the following 32-bits of the instruction (insn_suffix).  Return 0 on
> +   success.  */
> +
> +static int
> +ppc_process_prefix_instruction (int insn_prefix, int insn_suffix,
> +				CORE_ADDR addr,	struct gdbarch *gdbarch,
> +				struct regcache *regcache)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  int op6;
> +
> +  /* D-form has uses a 5-bit opcode in the instruction suffix */
> +  if (ppc_process_record_prefix_vsx_d_form ( gdbarch, regcache, addr,
> +					     insn_prefix, insn_suffix) == 0)
> +    goto SUCCESS;
> +
> +  op6 = PPC_OP6 (insn_suffix);  /* 6-bit opcode in the instruction suffix */
> +
> +  switch (op6)
> +    {
> +    case 14:		/* Prefixed Add Immediate, paddi */
> +      if ((type == 2) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 32:
> +      if (ppc_process_record_prefix_op32 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 33:
> +      if (ppc_process_record_prefix_op33 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 34:		/* Prefixed Load Byte and Zero, plbz */
> +      if (ppc_process_record_prefix_op34 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +    case 40:		/* Prefixed Load Halfword and Zero, plhz */
> +      if ((type == 2) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +      break;
> +
> +    case 36:		/* Prefixed Store Word, pstw */
> +    case 38:		/* Prefixed Store Byte, pstb */
> +    case 44:		/* Prefixed Store Halfword, psth */
> +    case 52:		/* Prefixed Store Floating-Point Single, pstfs */
> +    case 54:		/* Prefixed Store Floating-Point Double, pstfd */
> +    case 60:		/* Prefixed Store Quadword, pstq */
> +    case 61:		/* Prefixed Store Doubleword, pstd */
> +      if (ppc_process_record_prefix_store (gdbarch, regcache, addr,
> +					   insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 42:
> +      if (ppc_process_record_prefix_op42 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 43:          /* Prefixed Load VSX Scalar Single-Precision, plxssp */
> +      if ((type == 0) && (ST1 == 0))
> +	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
> +      else
> +	  goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 46:
> +    case 47:
> +      if (ppc_process_record_prefix_store_vsx_ds_form (gdbarch, regcache, addr,
> +					       insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 56:		/* Prefixed Load Quadword, plq */
> +      {
> +	if ((type == 0) && (ST1 == 0))
> +	  {
> +	    int tmp;
> +	    tmp = tdep->ppc_gp0_regnum + (PPC_RT (insn_suffix) & ~1);
> +	    record_full_arch_list_add_reg (regcache, tmp);
> +	    record_full_arch_list_add_reg (regcache, tmp + 1);
> +	  }
> +	else
> +	  goto UNKNOWN_PREFIX_OP;
> +	break;
> +      }
> +
> +    case 41:		/* Prefixed Load Word Algebraic, plwa */
> +    case 57:  		/* Prefixed Load Doubleword, pld */
> +      if ((type == 0) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 48:		/* Prefixed Load Floating-Point Single, plfs */
> +    case 50:		/* Prefixed Load Floating-Point Double, plfd */
> +      if ((type == 2) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_fp0_regnum
> +				       + PPC_FRT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 58:		/* Prefixed Load VSX Vector Paired, plxvp */
> +      if ((type == 0) && (ST1 == 0))
> +	{
> +	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix));
> +	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix) + 1);
> +	}
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 59:
> +      if (ppc_process_record_prefix_op59_XX3 (gdbarch, regcache, insn_prefix,
> +					      insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 62:	    /* Prefixed Store VSX Vector Paired 8LS, pstxvp */
> +      if ((type == 0) && (ST1 == 0))
> +	{
> +	  int R = PPC_BIT (insn_prefix, 11);
> +	  CORE_ADDR ea = 0;
> +
> +	  if (R == 0)
> +	    {
> +	      if (PPC_RA (insn_suffix) != 0)
> +		regcache_raw_read_unsigned (regcache,
> +					    tdep->ppc_gp0_regnum
> +					    + PPC_RA (insn_suffix), &ea);
> +	    }
> +	  else
> +	    {
> +	      ea = addr;     /* PC relative */
> +	    }
> +
> +	  ea += P_PPC_D (insn_prefix, insn_suffix) << 4;
> +	  record_full_arch_list_add_mem (ea, 32);
> +	}
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    default:
> +UNKNOWN_PREFIX_OP:
> +      gdb_printf (gdb_stdlog,
> +		  "Warning: Don't know how to record prefix instruction "
> +		  "%08x %08x at %s, %d.\n",
> +		  insn_prefix, insn_suffix, paddress (gdbarch, addr),
> +		  op6);
> +      return -1;
> +    }
> +
> + SUCCESS:
> +  if (record_full_arch_list_add_reg (regcache, PPC_PC_REGNUM))
> +    return -1;
> +
> +  if (record_full_arch_list_add_end ())
> +    return -1;
> +  return 0;
> +}
> +
>  int
>  ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
>  		      CORE_ADDR addr)
>  {
>    ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
>    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
> -  uint32_t insn;
> +  uint32_t insn, insn_suffix;
>    int op6, tmp, i;
>  
>    insn = read_memory_unsigned_integer (addr, 4, byte_order);
> @@ -5965,16 +7100,28 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
>  
>    switch (op6)
>      {
> +    case 1:		/* prefixed instruction */
> +      {
> +	/* Get the lower 32-bits of the prefixed instruction. */
> +	insn_suffix = read_memory_unsigned_integer (addr+4, 4, byte_order);
> +	return ppc_process_prefix_instruction (insn, insn_suffix, addr,
> +					       gdbarch, regcache);
> +      }
>      case 2:		/* Trap Doubleword Immediate */
>      case 3:		/* Trap Word Immediate */
>        /* Do nothing.  */
>        break;
>  
> -    case 4:
> +    case 4:             /* Vector Integer, Compare, Logical, Shift, etc.  */  
>        if (ppc_process_record_op4 (gdbarch, regcache, addr, insn) != 0)
>  	return -1;
>        break;
>  
> +    case 6:             /* Vector Load and Store */
> +      if (ppc_process_record_op6 (gdbarch, regcache, addr, insn) != 0)
> +	return -1;
> +      break;
> +
>      case 17:		/* System call */
>        if (PPC_LEV (insn) != 0)
>  	goto UNKNOWN_OP;
> -- 
> 2.31.1
> 
> 

-- 
Joel

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/2 Version 4] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-14 20:43               ` Carl Love
@ 2022-04-17 16:48                 ` Joel Brobecker
  2022-04-18 19:21                   ` [PATCH 2/2 Version 5] " Carl Love
  0 siblings, 1 reply; 25+ messages in thread
From: Joel Brobecker @ 2022-04-17 16:48 UTC (permalink / raw)
  To: Carl Love
  Cc: Pedro Alves, will schmidt, Joel Brobecker, gdb-patches,
	Ulrich Weigand, Tulio Magno, Rogerio Alves

On Thu, Apr 14, 2022 at 01:43:09PM -0700, Carl Love wrote:
> Pedro, Will, Joel:
> 
> Ignore previous email.  The changes didn't get added to the file
> correctly.

Thanks for this new vesrion.

> 
> On Thu, 2022-04-14 at 13:20 -0700, Carl Love wrote:
> > Pedro, Will, Joel:
> > On Thu, 2022-04-14 at 14:05 +0100, Pedro Alves wrote:
> > > Hi Carl,
> > > 
> > > Some nits below.
> > 
> > Thanks for point out the typos.  I have fixed the typos in both
> > files. 
> > None of the include files are actually needed, I removed them in both
> > files. 
> > 
> > Please let me know is you see anything else.  Thanks.
> > 
> > I re-ran the tests on Power 10 to make sure I didn't break anything.
> 
> The following is the updated patch.  Sorry for the confusion.
> 
>                      Carl 
> 
> -------------------------------------------------------
> GDB Powerpc record test cases for ISA 2.06 and ISA 3.1

As mentioned by Pedro: PowerPC

> This patch adds Powerpc specific tests to verify recording of various

And here also.

> instructions.  The first test case checks the ISA 2.06 lxvd2x instruction.
> The second test case tests several of the ISA 3.01 instructions.  Specifically,
> it checks the word and prefixed instructions and some of the Matrix
> Multiply Assist (MMA) instructions.
> 
> The patch has been run on both Power 10 and Power 9 to verify the ISA
> 2.06 test case runs on both platforms without errors.  The ISA 3.1 test
> runs without errors on Power 10 and is skipped as expected on Power 9.
> ---
>  .../gdb.reverse/ppc_record_test_isa_2_06.c    |  39 ++
>  .../gdb.reverse/ppc_record_test_isa_2_06.exp  | 120 +++++
>  .../gdb.reverse/ppc_record_test_isa_3_1.c     |  95 ++++
>  .../gdb.reverse/ppc_record_test_isa_3_1.exp   | 492 ++++++++++++++++++
>  4 files changed, 746 insertions(+)
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> 
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
> new file mode 100644
> index 00000000000..45e58413da2
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
> @@ -0,0 +1,39 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2012-2022 Free Software Foundation, Inc.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +/* globals used for vector tests */
> +static vector unsigned long vec_xb;
> +static unsigned long ra, rb, rs;
> +
> +int
> +main ()
> +{
> +  ra = 0xABCDEF012;
> +  rb = 0;
> +  rs = 0x012345678;
> +
> +  /* 9.0, 16.0, 25.0, 36.0 */
> +  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
> +
> +  /* Test ISA 2.06 instructions.  Load source into vs1, result of sqrt
> +     put into vs0.  */
> +  ra = (unsigned long) & vec_xb;        /* stop 1 */
> +  __asm__ __volatile__ ("lxvd2x 1, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("xvsqrtsp 0, 1");
> +  ra = 0;                               /* stop 2 */
> +}
> +
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
> new file mode 100644
> index 00000000000..8ba8c1720ec
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
> @@ -0,0 +1,120 @@
> +# Copyright 2008-2022 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +#
> +# Test instruction record for PowerPC, ISA 2.06.
> +#
> +
> +# The basic flow of the record tests are:
> +#    1) Stop before executing the instructions of interest.  Record
> +#       the initial value of the registers that the instruction will
> +#       change, i.e. the destination register.
> +#    2) Execute the instructions.  Record the new value of the
> +#       registers that changed.
> +#    3) Reverse the direction of the execution and execute back to
> +#       just before the instructions of interest.  Record the final
> +#       value of the registers of interest.
> +#    4) Check that the initial and new values of the registers are
> +#       different, i.e. the instruction changed the registers as expected.
> +#    5) Check that the initial and final values of the registers are
> +#       the same, i.e. gdb record restored the registers to their
> +#       original values.
> +
> +standard_testfile
> +
> +set gen_src record_test_isa_2_06.c
> +set executable record_test_isa_2_06
> +set options [list debug]
> +
> +if {![istarget "powerpc*"]} then  {

Extra space before the last "{".

> +    verbose "Skipping PowerPC ISA 2.06 instruction record_test_2_06."
> +    return
> +}
> +
> +if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
> +    return -1
> +}
> +
> +clean_restart $executable
> +
> +if ![runto_main] then {
> +    untested "could not run to main"
> +    continue
> +}
> +
> +gdb_test_no_output "record"
> +
> +###### Test: Test an ISA 2.06 load (lxvd2x) and square root instruction
> +###### (xvsqrtsp).  The load instruction will load vs1.  The sqrt instruction
> +###### will put its result into vs0.
> +
> +set stop1 [gdb_get_line_number "stop 1"]
> +set stop2 [gdb_get_line_number "stop 2"]
> +
> +gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 1"
> +
> +# Record the initial values in vs0, vs1.
> +set vs0_initial [capture_command_output "info register vs0" ""]
> +set vs1_initial [capture_command_output "info register vs1" ""]
> +
> +gdb_test "break $stop2" ".*Breakpoint .*" "executed lxvd2x, xvsqrtsp"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 2"
> +
> +# Record the new values of vs0 and vs1.
> +set vs0_new [capture_command_output "info register vs0" ""]
> +set vs1_new [capture_command_output "info register vs1" ""]
> +
> +# Reverse the execution direction. 

small nit: Trailing space here.

> +gdb_test_no_output "set exec-direction reverse"
> +gdb_test "break $stop1" ".*Breakpoint .*" "un executed lxvd2x, xvsqrtsp"
> +
> +# Execute in reverse to before the lxvd2x instruction.
> +gdb_test "continue"  ".*Breakpoint.*" "at stop 1 in reverse"
> +
> +# Record the final values of vs0, vs1.
> +set vs0_final [capture_command_output "info register vs0" ""]
> +set vs1_final [capture_command_output "info register vs1" ""]
> +
> +# Check initial and new of vs0 are different.
> +set test_vs0_init_new "check vs0 initial versus vs0 new"
> +if {[string compare $vs0_initial $vs0_new] == 0} {
> +    fail $test_vs0_init_new
> +} else {
> +    pass $test_vs0_init_new
> +}

I looked at gdb_assert following Pedro's suggestion, and I agree
it would really simplify your testcase. Any reason why you didn't
follow his advice?

> +# Check initial and new of vs1 are different.
> +set test_vs1_init_new "check vs0 initial versus vs1 new"
> +if {[string compare $vs1_initial $vs1_new] == 0} {
> +    fail $test_vs1_init_new
> +} else {
> +    pass $test_vs1_init_new
> +}
> +
> +# Check initial and final are the same.
> +set test_vs0_init_final "check vs0 initial versus vs0 final"
> +if {[string compare $vs0_initial $vs0_final] == 0} {
> +    pass $test_vs0_init_final
> +} else {
> +    fail $test_vs0_init_final
> +}
> +
> +# Check initial and final are the same.
> +set test_vs1_init_final "check vs1 initial versus vs1 final"
> +if {[string compare $vs1_initial $vs1_final] == 0} {
> +    pass $test_vs1_init_final
> +} else {
> +    fail $test_vs1_init_final
> +}
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
> new file mode 100644
> index 00000000000..c0d65d944af
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
> @@ -0,0 +1,95 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2012-2022 Free Software Foundation, Inc.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +/* Globals used for vector tests.  */
> +static vector unsigned long vec_xa, vec_xb, vec_xt;
> +static unsigned long ra, rb, rs;
> +
> +int
> +main ()
> +{
> +  ra = 0xABCDEF012;
> +  rb = 0;
> +  rs = 0x012345678;
> +
> +  /* 9.0, 16.0, 25.0, 36.0 */
> +  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
> +
> +  vec_xt = (vector unsigned long){0xFF00FF00FF00FF00, 0xAA00AA00AA00AA00};
> +
> +  /* Test 1, ISA 3.1 word instructions. Load source into r1, result of brh
> +     put in r0.  */
> +  ra = 0xABCDEF012;                     /* stop 1 */
> +  __asm__ __volatile__ ("pld 1, %0" :: "r" (ra ));
> +  __asm__ __volatile__ ("brh 0, 1" );
> +  ra = 0;                               /* stop 2 */
> +
> +  /* Test 2, ISA 3.1 MMA instructions with results in various ACC entries
> +     xxsetaccz    - ACC[3]
> +     xvi4ger8     - ACC[4]
> +     xvf16ger2pn  - ACC[5]
> +     pmxvi8ger4   - ACC[6]
> +     pmxvf32gerpp - ACC[7] and fpscr */
> +  /* Need to initialize the vs registers to a non zero value.  */
> +  ra = (unsigned long) & vec_xb;
> +  __asm__ __volatile__ ("lxvd2x 12, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 13, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 14, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 15, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xa = (vector unsigned long){0x333134343987601, 0x9994bbbc9983307};
> +  vec_xb = (vector unsigned long){0x411234041898760, 0x41c833042103400};
> +  __asm__ __volatile__ ("lxvd2x 16, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x123456789987650, 0x235676546989807};
> +  __asm__ __volatile__ ("lxvd2x 17, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x878363439823470, 0x413434c99839870};
> +  __asm__ __volatile__ ("lxvd2x 18, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x043765434398760, 0x419876555558850};
> +  __asm__ __volatile__ ("lxvd2x 19, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x33313434398760, 0x9994bbbc99899330};
> +  __asm__ __volatile__ ("lxvd2x 20, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 21, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 22, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 23, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 24, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 25, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 26, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 27, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xa = (vector unsigned long){0x33313434398760, 0x9994bbbc998330};
> +  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
> +  __asm__ __volatile__ ("lxvd2x 28, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x4567000046800000, 0x4458000048700000};
> +  __asm__ __volatile__ ("lxvd2x 29, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x41dd000041e00000, 0x41c8000046544400};
> +  __asm__ __volatile__ ("lxvd2x 30, %0, %1" :: "r" (ra ), "r" (rb));
> +
> +  /* SNAN */
> +  vec_xb = (vector unsigned long){0x7F8F00007F8F0000, 0x7F8F00007F8F0000};
> +
> +  __asm__ __volatile__ ("lxvd2x 31, %0, %1" :: "r" (ra ), "r" (rb));
> +
> +  ra = 0xAB;                            /* stop 3 */
> +  __asm__ __volatile__ ("xxsetaccz 3");
> +  __asm__ __volatile__ ("xvi4ger8 4, %x0, %x1" :: "wa" (vec_xa), \
> +			"wa" (vec_xb) );
> +  __asm__ __volatile__ ("xvf16ger2pn 5, %x0, %x1" :: "wa" (vec_xa),\
> +			"wa" (vec_xb) );
> +  __asm__ __volatile__ ("pmxvi8ger4spp  6, %x0, %x1, 11, 13, 5"
> +                                :: "wa" (vec_xa), "wa" (vec_xb) );
> +  __asm__ __volatile__ ("pmxvf32gerpp  7, %x0, %x1, 11, 13"
> +                                :: "wa" (vec_xa), "wa" (vec_xb) );
> +  ra = 0;                               /* stop 4 */
> +}
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> new file mode 100644
> index 00000000000..07133c094ea
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> @@ -0,0 +1,492 @@
> +# Copyright 2008-2022 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +#
> +# Test instruction record for PowerPC, ISA 3.1.
> +#
> +
> +# The basic flow of the record tests are:
> +#    1) Stop before executing the instructions of interest.  Record
> +#       the initial value of the registers that the instruction will
> +#       change, i.e. the destination register.
> +#    2) Execute the instructions.  Record the new value of the
> +#       registers that changed.
> +#    3) Reverse the direction of the execution and execute back to
> +#       just before the instructions of interest.  Record the final
> +#       value of the registers of interest.
> +#    4) Check that the initial and new values of the registers are
> +#       different, i.e. the instruction changed the registers as expected.
> +#    5) Check that the initial and final values of the registers are
> +#       the same, i.e. gdb record restored the registers to their
> +#       original values.
> +
> +
> +standard_testfile
> +
> +set gen_src record_test_isa_3_1.c
> +set executable record_test_isa_3_1
> +
> +if {![istarget "powerpc*"] || [skip_power_isa_3_1_tests] } then  {
> +    verbose "Skipping Powerpc ISA 3.1 instruction record_test."
> +    return
> +}
> +
> +set options [list additional_flags=-mcpu=power10 debug]
> +if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
> +    return -1
> +}
> +
> +clean_restart $executable
> +
> +if ![runto_main] then {
> +    untested "could not run to main"
> +    continue
> +}
> +
> +gdb_test_no_output "record"
> +
> +######  Test 1:  Test an ISA 3.1 byte reverse word instruction (brd) and a
> +######   prefixed load double (pld) instruction.

FYI: Not sure if you intended to have 3 spaces after the hashes.

> +set stop1 [gdb_get_line_number "stop 1"]
> +set stop2 [gdb_get_line_number "stop 2"]
> +
> +gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test 1"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 1"
> +
> +# Record the initial values in r0, r1
> +# Load the argument into r1, result of byte reverse is put into r0.
> +set r0_initial [capture_command_output "info register r0" ""]
> +set r1_initial [capture_command_output "info register r1" ""]
> +
> +gdb_test "break $stop2" ".*Breakpoint .*" "executed test 1"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 2"
> +
> +# Record the new values of r0 and r1
> +set r0_new [capture_command_output "info register r0" ""]
> +set r1_new [capture_command_output "info register r1" ""]
> +
> +# Execute in reverse to before test 1
> +gdb_test "set exec-direction reverse" "" "reverse to start of test 1"
> +#gdb_test_no_output "set exec-direction reverse"

I just noticied this, because we normally avoid commented-out code
without a good reason behind it (which we also would typically
provide as a comment next to the code).

But looking at it more closely, I think the commented-out
version seems to be the correct one, not the one you are using.
In particular, there is an implicit ".*" at the start of the
expected output's matching in gdb_test, which means using ""
as the expected output is the same as matching anything.

> +gdb_test "break $stop1" ".*Breakpoint .*" "reverse stop at test 1 start"
> +gdb_test "continue"  ".*Breakpoint.*" "at stop 1 in reverse"
> +
> +# Record the final values of r0, r1
> +set r0_final [capture_command_output "info register r0" ""]
> +set r1_final [capture_command_output "info register r1" ""]
> +
> +# Check initial and new of r0 are different.
> +set test_r0_init_new "check r0 initial versus r0 new"
> +if {[string compare $r0_initial $r0_new] == 0} {
> +    fail $test_r0_init_new
> +} else {
> +    pass $test_r0_init_new
> +}
> +
> +# Check initial and new of r1 are different.
> +set test_r1_init_new "check r0 initial versus r1 new"
> +if {[string compare $r1_initial $r1_new] == 0} {
> +    fail $test_r1_init_new
> +} else {
> +    pass $test_r1_init_new
> +}
> +
> +# Check initial and final are the same.
> +set test_r0_init_final "check r0 initial versus r0 final"
> +if {[string compare $r0_initial $r0_final] == 0} {
> +    pass $test_r0_init_final
> +} else {
> +    fail $test_r0_init_final
> +}
> +
> +# Check initial and final are the same.
> +set test_r1_init_final "check r1 initial versus r1 final"
> +if {[string compare $r1_initial $r1_final] == 0} {
> +    pass $test_r1_init_final
> +} else {
> +    fail $test_r1_init_final
> +}
> +
> +
> +# Change execution direction to forward for next test.
> +gdb_test "set exec-direction forward" "" "start forward test3"

Same as above, re: gdb_test_no_output.

> +gdb_test "record stop" ".*Process record is stopped.*" "stopped recording 2"
> +set test_del_bkpts "delete breakpoints, answer prompt 2"
> +
> +# Delete all breakpoints and catchpoints.
> +delete_breakpoints
> +
> +gdb_test "record" "" "start recording test2"

Same here.

> +
> +
> +######  Test 2:  Test the ISA 3.1 MMA instructions xxsetaccz, xvi4ger8,
> +######  xvf16ger2pn, pmxvi8ger4, and pmxvf32gerpp.  Goal here is to hit all
> +######  the places where ppc_record_ACC_fpscr() gets called.
> +##
> +##       xxsetaccz    - ACC[3], vs[12] to vs[15]
> +##       xvi4ger8     - ACC[4], vs[16] to vs[19]
> +##       xvf16ger2pn  - ACC[5], vs[20] to vs[23]
> +##       pmxvi8ger4   - ACC[6], vs[21] to vs[27]
> +##       pmxvf32gerpp - ACC[7], vs[28] to vs[31] and fpscr
> +
> +set stop3 [gdb_get_line_number "stop 3"]
> +set stop4 [gdb_get_line_number "stop 4"]
> +
> +gdb_test "break $stop3" ".*Breakpoint .*" "about to execute test 2"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 3"
> +
> +# Record the initial values of vs's that correspond to the ACC entries,
> +# and fpscr.
> +set acc_3_0_initial [capture_command_output "info register vs12" ""]
> +set acc_3_1_initial [capture_command_output "info register vs13" ""]
> +set acc_3_2_initial [capture_command_output "info register vs14" ""]
> +set acc_3_3_initial [capture_command_output "info register vs15" ""]
> +set acc_4_0_initial [capture_command_output "info register vs16" ""]
> +set acc_4_1_initial [capture_command_output "info register vs17" ""]
> +set acc_4_2_initial [capture_command_output "info register vs18" ""]
> +set acc_4_3_initial [capture_command_output "info register vs19" ""]
> +set acc_5_0_initial [capture_command_output "info register vs20" ""]
> +set acc_5_1_initial [capture_command_output "info register vs21" ""]
> +set acc_5_2_initial [capture_command_output "info register vs22" ""]
> +set acc_5_3_initial [capture_command_output "info register vs23" ""]
> +set acc_6_0_initial [capture_command_output "info register vs24" ""]
> +set acc_6_1_initial [capture_command_output "info register vs25" ""]
> +set acc_6_2_initial [capture_command_output "info register vs26" ""]
> +set acc_6_3_initial [capture_command_output "info register vs27" ""]
> +set acc_7_0_initial [capture_command_output "info register vs28" ""]
> +set acc_7_1_initial [capture_command_output "info register vs29" ""]
> +set acc_7_2_initial [capture_command_output "info register vs30" ""]
> +set acc_7_3_initial [capture_command_output "info register vs31" ""]
> +set fpscr_initial [capture_command_output "info register fpscr" ""]
> +
> +gdb_test "break $stop4" ".*Breakpoint .*" "executed test 2"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 4"
> +
> +# Record the new values of the ACC entries and fpscr.
> +set acc_3_0_new [capture_command_output "info register vs12" ""]
> +set acc_3_1_new [capture_command_output "info register vs13" ""]
> +set acc_3_2_new [capture_command_output "info register vs14" ""]
> +set acc_3_3_new [capture_command_output "info register vs15" ""]
> +set acc_4_0_new [capture_command_output "info register vs16" ""]
> +set acc_4_1_new [capture_command_output "info register vs17" ""]
> +set acc_4_2_new [capture_command_output "info register vs18" ""]
> +set acc_4_3_new [capture_command_output "info register vs19" ""]
> +set acc_5_0_new [capture_command_output "info register vs20" ""]
> +set acc_5_1_new [capture_command_output "info register vs21" ""]
> +set acc_5_2_new [capture_command_output "info register vs22" ""]
> +set acc_5_3_new [capture_command_output "info register vs23" ""]
> +set acc_6_0_new [capture_command_output "info register vs24" ""]
> +set acc_6_1_new [capture_command_output "info register vs25" ""]
> +set acc_6_2_new [capture_command_output "info register vs26" ""]
> +set acc_6_3_new [capture_command_output "info register vs27" ""]
> +set acc_7_0_new [capture_command_output "info register vs28" ""]
> +set acc_7_1_new [capture_command_output "info register vs29" ""]
> +set acc_7_2_new [capture_command_output "info register vs30" ""]
> +set acc_7_3_new [capture_command_output "info register vs31" ""]
> +set fpscr_new [capture_command_output "info register fpscr" ""]
> +
> +# Execute in reverse to before test 2.
> +gdb_test "set exec-direction reverse" "" "reverse to start of test 2"

Same here.

> +
> +gdb_test "break $stop3" ".*Breakpoint .*" "reverse stop at test 2 start"
> +gdb_test "continue"  ".*Breakpoint.*" "at stop 3 in reverse"
> +
> +# Record the final values of the ACC entries and fpscr.
> +set acc_3_0_final [capture_command_output "info register vs12" ""]
> +set acc_3_1_final [capture_command_output "info register vs13" ""]
> +set acc_3_2_final [capture_command_output "info register vs14" ""]
> +set acc_3_3_final [capture_command_output "info register vs15" ""]
> +set acc_4_0_final [capture_command_output "info register vs16" ""]
> +set acc_4_1_final [capture_command_output "info register vs17" ""]
> +set acc_4_2_final [capture_command_output "info register vs18" ""]
> +set acc_4_3_final [capture_command_output "info register vs19" ""]
> +set acc_5_0_final [capture_command_output "info register vs20" ""]
> +set acc_5_1_final [capture_command_output "info register vs21" ""]
> +set acc_5_2_final [capture_command_output "info register vs22" ""]
> +set acc_5_3_final [capture_command_output "info register vs23" ""]
> +set acc_6_0_final [capture_command_output "info register vs24" ""]
> +set acc_6_1_final [capture_command_output "info register vs25" ""]
> +set acc_6_2_final [capture_command_output "info register vs26" ""]
> +set acc_6_3_final [capture_command_output "info register vs27" ""]
> +set acc_7_0_final [capture_command_output "info register vs28" ""]
> +set acc_7_1_final [capture_command_output "info register vs29" ""]
> +set acc_7_2_final [capture_command_output "info register vs30" ""]
> +set acc_7_3_final [capture_command_output "info register vs31" ""]
> +set fpscr_final [capture_command_output "info register fpscr" ""]
> +
> +# check initial and new ACC entries.
> +set test_acc_3_0_init_new "check vs12 initial versus new"
> +if {[string compare $acc_3_0_initial $acc_3_0_new] == 0} {
> +    fail $test_acc_3_0_init_new
> +} else {
> +    pass $test_acc_3_0_init_new
> +}
> +set test_acc_3_1_init_new "check vs13 initial versus new"
> +if {[string compare $acc_3_1_initial $acc_3_1_new] == 0} {
> +    fail $test_acc_3_1_init_new
> +} else {
> +    pass $test_acc_3_1_init_new
> +}
> +set test_acc_3_2_init_new "check vs14 initial versus new"
> +if {[string compare $acc_3_2_initial $acc_3_2_new] == 0} {
> +    fail $test_acc_3_2_init_new
> +} else {
> +    pass $test_acc_3_2_init_new
> +}
> +set test_acc_3_3_init_new "check vs15 initial versus new"
> +if {[string compare $acc_3_3_initial $acc_3_3_new] == 0} {
> +    fail $test_acc_3_3_init_new
> +} else {
> +    pass $test_acc_3_3_init_new
> +}
> +
> +set test_acc_4_0_init_new "check vs16 initial versus new"
> +if {[string compare $acc_4_0_initial $acc_4_0_new] == 0} {
> +    fail $test_acc_4_0_init_new
> +} else {
> +    pass $test_acc_4_0_init_new
> +}
> +set test_acc_4_1_init_new "check vs17 initial versus new"
> +if {[string compare $acc_4_1_initial $acc_4_1_new] == 0} {
> +    fail $test_acc_4_1_init_new
> +} else {
> +    pass $test_acc_4_1_init_new
> +}
> +set test_acc_4_2_init_new "check vs18 initial versus new"
> +if {[string compare $acc_4_2_initial $acc_4_2_new] == 0} {
> +    fail $test_acc_4_2_init_new
> +} else {
> +    pass $test_acc_4_2_init_new
> +}
> +set test_acc_4_3_init_new "check vs19 initial versus new"
> +if {[string compare $acc_4_3_initial $acc_4_3_new] == 0} {
> +    fail $test_acc_4_3_init_new
> +} else {
> +    pass $test_acc_4_3_init_new
> +}
> +
> +set test_acc_5_0_init_new "check vs20 initial versus new"
> +if {[string compare $acc_5_0_initial $acc_5_0_new] == 0} {
> +    fail $test_acc_5_0_init_new
> +} else {
> +    pass $test_acc_5_0_init_new
> +}
> +set test_acc_5_1_init_new "check vs21 initial versus new"
> +if {[string compare $acc_5_1_initial $acc_5_1_new] == 0} {
> +    fail $test_acc_5_1_init_new
> +} else {
> +    pass $test_acc_5_1_init_new
> +}
> +set test_acc_5_2_init_new "check vs22 initial versus new"
> +if {[string compare $acc_5_2_initial $acc_5_2_new] == 0} {
> +    fail $test_acc_5_2_init_new
> +} else {
> +    pass $test_acc_5_2_init_new
> +}
> +set test_acc_5_3_init_new "check vs23 initial versus new"
> +if {[string compare $acc_5_3_initial $acc_5_3_new] == 0} {
> +    fail $test_acc_5_3_init_new
> +} else {
> +    pass $test_acc_5_3_init_new
> +}
> +
> +set test_acc_6_0_init_new "check vs24 initial versus new"
> +if {[string compare $acc_6_0_initial $acc_6_0_new] == 0} {
> +    fail $test_acc_6_0_init_new
> +} else {
> +    pass $test_acc_6_0_init_new
> +}
> +set test_acc_6_1_init_new "check vs25 initial versus new"
> +if {[string compare $acc_6_1_initial $acc_6_1_new] == 0} {
> +    fail $test_acc_6_1_init_new
> +} else {
> +    pass $test_acc_6_1_init_new
> +}
> +set test_acc_6_2_init_new "check vs26 initial versus new"
> +if {[string compare $acc_6_2_initial $acc_6_2_new] == 0} {
> +    fail $test_acc_6_2_init_new
> +} else {
> +    pass $test_acc_6_2_init_new
> +}
> +set test_acc_6_3_init_new "check vs27 initial versus new"
> +if {[string compare $acc_6_3_initial $acc_6_3_new] == 0} {
> +    fail $test_acc_6_3_init_new
> +} else {
> +    pass $test_acc_6_3_init_new
> +}
> +
> +set test_acc_7_0_init_new "check vs28 initial versus new"
> +if {[string compare $acc_7_0_initial $acc_7_0_new] == 0} {
> +    fail $test_acc_7_0_init_new
> +} else {
> +    pass $test_acc_7_0_init_new
> +}
> +set test_acc_7_1_init_new "check vs29 initial versus new"
> +if {[string compare $acc_7_1_initial $acc_7_1_new] == 0} {
> +    fail $test_acc_7_1_init_new
> +} else {
> +    pass $test_acc_7_1_init_new
> +}
> +set test_acc_7_2_init_new "check vs30 initial versus new"
> +if {[string compare $acc_7_2_initial $acc_7_2_new] == 0} {
> +    fail $test_acc_7_2_init_new
> +} else {
> +    pass $test_acc_7_2_init_new
> +}
> +set test_acc_7_3_init_new "check vs31 initial versus new"
> +if {[string compare $acc_7_3_initial $acc_7_3_new] == 0} {
> +    fail $test_acc_7_3_init_new
> +} else {
> +    pass $test_acc_7_3_init_new
> +}
> +set test_fpscr_init_new "check fpscr initial versus new"
> +if {[string compare $fpscr_initial $fpscr_new] == 0} {
> +    fail $test_fpscr_init_new
> +} else {
> +    pass $test_fpscr_init_new
> +}
> +
> +# Check initial and new ACC entries are different.
> +set test_acc_3_0_init_final "check vs12 initial versus final"
> +if {[string compare $acc_3_0_initial $acc_3_0_final] == 0} {
> +    pass $test_acc_3_0_init_final
> +} else {
> +    fail $test_acc_3_0_init_final
> +}
> +set test_acc_3_1_init_final "check vs13 initial versus final"
> +if {[string compare $acc_3_1_initial $acc_3_1_final] == 0} {
> +    pass $test_acc_3_1_init_final
> +} else {
> +    fail $test_acc_3_0_init_final
> +}
> +set test_acc_3_2_init_final "check vs14 initial versus final"
> +if {[string compare $acc_3_2_initial $acc_3_2_final] == 0} {
> +    pass $test_acc_3_2_init_final
> +} else {
> +    fail $test_acc_3_2_init_final
> +}
> +set test_acc_3_3_init_final "check vs15 initial versus final"
> +if {[string compare $acc_3_3_initial $acc_3_3_final] == 0} {
> +    pass $test_acc_3_3_init_final
> +} else {
> +    new $test_acc_3_3_init_final
> +}
> +
> +set test_acc_4_0_init_final "check vs16 initial versus final"
> +if {[string compare $acc_4_0_initial $acc_4_0_final] == 0} {
> +    pass $test_acc_4_0_init_final
> +} else {
> +    new $test_acc_4_0_init_final
> +}
> +set test_acc_4_1_init_final "check vs17 initial versus final"
> +if {[string compare $acc_4_1_initial $acc_4_1_final] == 0} {
> +    pass $test_acc_4_1_init_final
> +} else {
> +    new $test_acc_4_0_init_final
> +}
> +set test_acc_4_2_init_final "check vs18 initial versus final"
> +if {[string compare $acc_4_2_initial $acc_4_2_final] == 0} {
> +    pass $test_acc_4_2_init_final
> +} else {
> +    new $test_acc_4_2_init_final
> +}
> +set test_acc_4_3_init_final "check vs19 initial versus final"
> +if {[string compare $acc_4_3_initial $acc_4_3_final] == 0} {
> +    pass $test_acc_4_3_init_final
> +} else {
> +    fail $test_acc_4_3_init_final
> +}
> +
> +set test_acc_5_0_init_final "check vs20 initial versus final"
> +if {[string compare $acc_5_0_initial $acc_5_0_final] == 0} {
> +    pass $test_acc_5_0_init_final
> +} else {
> +    fail $test_acc_5_0_init_final
> +}
> +set test_acc_5_1_init_final "check vs21 initial versus final"
> +if {[string compare $acc_5_1_initial $acc_5_1_final] == 0} {
> +    pass $test_acc_5_1_init_final
> +} else {
> +    fail $test_acc_5_0_init_final
> +}
> +set test_acc_5_2_init_final "check vs22 initial versus final"
> +if {[string compare $acc_5_2_initial $acc_5_2_final] == 0} {
> +    pass $test_acc_5_2_init_final
> +} else {
> +    fail $test_acc_5_2_init_final
> +}
> +set test_acc_5_3_init_final "check vs23 initial versus final"
> +if {[string compare $acc_5_3_initial $acc_5_3_final] == 0} {
> +    pass $test_acc_5_3_init_final
> +} else {
> +    fail $test_acc_5_3_init_final
> +}
> +
> +set test_acc_6_0_init_final "check vs24 initial versus final"
> +if {[string compare $acc_6_0_initial $acc_6_0_final] == 0} {
> +    pass $test_acc_6_0_init_final
> +} else {
> +    fail $test_acc_6_0_init_final
> +}
> +set test_acc_6_1_init_final "check vs25 initial versus final"
> +if {[string compare $acc_6_1_initial $acc_6_1_final] == 0} {
> +    pass $test_acc_6_1_init_final
> +} else {
> +    fail $test_acc_6_0_init_final
> +}
> +set test_acc_6_2_init_final "check vs26 initial versus final"
> +if {[string compare $acc_6_2_initial $acc_6_2_final] == 0} {
> +    pass $test_acc_6_2_init_final
> +} else {
> +    fail $test_acc_6_2_init_final
> +}
> +set test_acc_6_3_init_final "check vs27 initial versus final"
> +if {[string compare $acc_6_3_initial $acc_6_3_final] == 0} {
> +    pass $test_acc_6_3_init_final
> +} else {
> +    fail $test_acc_6_3_init_final
> +}
> +
> +set test_acc_7_0_init_final "check vs28 initial versus final"
> +if {[string compare $acc_7_0_initial $acc_7_0_final] == 0} {
> +    pass $test_acc_7_0_init_final
> +} else {
> +    fail $test_acc_7_0_init_final
> +}
> +set test_acc_7_1_init_final "check vs29 initial versus final"
> +if {[string compare $acc_7_1_initial $acc_7_1_final] == 0} {
> +    pass $test_acc_7_1_init_final
> +} else {
> +    fail $test_acc_7_0_init_final
> +}
> +set test_acc_7_2_init_final "check vs30 initial versus final"
> +if {[string compare $acc_7_2_initial $acc_7_2_final] == 0} {
> +    pass $test_acc_7_2_init_final
> +} else {
> +    fail $test_acc_7_2_init_final
> +}
> +set test_acc_7_3_init_final "check vs31 initial versus final"
> +if {[string compare $acc_7_3_initial $acc_7_3_final] == 0} {
> +    pass $test_acc_7_3_init_final
> +} else {
> +    fail $test_acc_7_3_init_final
> +}
> +set test_fpscr_init_final "check fpscr initial versus final"
> +if {[string compare $fpscr_initial $fpscr_final] == 0} {
> +    pass $test_fpscr_init_final
> +} else {
> +    fail $test_fpscr_init_final
> +}
> +
> -- 
> 2.31.1
> 
> 

-- 
Joel

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/2  Version 5] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-17 16:23           ` Joel Brobecker
@ 2022-04-18 19:21             ` Carl Love
  2022-04-22 19:49               ` [PATCH 1/2 Version 5 Ping] " Carl Love
  2022-04-24 16:50               ` [PATCH 1/2 Version 5] " Joel Brobecker
  0 siblings, 2 replies; 25+ messages in thread
From: Carl Love @ 2022-04-18 19:21 UTC (permalink / raw)
  To: Joel Brobecker, cel
  Cc: will schmidt, gdb-patches, Ulrich Weigand, Tulio Magno, Rogerio Alves

Joel, Pedro, Will, GDB maintainers:

On Sun, 2022-04-17 at 09:23 -0700, Joel Brobecker wrote:
> On Wed, Apr 13, 2022 at 10:26:47AM -0700, Carl Love wrote:
> 
> > Add recording support for the ISA 3.1 Powerpc instructions.
> 
> Thanks for the updated version. I have a few more requests of
> a trivial natural (Coding Style, and I apologize if this is a bit
> frustrating for you - I wish we had a tool like in python that
> we could use to just automate the whole thing...).

Yea, it would speed things up.  GCC has a script that runs when you try
to checkin a patch.  Not sure how much coding style it checks.  It does
check the change log entries.  It would be nice to have a stand alone
script that could be run on a patch to check coding style before
posting or committing a patch.  It would save a lot of time and effort.


I updated the patch with the typos you mentioned and found an
additional one as well.  I updated the header comment for
ppc_record_ACC_fpscr().  I think it is simpler and cleaner now.

This patch was retested with the updated (version 5) testcases to
verify the patch is still ok.

                     Carl 

-----------------------------------------------------------------
Add recording support for the ISA 3.1 PowerPC instructions.

This patch adds support for the PowerPC ISA 3.1 instructions to the PowerPC
gdb instruction recording routines.  Case statement entries are added to a
number of the existing routines for recording the 32-bit word instructions.
A few new functions were added to handle the new word instructions.  The 64-bit
prefix instructions are all handled by a set of new routines.  The function
ppc_process_prefix_instruction() is the primary function to handle the
prefixed instructions. It calls additional functions to handle specific
sets of prefixed instructions.  These new functions are:
  ppc_process_record_prefix_vsx_d_form(),
  ppc_process_record_prefix_store_vsx_ds_form(),
  ppc_process_record_prefix_op34(),
  ppc_process_record_prefix_op33(),
  ppc_process_record_prefix_op32(),
  ppc_process_record_prefix_store(),
  ppc_process_record_prefix_op59_XX3(),
  ppc_process_record_prefix_op42().
---
 gdb/rs6000-tdep.c | 1197 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 1171 insertions(+), 26 deletions(-)

diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 44828bcff6d..8259d9d8454 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -4123,8 +4123,25 @@ bfd_uses_spe_extensions (bfd *abfd)
 #define PPC_LEV(insn)	PPC_FIELD (insn, 20, 7)
 
 #define PPC_XT(insn)	((PPC_TX (insn) << 5) | PPC_T (insn))
+#define PPC_XTp(insn)	((PPC_BIT (insn, 10) << 5)	\
+			 | PPC_FIELD (insn, 6, 4) << 1)
+#define PPC_XSp(insn)	((PPC_BIT (insn, 10) << 5)	\
+			 | PPC_FIELD (insn, 6, 4) << 1)
 #define PPC_XER_NB(xer)	(xer & 0x7f)
 
+/* The following macros are for the prefixed instructions.  */
+#define P_PPC_D(insn_prefix, insn_suffix) \
+  PPC_SEXT (PPC_FIELD (insn_prefix, 14, 18) << 16 \
+	    | PPC_FIELD (insn_suffix, 16, 16), 34)
+#define P_PPC_TX5(insn_sufix)	PPC_BIT (insn_suffix, 5)
+#define P_PPC_TX15(insn_suffix) PPC_BIT (insn_suffix, 15)
+#define P_PPC_XT(insn_suffix)	((PPC_TX (insn_suffix) << 5) \
+				 | PPC_T (insn_suffix))
+#define P_PPC_XT5(insn_suffix) ((P_PPC_TX5 (insn_suffix) << 5) \
+				| PPC_T (insn_suffix))
+#define P_PPC_XT15(insn_suffix) \
+  ((P_PPC_TX15 (insn_suffix) << 5) | PPC_T (insn_suffix))
+
 /* Record Vector-Scalar Registers.
    For VSR less than 32, it's represented by an FPR and an VSR-upper register.
    Otherwise, it's just a VR register.  Record them accordingly.  */
@@ -4152,6 +4169,61 @@ ppc_record_vsr (struct regcache *regcache, ppc_gdbarch_tdep *tdep, int vsr)
   return 0;
 }
 
+/* The ppc_record_ACC_fpscr() records the changes to the VSR registers
+   modified by a floating point instruction.  The at argument gives which of
+   the 8 AT entries to record.  The save_fpscr argument is used to indicate
+   if the FPSCR also needs to be recorded.  The function returns 0 on
+   success.  */
+
+#define RECORD_FPSCR 1
+#define DO_NOT_RECORD_FPSCR 0
+
+static int
+ppc_record_ACC_fpscr (struct regcache *regcache, ppc_gdbarch_tdep *tdep,
+		      int at, int save_fpscr)
+{
+  int i;
+  if (at < 0 || at >= 8)
+    return -1;
+
+  /* The ACC register file consists of 8 register entries, each register
+     entry consist of four 128-bit rows.
+
+     The ACC rows map to specific VSR registers.
+         ACC[0][0] -> VSR[0]
+         ACC[0][1] -> VSR[1]
+         ACC[0][2] -> VSR[2]
+         ACC[0][3] -> VSR[3]
+              ...
+         ACC[7][0] -> VSR[28]
+         ACC[7][1] -> VSR[29]
+         ACC[7][2] -> VSR[30]
+         ACC[7][3] -> VSR[31]
+
+     NOTE:
+     In ISA 3.1 the ACC is mapped on top of VSR[0] thru VSR[31].
+
+     In the future, the ACC may be implemented as an independent register file
+     rather than mapping on top of the VSRs.  This will then require the ACC to
+     be assigned its own register number and the ptrace interface to be able
+     access the ACC.  Note the ptrace interface for the ACC will also need to
+     be implemented.  */
+
+  /* ACC maps over the same VSR space as the fp registers.  */
+  for (i = 0; i < 4; i++)
+    {
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fp0_regnum
+				     + at * 4 + i);
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_vsr0_upper_regnum + at * 4 + i);
+    }
+
+  if (save_fpscr)
+    record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+
+  return 0;
+}
+
 /* Parse and record instructions primary opcode-4 at ADDR.
    Return 0 if successful.  */
 
@@ -4171,9 +4243,34 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 41:		/* Vector Multiply-Sum Signed Halfword Saturate */
       record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
       /* FALL-THROUGH */
+    case 20:		/* Move To VSR Byte Mask Immediate opcode, b2 = 0,
+			   ignore bit 31 */
+    case 21:		/* Move To VSR Byte Mask Immediate opcode, b2 = 1,
+			   ignore bit 31 */
+    case 23:		/* Vector Multiply-Sum & write Carry-out Unsigned
+			   Doubleword */
+    case 24:		/* Vector Extract Double Unsigned Byte to VSR
+			   using GPR-specified Left-Index */
+    case 25:		/* Vector Extract Double Unsigned Byte to VSR
+			   using GPR-specified Right-Index */
+    case 26:		/* Vector Extract Double Unsigned Halfword to VSR
+			   using GPR-specified Left-Index */
+    case 27:		/* Vector Extract Double Unsigned Halfword to VSR
+			   using GPR-specified Right-Index */
+    case 28:		/* Vector Extract Double Unsigned Word to VSR
+			   using GPR-specified Left-Index */
+    case 29:		/* Vector Extract Double Unsigned Word to VSR
+			   using GPR-specified Right-Index */
+    case 30:		/* Vector Extract Double Unsigned Doubleword to VSR
+			   using GPR-specified Left-Index */
+    case 31:		/* Vector Extract Double Unsigned Doubleword to VSR
+			   using GPR-specified Right-Index */
     case 42:		/* Vector Select */
     case 43:		/* Vector Permute */
     case 59:		/* Vector Permute Right-indexed */
+    case 22: 		/* Vector Shift
+			      Left  Double by Bit Immediate if insn[21] = 0
+			      Right Double by Bit Immediate if insn[21] = 1 */
     case 44:		/* Vector Shift Left Double by Octet Immediate */
     case 45:		/* Vector Permute and Exclusive-OR */
     case 60:		/* Vector Add Extended Unsigned Quadword Modulo */
@@ -4236,6 +4333,9 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
   /* Bit-21 is used for RC */
   switch (ext & 0x3ff)
     {
+    case 5:		/* Vector Rotate Left Quadword */
+    case 69:		/* Vector Rotate Left Quadword then Mask Insert */
+    case 325:		/* Vector Rotate Left Quadword then AND with Mask */
     case 6:		/* Vector Compare Equal To Unsigned Byte */
     case 70:		/* Vector Compare Equal To Unsigned Halfword */
     case 134:		/* Vector Compare Equal To Unsigned Word */
@@ -4244,13 +4344,16 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     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 903:		/* Vector Compare Greater Than Signed Quadword */
     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 647:		/* Vector Compare Greater Than Unsigned Quadword */
     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 455:		/* Vector Compare Equal Quadword */
     case 710:		/* Vector Compare Greater Than Single-Precision */
     case 7:		/* Vector Compare Not Equal Byte */
     case 71:		/* Vector Compare Not Equal Halfword */
@@ -4263,6 +4366,21 @@ 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 13:
+      switch (vra)    /* Bit-21 is used for RC */
+	{
+	case 0:       /* Vector String Isolate Byte Left-justified */
+	case 1:       /* Vector String Isolate Byte Right-justified */
+	case 2:       /* Vector String Isolate Halfword Left-justified */
+	case 3:       /* Vector String Isolate Halfword Right-justified */
+	  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;
+	}
     }
 
   if (ext  == 1538)
@@ -4287,6 +4405,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
 	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 27:	/* Vector Extend Sign Doubleword To Quadword */
 	case 28:	/* Vector Count Trailing Zeros Byte */
 	case 29:	/* Vector Count Trailing Zeros Halfword */
 	case 30:	/* Vector Count Trailing Zeros Word */
@@ -4297,8 +4416,57 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
 	}
     }
 
+  if (ext == 1602)
+    {
+      switch (vra)
+	{
+	case 0: 	/* Vector Expand Byte Mask */
+	case 1: 	/* Vector Expand Halfword Mask */
+	case 2: 	/* Vector Expand Word Mask */
+	case 3: 	/* Vector Expand Doubleword Mask */
+	case 4: 	/* Vector Expand Quadword Mask */
+	case 16:	/* Move to VSR Byte Mask */
+	case 17:	/* Move to VSR Halfword Mask */
+	case 18:	/* Move to VSR Word Mask */
+	case 19:	/* Move to VSR Doubleword Mask */
+	case 20:	/* Move to VSR Quadword Mask */
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+	  return 0;
+
+	case 8: 	/* Vector Extract Byte Mask */
+	case 9: 	/* Vector Extract Halfword Mask */
+	case 10: 	/* Vector Extract Word Mask */
+	case 11: 	/* Vector Extract Doubleword Mask */
+	case 12: 	/* Vector Extract Quadword Mask */
+
+	/* Ignore the MP bit in the LSB position of the vra value. */
+	case 24:	/* Vector Count Mask Bits Byte, MP = 0 */
+	case 25:	/* Vector Count Mask Bits Byte, MP = 1 */
+	case 26:	/* Vector Count Mask Bits Halfword, MP = 0 */
+	case 27:	/* Vector Count Mask Bits Halfword, MP = 1 */
+	case 28:	/* Vector Count Mask Bits Word, MP = 0 */
+	case 29:	/* Vector Count Mask Bits Word, MP = 1 */
+	case 30:	/* Vector Count Mask Bits Doubleword, MP = 0 */
+	case 31:	/* Vector Count Mask Bits Doubleword, MP = 1 */
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_gp0_regnum + PPC_RT (insn));
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_gp0_regnum + PPC_RT (insn));
+	  return 0;
+	}
+    }
+
   switch (ext)
     {
+
+    case 257:		/* Vector Compare Unsigned Quadword */
+    case 321:		/* Vector Compare Signed Quadword */
+      /* Comparison tests that always set CR field BF */
+      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;
+
     case 142:		/* Vector Pack Unsigned Halfword Unsigned Saturate */
     case 206:		/* Vector Pack Unsigned Word Unsigned Saturate */
     case 270:		/* Vector Pack Signed Halfword Unsigned Saturate */
@@ -4338,6 +4506,8 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 268:		/* Vector Merge Low Byte */
     case 332:		/* Vector Merge Low Halfword */
     case 396:		/* Vector Merge Low Word */
+    case 397:		/* Vector Clear Leftmost Bytes */
+    case 461:		/* Vector Clear Rightmost Bytes */
     case 526:		/* Vector Unpack High Signed Byte */
     case 590:		/* Vector Unpack High Signed Halfword */
     case 654:		/* Vector Unpack Low Signed Byte */
@@ -4356,8 +4526,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 780:		/* Vector Splat Immediate Signed Byte */
     case 844:		/* Vector Splat Immediate Signed Halfword */
     case 908:		/* Vector Splat Immediate Signed Word */
+    case 261:		/* Vector Shift Left Quadword */
     case 452:		/* Vector Shift Left */
+    case 517:		/* Vector Shift Right Quadword */
     case 708:		/* Vector Shift Right */
+    case 773:		/* Vector Shift Right Algebraic Quadword */
     case 1036:		/* Vector Shift Left by Octet */
     case 1100:		/* Vector Shift Right by Octet */
     case 0:		/* Vector Add Unsigned Byte Modulo */
@@ -4370,15 +4543,43 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 8:		/* Vector Multiply Odd Unsigned Byte */
     case 72:		/* Vector Multiply Odd Unsigned Halfword */
     case 136:		/* Vector Multiply Odd Unsigned Word */
+    case 200:		/* Vector Multiply Odd Unsigned Doubleword */
     case 264:		/* Vector Multiply Odd Signed Byte */
     case 328:		/* Vector Multiply Odd Signed Halfword */
     case 392:		/* Vector Multiply Odd Signed Word */
+    case 456:		/* Vector Multiply Odd Signed Doubleword */
     case 520:		/* Vector Multiply Even Unsigned Byte */
     case 584:		/* Vector Multiply Even Unsigned Halfword */
     case 648:		/* Vector Multiply Even Unsigned Word */
+    case 712:		/* Vector Multiply Even Unsigned Doubleword */
     case 776:		/* Vector Multiply Even Signed Byte */
     case 840:		/* Vector Multiply Even Signed Halfword */
     case 904:		/* Vector Multiply Even Signed Word */
+    case 968:		/* Vector Multiply Even Signed Doubleword */
+    case 457:		/* Vector Multiply Low Doubleword */
+    case 649:		/* Vector Multiply High Unsigned Word */
+    case 713:		/* Vector Multiply High Unsigned Doubleword */
+    case 905:		/* Vector Multiply High Signed Word */
+    case 969:		/* Vector Multiply High Signed Doubleword */
+    case 11:		/* Vector Divide Unsigned Quadword */
+    case 203:		/* Vector Divide Unsigned Doubleword */
+    case 139:		/* Vector Divide Unsigned Word */
+    case 267:		/* Vector Divide Signed Quadword */
+    case 459:		/* Vector Divide Signed Doubleword */
+    case 395:		/* Vector Divide Signed Word */
+    case 523:		/* Vector Divide Extended Unsigned Quadword */
+    case 715:		/* Vector Divide Extended Unsigned Doubleword */
+    case 651:		/* Vector Divide Extended Unsigned Word */
+    case 779:		/* Vector Divide Extended Signed Quadword */
+    case 971:		/* Vector Divide Extended Signed Doubleword */
+    case 907:		/* Vector Divide Extended Unsigned Word */
+    case 1547:		/* Vector Modulo Unsigned Quadword */
+    case 1675:		/* Vector Modulo Unsigned Word */
+    case 1739:		/* Vector Modulo Unsigned Doubleword */
+    case 1803:		/* Vector Modulo Signed Quadword */
+    case 1931:		/* Vector Modulo Signed Word */
+    case 1995:		/* Vector Modulo Signed Doubleword */
+
     case 137:		/* Vector Multiply Unsigned Word Modulo */
     case 1024:		/* Vector Subtract Unsigned Byte Modulo */
     case 1088:		/* Vector Subtract Unsigned Halfword Modulo */
@@ -4462,7 +4663,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 1794:		/* Vector Count Leading Zeros Byte */
     case 1858:		/* Vector Count Leading Zeros Halfword */
     case 1922:		/* Vector Count Leading Zeros Word */
+    case 1924:		/* Vector Count Leading Zeros Doubleword under
+			   bit Mask*/
     case 1986:		/* Vector Count Leading Zeros Doubleword */
+    case 1988:		/* Vector Count Trailing Zeros Doubleword under bit
+			   Mask */
     case 1795:		/* Vector Population Count Byte */
     case 1859:		/* Vector Population Count Halfword */
     case 1923:		/* Vector Population Count Word */
@@ -4488,14 +4693,50 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 589:		/* Vector Extract Unsigned Halfword */
     case 653:		/* Vector Extract Unsigned Word */
     case 717:		/* Vector Extract Doubleword */
+    case 15:		/* Vector Insert Byte from VSR using GPR-specified
+			   Left-Index */
+    case 79:		/* Vector Insert Halfword from VSR using GPR-specified
+			   Left-Index */
+    case 143:		/* Vector Insert Word from VSR using GPR-specified
+			   Left-Index */
+    case 207:		/* Vector Insert Word from GPR using
+			   immediate-specified index */
+    case 463:		/* Vector Insert Doubleword from GPR using
+			   immediate-specified index */
+    case 271:		/* Vector Insert Byte from VSR using GPR-specified
+			   Right-Index */
+    case 335:		/* Vector Insert Halfword from VSR using GPR-specified
+			   Right-Index */
+    case 399:		/* Vector Insert Word from VSR using GPR-specified
+			   Right-Index */
+    case 527:		/* Vector Insert Byte from GPR using GPR-specified
+			   Left-Index */
+    case 591:		/* Vector Insert Halfword from GPR using GPR-specified
+			   Left-Index */
+    case 655:		/* Vector Insert Word from GPR using GPR-specified
+			   Left-Index */
+    case 719:		/* Vector Insert Doubleword from GPR using
+			    GPR-specified Left-Index */
+    case 783:		/* Vector Insert Byte from GPR using GPR-specified
+			   Right-Index */
+    case 847:		/* Vector Insert Halfword from GPR using GPR-specified
+			   Left-Index */
+    case 911:		/* Vector Insert Word from GPR using GPR-specified
+			   Left-Index */
+    case 975:		/* Vector Insert Doubleword from GPR using
+			    GPR-specified Right-Index */
     case 781:		/* Vector Insert Byte */
     case 845:		/* Vector Insert Halfword */
     case 909:		/* Vector Insert Word */
     case 973:		/* Vector Insert Doubleword */
+    case 1357:		/* Vector Centrifuge Doubleword */
+    case 1421:		/* Vector Parallel Bits Extract Doubleword */
+    case 1485:		/* Vector Parallel Bits Deposit Doubleword */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
       return 0;
 
+    case 1228:		/* Vector Gather every Nth Bit */
     case 1549:		/* Vector Extract Unsigned Byte Left-Indexed */
     case 1613:		/* Vector Extract Unsigned Halfword Left-Indexed */
     case 1677:		/* Vector Extract Unsigned Word Left-Indexed */
@@ -4525,6 +4766,34 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record instructions of primary opcode 6 at ADDR.
+   Return 0 if successful.  */
+
+static int
+ppc_process_record_op6 (struct gdbarch *gdbarch, struct regcache *regcache,
+			CORE_ADDR addr, uint32_t insn)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int subtype = PPC_FIELD (insn, 28, 4);
+  CORE_ADDR ea = 0;
+
+  switch (subtype)
+    {
+    case 0:    /* Load VSX Vector Paired */
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
+      return 0;
+    case 1:    /* Store VSX Vector Paired */
+      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, 32);
+      return 0;
+    }
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-19 at ADDR.
    Return 0 if successful.  */
 
@@ -4577,6 +4846,30 @@ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record instructions of primary opcode-31 with the extended opcode
+   177.  The argument is the word instruction (insn).  Return 0 if successful.
+*/
+
+static int
+ppc_process_record_op31_177 (struct gdbarch *gdbarch,
+			     struct regcache *regcache,
+			     uint32_t insn)
+{
+  int RA_opcode = PPC_RA(insn);
+  int as = PPC_FIELD (insn, 6, 3);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  switch (RA_opcode)
+    {
+    case 0: 		/* VSX Move From Accumulator, xxmfacc */
+    case 1: 		/* VSX Move To Accumulator, xxmtacc */
+    case 3: 		/* VSX Set Accumulator to Zero, xxsetaccz */
+      ppc_record_ACC_fpscr (regcache, tdep, as, DO_NOT_RECORD_FPSCR);
+      return 0;
+    }
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-31 at ADDR.
    Return 0 if successful.  */
 
@@ -4586,7 +4879,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
-  int tmp, nr, nb, i;
+  int tmp, nr, nb = 0, i;
   CORE_ADDR at_dcsz, ea = 0;
   ULONGEST rb, ra, xer;
   int size = 0;
@@ -4677,6 +4970,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 371:		/* Move From Time Base [Phased-Out]  */
     case 309:		/* Load Doubleword Monitored Indexed  */
     case 128:		/* Set Boolean */
+    case 384:		/* Set Boolean Condition */
+    case 416:		/* Set Boolean Condition Reverse */
+    case 448:		/* Set Negative Boolean Condition */
+    case 480:		/* Set Negative Boolean Condition Reverse */
     case 755:		/* Deliver A Random Number */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_gp0_regnum + PPC_RT (insn));
@@ -4684,8 +4981,15 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 
     /* These only write to RA.  */
     case 51:		/* Move From VSR Doubleword */
+    case 59:		/* Count Leading Zeros Doubleword under bit Mask */
     case 115:		/* Move From VSR Word and Zero */
     case 122:		/* Population count bytes */
+    case 155:		/* Byte-Reverse Word */
+    case 156:		/* Parallel Bits Deposit Doubleword */
+    case 187:		/* Byte-Reverse Doubleword */
+    case 188:		/* Parallel Bits Extract Doubleword */
+    case 219:		/* Byte-Reverse Halfword */
+    case 220:		/* Centrifuge Doubleword */
     case 378:		/* Population count words */
     case 506:		/* Population count doublewords */
     case 154:		/* Parity Word */
@@ -4695,6 +4999,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 314:		/* Convert Binary Coded Decimal To Declets */
     case 508:		/* Compare bytes */
     case 307:		/* Move From VSR Lower Doubleword */
+    case 571:		/* Count Trailing Zeros Doubleword under bit Mask */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_gp0_regnum + PPC_RA (insn));
       return 0;
@@ -4819,6 +5124,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache, tmp + 1);
       return 0;
 
+    /* These write to destination register PPC_XT. */
     case 179:		/* Move To VSR Doubleword */
     case 211:		/* Move To VSR Word Algebraic */
     case 243:		/* Move To VSR Word and Zero */
@@ -4826,6 +5132,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     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 13:		/* Load VSX Vector Rightmost Byte Indexed */
+    case 45:		/* Load VSX Vector Rightmost Halfword Indexed */
+    case 77:		/* Load VSX Vector Rightmost Word Indexed */
+    case 109:		/* Load VSX Vector Rightmost Doubleword 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 */
@@ -4842,6 +5152,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
 
+    case 333:		/* Load VSX Vector Paired Indexed */
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
+      return 0;
+
     /* These write RA.  Update CR if RC is set.  */
     case 24:		/* Shift Left Word */
     case 26:		/* Count Leading Zeros Word */
@@ -5006,6 +5321,31 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_mem (ea, size);
       return 0;
 
+    case 141:		/* Store VSX Vector Rightmost Byte Indexed */
+    case 173:		/* Store VSX Vector Rightmost Halfword Indexed */
+    case 205:		/* Store VSX Vector Rightmost Word Indexed */
+    case 237:		/* Store VSX Vector Rightmost Doubleword Indexed */
+      switch(ext)
+	{
+	  case 141: nb = 1;
+	  break;
+	  case 173: nb = 2;
+	  break;
+	  case 205: nb = 4;
+	  break;
+	  case 237: nb = 8;
+	  break;
+	}
+      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;
+      record_full_arch_list_add_mem (ea, nb);
+      return 0;
+
     case 397:		/* Store VSX Vector with Length */
     case 429:		/* Store VSX Vector Left-justified with Length */
       ra = 0;
@@ -5021,6 +5361,19 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 	record_full_arch_list_add_mem (ea, nb);
       return 0;
 
+    case 461:		/* Store VSX Vector Paired Indexed */
+      {
+	if (PPC_RA (insn) != 0)
+	  regcache_raw_read_unsigned (regcache,
+				      tdep->ppc_gp0_regnum
+				      + PPC_RA (insn), &ea);
+	regcache_raw_read_unsigned (regcache,
+				    tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
+	ea += rb;
+	record_full_arch_list_add_mem (ea, 32);
+	return 0;
+      }
+
     case 710:		/* Store Word Atomic */
     case 742:		/* Store Doubleword Atomic */
       ra = 0;
@@ -5166,6 +5519,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       ea = (ra + rb) & ~((ULONGEST) (at_dcsz - 1));
       record_full_arch_list_add_mem (ea, at_dcsz);
       return 0;
+
+    case 177:
+      if (ppc_process_record_op31_177 (gdbarch, regcache, insn) == 0)
+	return 0;
     }
 
 UNKNOWN_OP:
@@ -5179,10 +5536,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 
 static int
 ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
-			   CORE_ADDR addr, uint32_t insn)
+			 CORE_ADDR addr, uint32_t insn)
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
+  int at = PPC_FIELD (insn, 6, 3);
 
   switch (ext & 0x1f)
     {
@@ -5206,6 +5564,75 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
+  /* MMA instructions, keep looking.  */
+  switch (ext >> 2)    /* Additional opcode field is upper 8-bits of ext */
+    {
+    case 3:	/* VSX Vector 8-bit Signed/Unsigned Integer GER, xvi8ger4 */
+    case 2:	/* VSX Vector 8-bit Signed/Unsigned Integer GER Positive
+		   multiply, Positive accumulate, xvi8ger4pp */
+
+    case 99:	/* VSX Vector 8-bit Signed/Unsigned Integer GER with
+		   Saturate Positive multiply, Positive accumulate,
+		   xvi8ger4spp */
+
+    case 35:	/* VSX Vector 4-bit Signed Integer GER, xvi4ger8 */
+    case 34:	/* VSX Vector 4-bit Signed Integer GER Positive multiply,
+		   Positive accumulate, xvi4ger8pp */
+
+    case 75:	/* VSX Vector 16-bit Signed Integer GER, xvi16ger2 */
+    case 107:	/* VSX Vector 16-bit Signed Integer GER  Positive multiply,
+		   Positive accumulate, xvi16ger2pp */
+
+    case 43:	/* VSX Vector 16-bit Signed Integer GER with Saturation,
+		   xvi16ger2s */
+    case 42:	/* VSX Vector 16-bit Signed Integer GER with Saturation
+		   Positive multiply, Positive accumulate, xvi16ger2spp */
+      ppc_record_ACC_fpscr (regcache, tdep, at, DO_NOT_RECORD_FPSCR);
+      return 0;
+
+    case 19:	/* VSX Vector 16-bit Floating-Point GER, xvf16ger2 */
+    case 18:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf16ger2pp */
+    case 146:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf16ger2pn */
+    case 82:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf16ger2np */
+    case 210:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
+		   Negative accumulate, xvf16ger2nn */
+
+    case 27:	/* VSX Vector 32-bit Floating-Point GER, xvf32ger */
+    case 26:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf32gerpp */
+    case 154:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf32gerpn */
+    case 90:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf32gernp */
+    case 218:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
+		   Negative accumulate, xvf32gernn */
+
+    case 59:	/* VSX Vector 64-bit Floating-Point GER, pmxvf64ger */
+    case 58:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf64gerpp */
+    case 186:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf64gerpn */
+    case 122:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf64gernp */
+    case 250:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
+		   Negative accumulate, pmxvf64gernn */
+
+    case 51:	/* VSX Vector bfloat16 GER, xvbf16ger2 */
+    case 50:	/* VSX Vector bfloat16 GER Positive multiply,
+		   Positive accumulate, xvbf16ger2pp */
+    case 178:	/* VSX Vector bfloat16 GER Positive multiply,
+		   Negative accumulate, xvbf16ger2pn */
+    case 114:	/* VSX Vector bfloat16 GER Negative multiply,
+		   Positive accumulate, xvbf16ger2np */
+    case 242:	/* VSX Vector bfloat16 GER Negative multiply,
+		   Negative accumulate, xvbf16ger2nn */
+      ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
+      return 0;
+    }
+
   switch (ext)
     {
     case 2:		/* DFP Add */
@@ -5268,6 +5695,48 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record an XX2-Form instruction with opcode 60 at ADDR.  The
+   word instruction is an argument insn.  Return 0 if successful.  */
+
+static int
+ppc_process_record_op60_XX2 (struct gdbarch *gdbarch,
+			     struct regcache *regcache,
+			     CORE_ADDR addr, uint32_t insn)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int RA_opcode = PPC_RA(insn);
+
+  switch (RA_opcode)
+    {
+    case 2:	/* VSX Vector Test Least-Significant Bit by Byte */
+    case 25:	/* VSX Vector round and Convert Single-Precision format
+		   to Half-Precision format.  Only changes the CR
+		   field.  */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+    case 17:	/* VSX Vector Convert with round Single-Precision
+		   to bfloat16 format */
+    case 24:	/* VSX Vector Convert Half-Precision format to
+		   Single-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 16:	/* VSX Vector Convert bfloat16 to Single-Precision
+		   format Non-signaling */
+    case 23:	/* VSX Vector Byte-Reverse Doubleword */
+    case 31:	/* VSX Vector Byte-Reverse Quadword */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
+    }
+
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-60 at ADDR.
    Return 0 if successful.  */
 
@@ -5583,37 +6052,30 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
       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;
+      if (ppc_process_record_op60_XX2 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      return 0;
     }
 
   switch (ext)
     {
-    case 360:		/* VSX Vector Splat Immediate Byte */
-      if (PPC_FIELD (insn, 11, 2) == 0)
+    case 360:
+      if (PPC_FIELD (insn, 11, 2) == 0)  /* VSX Vector Splat Immediate Byte */
+	{
+	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+	  return 0;
+	}
+      if (PPC_FIELD (insn, 11, 5) == 31)  /* Load VSX Vector Special Value
+					     Quadword */
 	{
 	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
 	  return 0;
 	}
       break;
+    case 916:		/* VSX Vector Generate PCV from Byte Mask */
+    case 917:		/* VSX Vector Generate PCV from Halfword Mask */
+    case 948:		/* VSX Vector Generate PCV from Word Mask */
+    case 949:		/* VSX Vector Generate PCV from Doubleword Mask */
     case 918:		/* VSX Scalar Insert Exponent Double-Precision */
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
@@ -5894,6 +6356,35 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
 			   Quad-Precision */
     case 516:		/* VSX Scalar Subtract Quad-Precision */
     case 548:		/* VSX Scalar Divide Quad-Precision */
+    case 994:
+      {
+      switch (PPC_FIELD (insn, 11, 5))
+	{
+	case 0:	/* DFP Convert From Fixed Quadword Quad */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_fp0_regnum
+					 + PPC_FRT (insn));
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_fp0_regnum
+					 + PPC_FRT (insn) + 1);
+	  return 0;
+	case 1:	/* DFP Convert To Fixed Quadword Quad */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+	  return 0;
+	}
+      }
+
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
+    case 68:		/* VSX Scalar Compare Equal Quad-Precision */
+    case 196:		/* VSX Scalar Compare Greater Than or Equal
+			   Quad-Precision */
+    case 228:		/* VSX Scalar Compare Greater Than Quad-Precision */
+    case 676:		/* VSX Scalar Maximum Type-C Quad-Precision */
+    case 740:		/* VSX Scalar Minimum Type-C Quad-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       /* FALL-THROUGH */
     case 100:		/* VSX Scalar Copy Sign Quad-Precision */
@@ -5920,14 +6411,22 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 836:
       switch (PPC_FIELD (insn, 11, 5))
 	{
+	case 0:		/* VSX Scalar Convert with round to zero
+			   Quad-Precision to Unsigned Quadword  */
 	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 3:		/* VSX Scalar Convert with round
+			   Unsigned Quadword to Quad-Precision  */
+	case 8:		/* VSX Scalar Convert with round to zero
+			   Quad-Precision to Signed Quadword  */
 	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 11:	/* VSX Scalar Convert with round
+			   Signed Quadword to Quad-Precision */
 	case 17:	/* VSX Scalar truncate & Convert Quad-Precision format
 			   to Unsigned Doubleword format */
 	case 20:	/* VSX Scalar round & Convert Quad-Precision format to
@@ -5947,17 +6446,651 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Record the prefixed instructions with primary opcode 32.  The arguments are
+   the first 32-bits of the instruction (insn_prefix), and the second 32-bits
+   of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op42 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if (ST1 != 0)
+    return -1;
+
+  switch (type)
+    {
+    case 0:  /* Prefixed Load VSX Scalar Doubleword, plxsd */
+      ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
+      break;
+    case 2:  /* Prefixed Load Halfword Algebraic, plha */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum
+				     + PPC_RT (insn_suffix));
+      break;
+    default:
+      return -1;
+    }
+  return 0;
+}
+
+/* Record the prefixed XX3-Form instructions with primary opcode 59.  The
+   arguments are the first 32-bits of the instruction (insn_prefix), and the
+   second 32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op59_XX3 (struct gdbarch *gdbarch,
+				    struct regcache *regcache,
+				    uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int opcode = PPC_FIELD (insn_suffix, 21, 8);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  int at = PPC_FIELD (insn_suffix, 6, 3);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 3)
+    {
+      if (ST4 == 9)
+	switch (opcode)
+	  {
+	  case 35:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
+			   MMIRR, pmxvi4ger8 */
+	  case 34:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
+			   MMIRR, pmxvi4ger8pp */
+
+	  case 99:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER with Saturate Positive multiply,
+			   Positive accumulate, xvi8ger4spp */
+
+	  case 3:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER MMIRR, pmxvi8ger4 */
+	  case 2:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER Positive multiply, Positive accumulate
+			   MMIRR, pmxvi8ger4pp */
+
+	  case 75:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER MMIRR, pmxvi16ger2 */
+	  case 107:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER  Positive multiply, Positive accumulate,
+			   pmxvi16ger2pp */
+
+	  case 43:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER with Saturation MMIRR, pmxvi16ger2s */
+	  case 42:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER with Saturation Positive multiply, Positive
+			   accumulate MMIRR, pmxvi16ger2spp */
+	    ppc_record_ACC_fpscr (regcache, tdep, at, DO_NOT_RECORD_FPSCR);
+	    return 0;
+
+	  case 19:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER MMIRR, pmxvf16ger2 */
+	  case 18:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Positive multiply, Positive accumulate MMIRR,
+			   pmxvf16ger2pp */
+	  case 146:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf16ger2pn */
+	  case 82:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf16ger2np */
+	  case 210:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf16ger2nn */
+
+	  case 27:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER MMIRR, pmxvf32ger */
+	  case 26:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Positive multiply, Positive accumulate MMIRR,
+			   pmxvf32gerpp */
+	  case 154:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf32gerpn */
+	  case 90:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf32gernp */
+	  case 218:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf32gernn */
+
+	  case 59:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER MMIRR, pmxvf64ger */
+	  case 58:	/* Floating-Point GER Positive multiply, Positive
+			   accumulate MMIRR, pmxvf64gerpp */
+	  case 186:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf64gerpn */
+	  case 122:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf64gernp */
+	  case 250:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf64gernn */
+
+	  case 51:	/* Prefixed Masked VSX Vector bfloat16 GER MMIRR,
+			   pmxvbf16ger2 */
+	  case 50:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
+			   multiply, Positive accumulate MMIRR,
+			   pmxvbf16ger2pp */
+	  case 178:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
+			   multiply, Negative accumulate MMIRR,
+			   pmxvbf16ger2pn */
+	  case 114:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
+			   multiply, Positive accumulate MMIRR,
+			   pmxvbf16ger2np */
+	  case 242:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
+			   multiply, Negative accumulate MMIRR,
+			   pmxvbf16ger2nn */
+	    ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
+	    return 0;
+	  }
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed store instructions.  The arguments are the instruction
+   address, the first 32-bits of the instruction(insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_store (struct gdbarch *gdbarch,
+				 struct regcache *regcache,
+				 CORE_ADDR addr, uint32_t insn_prefix,
+				 uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST iaddr = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int op6 = PPC_OP6 (insn_suffix);
+
+  if (R == 0)
+    {
+      if (PPC_RA (insn_suffix) != 0)
+	regcache_raw_read_unsigned (regcache, tdep->ppc_gp0_regnum
+				    + PPC_RA (insn_suffix), &iaddr);
+    }
+  else
+    {
+      iaddr = addr;     /* PC relative */
+    }
+
+  switch (op6)
+    {
+    case 38:
+      size =  1;    /* store byte, pstb */
+      break;
+    case 44:
+      size =  2;    /* store halfword, psth */
+      break;
+    case 36:
+    case 52:
+      size =  4;    /* store word, pstw, pstfs */
+      break;
+    case 54:
+    case 61:
+      size =  8;    /* store double word, pstd, pstfd */
+      break;
+    case 60:
+      size = 16;    /* store quadword, pstq */
+      break;
+    default: return -1;
+    }
+
+  iaddr += P_PPC_D (insn_prefix, insn_suffix);
+  record_full_arch_list_add_mem (iaddr, size);
+  return 0;
+}
+
+/* Record the prefixed instructions with primary op code 32.  The arguments
+   are the first 32-bits of the instruction (insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op32 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1)
+    {
+      if (ST4 == 0)
+	{
+	  switch (PPC_FIELD (insn_suffix, 11, 3))
+	    {
+	    case 0:  	/* VSX Vector Splat Immediate Word 8RR, xxsplti32dx */
+	      ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
+	      return 0;
+	    }
+
+	  switch (PPC_FIELD (insn_suffix, 11, 4))
+	    {
+	    case 2:  	/* VSX Vector Splat Immediate Double-Precision
+			   8RR, xxspltidp */
+	    case 3:  	/* VSX Vector Splat Immediate Word 8RR, xxspltiw */
+	      ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
+	      return 0;
+	    default:
+	      return -1;
+	    }
+	}
+      else
+	return -1;
+
+    }
+  else if (type == 2)
+    {
+      if (ST1 == 0)  		/* Prefixed Load Word and Zero, plwz */
+	record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	return -1;
+
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed instructions with primary op code 33.  The arguments
+   are the first 32-bits of the instruction(insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op33 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1)
+    {
+      if (ST4 == 0)
+	switch (PPC_FIELD (insn_suffix, 26, 2))
+	  {
+	  case 0:  	/* VSX Vector Blend Variable Byte 8RR, xxblendvb */
+	  case 1:  	/* VSX Vector Blend Variable Halfword, xxblendvh */
+	  case 2:  	/* VSX Vector Blend Variable Word, xxblendvw */
+	  case 3:  	/* VSX Vector Blend Variable Doubleword, xxblendvd */
+	    ppc_record_vsr (regcache, tdep, PPC_XT (insn_suffix));
+	  break;
+	  default:
+	    return -1;
+	  }
+      else
+	return -1;
+
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed instructions with primary op code 34.  The arguments
+   are the first 32-bits of the instruction(insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op34 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1)
+    {
+      if (ST4 == 0)
+	switch (PPC_FIELD (insn_suffix, 26, 2))
+	  {
+	  case 0:  	/* VSX Vector Permute Extended 8RR, xxpermx */
+	  case 1:  	/* VSX Vector Evaluate 8RR, xxeval */
+	    ppc_record_vsr (regcache, tdep, P_PPC_XT (insn_suffix));
+	    break;
+	  default:
+	    return -1;
+	  }
+      else
+	return -1;
+
+    }
+  else if (type == 2)
+    {
+      if (ST1 == 0)  		/* Prefixed Load Word and Zero, plbz */
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	return -1;
+
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed VSX store, form DS, instructions.  The arguments are the
+   instruction address (addr), the first 32-bits of the instruction
+   (insn_prefix) followed by the 32-bit instruction suffix (insn_suffix).
+   Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_store_vsx_ds_form (struct gdbarch *gdbarch,
+					     struct regcache *regcache,
+					     CORE_ADDR addr,
+					     uint32_t insn_prefix,
+					     uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST ea = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if ((type == 0) && (ST1 == 0))
+    {
+      if (R == 0)
+	{
+	  if (PPC_RA (insn_suffix) != 0)
+	    regcache_raw_read_unsigned (regcache,
+					tdep->ppc_gp0_regnum
+					+ PPC_RA (insn_suffix),
+					&ea);
+	}
+      else
+	{
+	  ea = addr;     /* PC relative */
+	}
+
+      ea += P_PPC_D (insn_prefix, insn_suffix);
+      switch (PPC_FIELD (insn_suffix, 0, 6))
+	{
+	case 46:    /* Prefixed Store VSX Scalar Doubleword, pstxsd */
+	  size = 8;
+	  break;
+	case 47:    /* Prefixed,Store VSX Scalar Single-Precision, pstxssp */
+	  size = 4;
+	  break;
+	default:
+	  return -1;
+	}
+      record_full_arch_list_add_mem (ea, size);
+      return 0;
+  }
+  else
+    return -1;
+}
+
+/* Record the prefixed VSX, form D, instructions.  The arguments are the
+   instruction address for PC-relative addresss (addr), the first 32-bits of
+   the instruction (insn_prefix) and the following 32-bits of the instruction
+   (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_vsx_d_form (struct gdbarch *gdbarch,
+				      struct regcache *regcache,
+				      CORE_ADDR addr,
+				      uint32_t insn_prefix,
+				      uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST ea = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if ((type == 0) && (ST1 == 0))
+    {
+      switch (PPC_FIELD (insn_suffix, 0, 5))
+	{
+	case 25:	/* Prefixed Load VSX Vector, plxv */
+	  ppc_record_vsr (regcache, tdep, P_PPC_XT5 (insn_prefix));
+	  return 0;
+	case 27:	/* Prefixed Store VSX Vector 8LS, pstxv */
+	  {
+	    size = 16;
+	    if (R == 0)
+	      {
+		if (PPC_RA (insn_suffix) != 0)
+		  regcache_raw_read_unsigned (regcache,
+					      tdep->ppc_gp0_regnum
+					      + PPC_RA (insn_suffix),
+					      &ea);
+	      }
+	    else
+	      {
+		ea = addr;     /* PC relative */
+	      }
+
+	    ea += P_PPC_D (insn_prefix, insn_suffix);
+	    record_full_arch_list_add_mem (ea, size);
+	    return 0;
+	  }
+	}
+      return -1;
+    }
+  else
+    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.  */
 
+/* This handles the recording of the various prefix instructions.  It takes
+   the instruction address, the first 32-bits of the instruction (insn_prefix)
+   and the following 32-bits of the instruction (insn_suffix).  Return 0 on
+   success.  */
+
+static int
+ppc_process_prefix_instruction (int insn_prefix, int insn_suffix,
+				CORE_ADDR addr,	struct gdbarch *gdbarch,
+				struct regcache *regcache)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int op6;
+
+  /* D-form has uses a 5-bit opcode in the instruction suffix */
+  if (ppc_process_record_prefix_vsx_d_form ( gdbarch, regcache, addr,
+					     insn_prefix, insn_suffix) == 0)
+    goto SUCCESS;
+
+  op6 = PPC_OP6 (insn_suffix);  /* 6-bit opcode in the instruction suffix */
+
+  switch (op6)
+    {
+    case 14:		/* Prefixed Add Immediate, paddi */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 32:
+      if (ppc_process_record_prefix_op32 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 33:
+      if (ppc_process_record_prefix_op33 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 34:		/* Prefixed Load Byte and Zero, plbz */
+      if (ppc_process_record_prefix_op34 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+    case 40:		/* Prefixed Load Halfword and Zero, plhz */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+      break;
+
+    case 36:		/* Prefixed Store Word, pstw */
+    case 38:		/* Prefixed Store Byte, pstb */
+    case 44:		/* Prefixed Store Halfword, psth */
+    case 52:		/* Prefixed Store Floating-Point Single, pstfs */
+    case 54:		/* Prefixed Store Floating-Point Double, pstfd */
+    case 60:		/* Prefixed Store Quadword, pstq */
+    case 61:		/* Prefixed Store Doubleword, pstd */
+      if (ppc_process_record_prefix_store (gdbarch, regcache, addr,
+					   insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 42:
+      if (ppc_process_record_prefix_op42 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 43:          /* Prefixed Load VSX Scalar Single-Precision, plxssp */
+      if ((type == 0) && (ST1 == 0))
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
+      else
+	  goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 46:
+    case 47:
+      if (ppc_process_record_prefix_store_vsx_ds_form (gdbarch, regcache, addr,
+					       insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 56:		/* Prefixed Load Quadword, plq */
+      {
+	if ((type == 0) && (ST1 == 0))
+	  {
+	    int tmp;
+	    tmp = tdep->ppc_gp0_regnum + (PPC_RT (insn_suffix) & ~1);
+	    record_full_arch_list_add_reg (regcache, tmp);
+	    record_full_arch_list_add_reg (regcache, tmp + 1);
+	  }
+	else
+	  goto UNKNOWN_PREFIX_OP;
+	break;
+      }
+
+    case 41:		/* Prefixed Load Word Algebraic, plwa */
+    case 57:  		/* Prefixed Load Doubleword, pld */
+      if ((type == 0) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 48:		/* Prefixed Load Floating-Point Single, plfs */
+    case 50:		/* Prefixed Load Floating-Point Double, plfd */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_fp0_regnum
+				       + PPC_FRT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 58:		/* Prefixed Load VSX Vector Paired, plxvp */
+      if ((type == 0) && (ST1 == 0))
+	{
+	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix));
+	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix) + 1);
+	}
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 59:
+      if (ppc_process_record_prefix_op59_XX3 (gdbarch, regcache, insn_prefix,
+					      insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 62:	    /* Prefixed Store VSX Vector Paired 8LS, pstxvp */
+      if ((type == 0) && (ST1 == 0))
+	{
+	  int R = PPC_BIT (insn_prefix, 11);
+	  CORE_ADDR ea = 0;
+
+	  if (R == 0)
+	    {
+	      if (PPC_RA (insn_suffix) != 0)
+		regcache_raw_read_unsigned (regcache,
+					    tdep->ppc_gp0_regnum
+					    + PPC_RA (insn_suffix), &ea);
+	    }
+	  else
+	    {
+	      ea = addr;     /* PC relative */
+	    }
+
+	  ea += P_PPC_D (insn_prefix, insn_suffix) << 4;
+	  record_full_arch_list_add_mem (ea, 32);
+	}
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    default:
+UNKNOWN_PREFIX_OP:
+      gdb_printf (gdb_stdlog,
+		  "Warning: Don't know how to record prefix instruction "
+		  "%08x %08x at %s, %d.\n",
+		  insn_prefix, insn_suffix, paddress (gdbarch, addr),
+		  op6);
+      return -1;
+    }
+
+ SUCCESS:
+  if (record_full_arch_list_add_reg (regcache, PPC_PC_REGNUM))
+    return -1;
+
+  if (record_full_arch_list_add_end ())
+    return -1;
+  return 0;
+}
+
 int
 ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 		      CORE_ADDR addr)
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  uint32_t insn;
+  uint32_t insn, insn_suffix;
   int op6, tmp, i;
 
   insn = read_memory_unsigned_integer (addr, 4, byte_order);
@@ -5965,16 +7098,28 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 
   switch (op6)
     {
+    case 1:		/* prefixed instruction */
+      {
+	/* Get the lower 32-bits of the prefixed instruction. */
+	insn_suffix = read_memory_unsigned_integer (addr+4, 4, byte_order);
+	return ppc_process_prefix_instruction (insn, insn_suffix, addr,
+					       gdbarch, regcache);
+      }
     case 2:		/* Trap Doubleword Immediate */
     case 3:		/* Trap Word Immediate */
       /* Do nothing.  */
       break;
 
-    case 4:
+    case 4:             /* Vector Integer, Compare, Logical, Shift, etc.  */
       if (ppc_process_record_op4 (gdbarch, regcache, addr, insn) != 0)
 	return -1;
       break;
 
+    case 6:             /* Vector Load and Store */
+      if (ppc_process_record_op6 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      break;
+
     case 17:		/* System call */
       if (PPC_LEV (insn) != 0)
 	goto UNKNOWN_OP;
-- 
2.31.1



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/2 Version 5] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-17 16:48                 ` Joel Brobecker
@ 2022-04-18 19:21                   ` Carl Love
  2022-04-22 19:47                     ` [PATCH 2/2 Version 5 PING] " Carl Love
  2022-04-24 16:56                     ` [PATCH 2/2 Version 5] " Joel Brobecker
  0 siblings, 2 replies; 25+ messages in thread
From: Carl Love @ 2022-04-18 19:21 UTC (permalink / raw)
  To: Joel Brobecker, cel
  Cc: Pedro Alves, will schmidt, gdb-patches, Ulrich Weigand,
	Tulio Magno, Rogerio Alves

Joel, Pedro, Will, GDB maintainers:

On Sun, 2022-04-17 at 09:48 -0700, Joel Brobecker wrote:
> 
> As mentioned by Pedro: PowerPC

<snip>

> > This patch adds Powerpc specific tests to verify recording of
> > various
> 
> And here also.

Yup, missed them.  I went thru these patches and the rest of the
patches I am working on to fix in in all of them. Have some additional
posted patches that need to have this fixed as well.


Fixed the additional space issues you mentioned.

<snip>
> 
> > +# Check initial and new of vs0 are different.
> > +set test_vs0_init_new "check vs0 initial versus vs0 new"
> > +if {[string compare $vs0_initial $vs0_new] == 0} {
> > +    fail $test_vs0_init_new
> > +} else {
> > +    pass $test_vs0_init_new
> > +}
> 
> I looked at gdb_assert following Pedro's suggestion, and I agree
> it would really simplify your testcase. Any reason why you didn't
> follow his advice?

I looked at his suggestion, but it didn't seem to me to make much
difference as you would still need the if statement.  I looked at it
again and realized that it really does make is a lot simpler then I
initially thought since you don't need the if statement.  The
gdb_assert takes care of doing the test pass/fail.   So, yea it is a
good change.  I changed the string compares in both the ISA 2.07 and
ISA 3.1 test cases.

<snip>

> > +# Execute in reverse to before test 1
> > +gdb_test "set exec-direction reverse" "" "reverse to start of test
> > 1"
> > +#gdb_test_no_output "set exec-direction reverse"
> 
> I just noticied this, because we normally avoid commented-out code
> without a good reason behind it (which we also would typically
> provide as a comment next to the code).
> 
> But looking at it more closely, I think the commented-out
> version seems to be the correct one, not the one you are using.
> In particular, there is an implicit ".*" at the start of the
> expected output's matching in gdb_test, which means using ""
> as the expected output is the same as matching anything.

Don't remember if I was playing around with using the
gdb_test_no_output or not.  I can't remember now.  I may have been and
got distracted and never got back to it????   Yea, the
gdb_test_no_output works just as well as the gdb_test.  Changed to
following tests as well.  Note, looks like I did use the
gdb_test_no_output in the ISA 2.07 test.

Again, retested this patch to make sure I didn't break anything.

Thanks for the detailed review.

                                Carl 
-----------------------------------------------------------
GDB PowerPC record test cases for ISA 2.06 and ISA 3.1

This patch adds PowerPC specific tests to verify recording of various
instructions.  The first test case checks the ISA 2.06 lxvd2x instruction.
The second test case tests several of the ISA 3.01 instructions.  Specifically,
it checks the word and prefixed instructions and some of the Matrix
Multiply Assist (MMA) instructions.

The patch has been run on both Power 10 and Power 9 to verify the ISA
2.06 test case runs on both platforms without errors.  The ISA 3.1 test
runs without errors on Power 10 and is skipped as expected on Power 9.
---
 .../gdb.reverse/ppc_record_test_isa_2_06.c    |  39 ++
 .../gdb.reverse/ppc_record_test_isa_2_06.exp  | 105 ++++++
 .../gdb.reverse/ppc_record_test_isa_3_1.c     |  95 +++++
 .../gdb.reverse/ppc_record_test_isa_3_1.exp   | 341 ++++++++++++++++++
 4 files changed, 580 insertions(+)
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
 create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp

diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
new file mode 100644
index 00000000000..45e58413da2
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
@@ -0,0 +1,39 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* globals used for vector tests */
+static vector unsigned long vec_xb;
+static unsigned long ra, rb, rs;
+
+int
+main ()
+{
+  ra = 0xABCDEF012;
+  rb = 0;
+  rs = 0x012345678;
+
+  /* 9.0, 16.0, 25.0, 36.0 */
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+
+  /* Test ISA 2.06 instructions.  Load source into vs1, result of sqrt
+     put into vs0.  */
+  ra = (unsigned long) & vec_xb;        /* stop 1 */
+  __asm__ __volatile__ ("lxvd2x 1, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("xvsqrtsp 0, 1");
+  ra = 0;                               /* stop 2 */
+}
+
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
new file mode 100644
index 00000000000..d68dd7b9049
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
@@ -0,0 +1,105 @@
+# Copyright 2008-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Test instruction record for PowerPC, ISA 2.06.
+#
+
+# The basic flow of the record tests are:
+#    1) Stop before executing the instructions of interest.  Record
+#       the initial value of the registers that the instruction will
+#       change, i.e. the destination register.
+#    2) Execute the instructions.  Record the new value of the
+#       registers that changed.
+#    3) Reverse the direction of the execution and execute back to
+#       just before the instructions of interest.  Record the final
+#       value of the registers of interest.
+#    4) Check that the initial and new values of the registers are
+#       different, i.e. the instruction changed the registers as expected.
+#    5) Check that the initial and final values of the registers are
+#       the same, i.e. gdb record restored the registers to their
+#       original values.
+
+standard_testfile
+
+set gen_src record_test_isa_2_06.c
+set executable record_test_isa_2_06
+set options [list debug]
+
+if {![istarget "powerpc*"]} then {
+    verbose "Skipping PowerPC ISA 2.06 instruction record_test_2_06."
+    return
+}
+
+if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
+    return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] then {
+    untested "could not run to main"
+    continue
+}
+
+gdb_test_no_output "record"
+
+###### Test: Test an ISA 2.06 load (lxvd2x) and square root instruction
+###### (xvsqrtsp).  The load instruction will load vs1.  The sqrt instruction
+###### will put its result into vs0.
+
+set stop1 [gdb_get_line_number "stop 1"]
+set stop2 [gdb_get_line_number "stop 2"]
+
+gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test"
+gdb_test "continue"  ".*Breakpoint .*" "at stop 1"
+
+# Record the initial values in vs0, vs1.
+set vs0_initial [capture_command_output "info register vs0" ""]
+set vs1_initial [capture_command_output "info register vs1" ""]
+
+gdb_test "break $stop2" ".*Breakpoint .*" "executed lxvd2x, xvsqrtsp"
+gdb_test "continue"  ".*Breakpoint .*" "at stop 2"
+
+# Record the new values of vs0 and vs1.
+set vs0_new [capture_command_output "info register vs0" ""]
+set vs1_new [capture_command_output "info register vs1" ""]
+
+# Reverse the execution direction.
+gdb_test_no_output "set exec-direction reverse"
+gdb_test "break $stop1" ".*Breakpoint .*" "un executed lxvd2x, xvsqrtsp"
+
+# Execute in reverse to before the lxvd2x instruction.
+gdb_test "continue"  ".*Breakpoint.*" "at stop 1 in reverse"
+
+# Record the final values of vs0, vs1.
+set vs0_final [capture_command_output "info register vs0" ""]
+set vs1_final [capture_command_output "info register vs1" ""]
+
+# Check initial and new of vs0 are different.
+gdb_assert [string compare $vs0_initial $vs1_new] \
+    "check vs0 initial versus vs0 new"
+
+# Check initial and new of vs1 are different.
+gdb_assert [string compare $vs1_initial $vs1_new] \
+    "check vs0 initial versus vs1 new"
+
+# Check initial and final are the same.
+gdb_assert ![string compare $vs0_initial $vs0_final] \
+    "check vs0 initial versus vs0 final"
+
+# Check initial and final are the same.
+gdb_assert ![string compare $vs1_initial $vs1_final] \
+    "check vs1 initial versus vs1 final"
+
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
new file mode 100644
index 00000000000..c0d65d944af
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
@@ -0,0 +1,95 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Globals used for vector tests.  */
+static vector unsigned long vec_xa, vec_xb, vec_xt;
+static unsigned long ra, rb, rs;
+
+int
+main ()
+{
+  ra = 0xABCDEF012;
+  rb = 0;
+  rs = 0x012345678;
+
+  /* 9.0, 16.0, 25.0, 36.0 */
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+
+  vec_xt = (vector unsigned long){0xFF00FF00FF00FF00, 0xAA00AA00AA00AA00};
+
+  /* Test 1, ISA 3.1 word instructions. Load source into r1, result of brh
+     put in r0.  */
+  ra = 0xABCDEF012;                     /* stop 1 */
+  __asm__ __volatile__ ("pld 1, %0" :: "r" (ra ));
+  __asm__ __volatile__ ("brh 0, 1" );
+  ra = 0;                               /* stop 2 */
+
+  /* Test 2, ISA 3.1 MMA instructions with results in various ACC entries
+     xxsetaccz    - ACC[3]
+     xvi4ger8     - ACC[4]
+     xvf16ger2pn  - ACC[5]
+     pmxvi8ger4   - ACC[6]
+     pmxvf32gerpp - ACC[7] and fpscr */
+  /* Need to initialize the vs registers to a non zero value.  */
+  ra = (unsigned long) & vec_xb;
+  __asm__ __volatile__ ("lxvd2x 12, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 13, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 14, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 15, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xa = (vector unsigned long){0x333134343987601, 0x9994bbbc9983307};
+  vec_xb = (vector unsigned long){0x411234041898760, 0x41c833042103400};
+  __asm__ __volatile__ ("lxvd2x 16, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x123456789987650, 0x235676546989807};
+  __asm__ __volatile__ ("lxvd2x 17, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x878363439823470, 0x413434c99839870};
+  __asm__ __volatile__ ("lxvd2x 18, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x043765434398760, 0x419876555558850};
+  __asm__ __volatile__ ("lxvd2x 19, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x33313434398760, 0x9994bbbc99899330};
+  __asm__ __volatile__ ("lxvd2x 20, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 21, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 22, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 23, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 24, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 25, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 26, %0, %1" :: "r" (ra ), "r" (rb));
+  __asm__ __volatile__ ("lxvd2x 27, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xa = (vector unsigned long){0x33313434398760, 0x9994bbbc998330};
+  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
+  __asm__ __volatile__ ("lxvd2x 28, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x4567000046800000, 0x4458000048700000};
+  __asm__ __volatile__ ("lxvd2x 29, %0, %1" :: "r" (ra ), "r" (rb));
+  vec_xb = (vector unsigned long){0x41dd000041e00000, 0x41c8000046544400};
+  __asm__ __volatile__ ("lxvd2x 30, %0, %1" :: "r" (ra ), "r" (rb));
+
+  /* SNAN */
+  vec_xb = (vector unsigned long){0x7F8F00007F8F0000, 0x7F8F00007F8F0000};
+
+  __asm__ __volatile__ ("lxvd2x 31, %0, %1" :: "r" (ra ), "r" (rb));
+
+  ra = 0xAB;                            /* stop 3 */
+  __asm__ __volatile__ ("xxsetaccz 3");
+  __asm__ __volatile__ ("xvi4ger8 4, %x0, %x1" :: "wa" (vec_xa), \
+			"wa" (vec_xb) );
+  __asm__ __volatile__ ("xvf16ger2pn 5, %x0, %x1" :: "wa" (vec_xa),\
+			"wa" (vec_xb) );
+  __asm__ __volatile__ ("pmxvi8ger4spp  6, %x0, %x1, 11, 13, 5"
+                                :: "wa" (vec_xa), "wa" (vec_xb) );
+  __asm__ __volatile__ ("pmxvf32gerpp  7, %x0, %x1, 11, 13"
+                                :: "wa" (vec_xa), "wa" (vec_xb) );
+  ra = 0;                               /* stop 4 */
+}
diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
new file mode 100644
index 00000000000..9ea8931e9cf
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
@@ -0,0 +1,341 @@
+# Copyright 2008-2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Test instruction record for PowerPC, ISA 3.1.
+#
+
+# The basic flow of the record tests are:
+#    1) Stop before executing the instructions of interest.  Record
+#       the initial value of the registers that the instruction will
+#       change, i.e. the destination register.
+#    2) Execute the instructions.  Record the new value of the
+#       registers that changed.
+#    3) Reverse the direction of the execution and execute back to
+#       just before the instructions of interest.  Record the final
+#       value of the registers of interest.
+#    4) Check that the initial and new values of the registers are
+#       different, i.e. the instruction changed the registers as expected.
+#    5) Check that the initial and final values of the registers are
+#       the same, i.e. gdb record restored the registers to their
+#       original values.
+
+
+standard_testfile
+
+set gen_src record_test_isa_3_1.c
+set executable record_test_isa_3_1
+
+if {![istarget "powerpc*"] || [skip_power_isa_3_1_tests] } then  {
+    verbose "Skipping PowerPC ISA 3.1 instruction record_test."
+    return
+}
+
+set options [list additional_flags=-mcpu=power10 debug]
+if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
+    return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] then {
+    untested "could not run to main"
+    continue
+}
+
+gdb_test_no_output "record"
+
+######  Test 1:  Test an ISA 3.1 byte reverse word instruction (brd) and a
+######  prefixed load double (pld) instruction.
+set stop1 [gdb_get_line_number "stop 1"]
+set stop2 [gdb_get_line_number "stop 2"]
+
+gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test 1"
+gdb_test "continue"  ".*Breakpoint .*" "at stop 1"
+
+# Record the initial values in r0, r1
+# Load the argument into r1, result of byte reverse is put into r0.
+set r0_initial [capture_command_output "info register r0" ""]
+set r1_initial [capture_command_output "info register r1" ""]
+
+gdb_test "break $stop2" ".*Breakpoint .*" "executed test 1"
+gdb_test "continue"  ".*Breakpoint .*" "at stop 2"
+
+# Record the new values of r0 and r1
+set r0_new [capture_command_output "info register r0" ""]
+set r1_new [capture_command_output "info register r1" ""]
+
+# Execute in reverse to before test 1
+gdb_test_no_output "set exec-direction reverse"
+
+gdb_test "break $stop1" ".*Breakpoint .*" "reverse stop at test 1 start"
+gdb_test "continue"  ".*Breakpoint.*" "at stop 1 in reverse"
+
+# Record the final values of r0, r1
+set r0_final [capture_command_output "info register r0" ""]
+set r1_final [capture_command_output "info register r1" ""]
+
+# Check initial and new of r0 are different.
+gdb_assert [string compare $r0_initial $r0_new] \
+    "check r0 initial versus r0 new"
+
+# Check initial and new of r1 are different.
+gdb_assert [string compare $r1_initial $r1_new] \
+    "check r0 initial versus r1 new"
+
+# Check initial and final are the same.
+gdb_assert ![string compare $r0_initial $r0_final] \
+    "check r0 initial versus r0 final"
+
+# Check initial and final are the same.
+gdb_assert ![string compare $r1_initial $r1_final] \
+    "check r1 initial versus r1 final"
+
+
+# Change execution direction to forward for next test.
+gdb_test_no_output "set exec-direction forward" "start forward test3"
+gdb_test "record stop" ".*Process record is stopped.*" "stopped recording 2"
+set test_del_bkpts "delete breakpoints, answer prompt 2"
+
+# Delete all breakpoints and catchpoints.
+delete_breakpoints
+
+gdb_test_no_output "record" "start recording test2"
+
+
+######  Test 2:  Test the ISA 3.1 MMA instructions xxsetaccz, xvi4ger8,
+######  xvf16ger2pn, pmxvi8ger4, and pmxvf32gerpp.  Goal here is to hit all
+######  the places where ppc_record_ACC_fpscr() gets called.
+##
+##       xxsetaccz    - ACC[3], vs[12] to vs[15]
+##       xvi4ger8     - ACC[4], vs[16] to vs[19]
+##       xvf16ger2pn  - ACC[5], vs[20] to vs[23]
+##       pmxvi8ger4   - ACC[6], vs[21] to vs[27]
+##       pmxvf32gerpp - ACC[7], vs[28] to vs[31] and fpscr
+
+set stop3 [gdb_get_line_number "stop 3"]
+set stop4 [gdb_get_line_number "stop 4"]
+
+gdb_test "break $stop3" ".*Breakpoint .*" "about to execute test 2"
+gdb_test "continue"  ".*Breakpoint .*" "at stop 3"
+
+# Record the initial values of vs's that correspond to the ACC entries,
+# and fpscr.
+set acc_3_0_initial [capture_command_output "info register vs12" ""]
+set acc_3_1_initial [capture_command_output "info register vs13" ""]
+set acc_3_2_initial [capture_command_output "info register vs14" ""]
+set acc_3_3_initial [capture_command_output "info register vs15" ""]
+set acc_4_0_initial [capture_command_output "info register vs16" ""]
+set acc_4_1_initial [capture_command_output "info register vs17" ""]
+set acc_4_2_initial [capture_command_output "info register vs18" ""]
+set acc_4_3_initial [capture_command_output "info register vs19" ""]
+set acc_5_0_initial [capture_command_output "info register vs20" ""]
+set acc_5_1_initial [capture_command_output "info register vs21" ""]
+set acc_5_2_initial [capture_command_output "info register vs22" ""]
+set acc_5_3_initial [capture_command_output "info register vs23" ""]
+set acc_6_0_initial [capture_command_output "info register vs24" ""]
+set acc_6_1_initial [capture_command_output "info register vs25" ""]
+set acc_6_2_initial [capture_command_output "info register vs26" ""]
+set acc_6_3_initial [capture_command_output "info register vs27" ""]
+set acc_7_0_initial [capture_command_output "info register vs28" ""]
+set acc_7_1_initial [capture_command_output "info register vs29" ""]
+set acc_7_2_initial [capture_command_output "info register vs30" ""]
+set acc_7_3_initial [capture_command_output "info register vs31" ""]
+set fpscr_initial [capture_command_output "info register fpscr" ""]
+
+gdb_test "break $stop4" ".*Breakpoint .*" "executed test 2"
+gdb_test "continue"  ".*Breakpoint .*" "at stop 4"
+
+# Record the new values of the ACC entries and fpscr.
+set acc_3_0_new [capture_command_output "info register vs12" ""]
+set acc_3_1_new [capture_command_output "info register vs13" ""]
+set acc_3_2_new [capture_command_output "info register vs14" ""]
+set acc_3_3_new [capture_command_output "info register vs15" ""]
+set acc_4_0_new [capture_command_output "info register vs16" ""]
+set acc_4_1_new [capture_command_output "info register vs17" ""]
+set acc_4_2_new [capture_command_output "info register vs18" ""]
+set acc_4_3_new [capture_command_output "info register vs19" ""]
+set acc_5_0_new [capture_command_output "info register vs20" ""]
+set acc_5_1_new [capture_command_output "info register vs21" ""]
+set acc_5_2_new [capture_command_output "info register vs22" ""]
+set acc_5_3_new [capture_command_output "info register vs23" ""]
+set acc_6_0_new [capture_command_output "info register vs24" ""]
+set acc_6_1_new [capture_command_output "info register vs25" ""]
+set acc_6_2_new [capture_command_output "info register vs26" ""]
+set acc_6_3_new [capture_command_output "info register vs27" ""]
+set acc_7_0_new [capture_command_output "info register vs28" ""]
+set acc_7_1_new [capture_command_output "info register vs29" ""]
+set acc_7_2_new [capture_command_output "info register vs30" ""]
+set acc_7_3_new [capture_command_output "info register vs31" ""]
+set fpscr_new [capture_command_output "info register fpscr" ""]
+
+# Execute in reverse to before test 2.
+gdb_test_no_output "set exec-direction reverse" "reverse to start of test 2"
+
+gdb_test "break $stop3" ".*Breakpoint .*" "reverse stop at test 2 start"
+gdb_test "continue"  ".*Breakpoint.*" "at stop 3 in reverse"
+
+# Record the final values of the ACC entries and fpscr.
+set acc_3_0_final [capture_command_output "info register vs12" ""]
+set acc_3_1_final [capture_command_output "info register vs13" ""]
+set acc_3_2_final [capture_command_output "info register vs14" ""]
+set acc_3_3_final [capture_command_output "info register vs15" ""]
+set acc_4_0_final [capture_command_output "info register vs16" ""]
+set acc_4_1_final [capture_command_output "info register vs17" ""]
+set acc_4_2_final [capture_command_output "info register vs18" ""]
+set acc_4_3_final [capture_command_output "info register vs19" ""]
+set acc_5_0_final [capture_command_output "info register vs20" ""]
+set acc_5_1_final [capture_command_output "info register vs21" ""]
+set acc_5_2_final [capture_command_output "info register vs22" ""]
+set acc_5_3_final [capture_command_output "info register vs23" ""]
+set acc_6_0_final [capture_command_output "info register vs24" ""]
+set acc_6_1_final [capture_command_output "info register vs25" ""]
+set acc_6_2_final [capture_command_output "info register vs26" ""]
+set acc_6_3_final [capture_command_output "info register vs27" ""]
+set acc_7_0_final [capture_command_output "info register vs28" ""]
+set acc_7_1_final [capture_command_output "info register vs29" ""]
+set acc_7_2_final [capture_command_output "info register vs30" ""]
+set acc_7_3_final [capture_command_output "info register vs31" ""]
+set fpscr_final [capture_command_output "info register fpscr" ""]
+
+# check initial and new ACC entries are different.
+gdb_assert [string compare $acc_3_0_initial $acc_3_0_new] \
+    "check vs12 initial versus new"
+
+gdb_assert [string compare $acc_3_1_initial $acc_3_1_new] \
+    "check vs13 initial versus new"
+
+gdb_assert [string compare $acc_3_2_initial $acc_3_2_new] \
+    "check vs14 initial versus new"
+
+gdb_assert [string compare $acc_3_3_initial $acc_3_3_new] \
+    "check vs15 initial versus new"
+
+gdb_assert [string compare $acc_4_0_initial $acc_4_0_new] \
+    "check vs16 initial versus new"
+
+gdb_assert [string compare $acc_4_1_initial $acc_4_1_new] \
+    "check vs17 initial versus new"
+
+gdb_assert [string compare $acc_4_2_initial $acc_4_2_new] \
+    "check vs18 initial versus new"
+
+gdb_assert [string compare $acc_4_3_initial $acc_4_3_new] \
+    "check vs19 initial versus new"
+
+gdb_assert [string compare $acc_5_0_initial $acc_5_0_new] \
+    "check vs20 initial versus new"
+
+gdb_assert [string compare $acc_5_1_initial $acc_5_1_new] \
+    "check vs21 initial versus new"
+
+gdb_assert [string compare $acc_5_2_initial $acc_5_2_new] \
+    "check vs22 initial versus new"
+
+gdb_assert [string compare $acc_5_3_initial $acc_5_3_new] \
+    "check vs23 initial versus new"
+
+gdb_assert [string compare $acc_6_0_initial $acc_6_0_new] \
+    "check vs24 initial versus new"
+
+gdb_assert [string compare $acc_6_1_initial $acc_6_1_new] \
+    "check vs25 initial versus new"
+
+gdb_assert [string compare $acc_6_2_initial $acc_6_2_new] \
+    "check vs26 initial versus new"
+
+gdb_assert [string compare $acc_6_3_initial $acc_6_3_new] \
+    "check vs27 initial versus new"
+
+gdb_assert [string compare $acc_7_0_initial $acc_7_0_new] \
+    "check vs28 initial versus new"
+
+gdb_assert [string compare $acc_7_1_initial $acc_7_1_new] \
+    "check vs29 initial versus new"
+
+gdb_assert [string compare $acc_7_2_initial $acc_7_2_new] \
+    "check vs30 initial versus new"
+
+gdb_assert [string compare $acc_7_3_initial $acc_7_3_new] \
+    "check vs31 initial versus new"
+
+gdb_assert [string compare $fpscr_initial $fpscr_new] \
+    "check fpscr initial versus new"
+
+
+# Check initial and final ACC entries are the same.
+gdb_assert ![string compare $acc_3_0_initial $acc_3_0_final] \
+    "check vs12 initial versus final"
+
+gdb_assert ![string compare $acc_3_1_initial $acc_3_1_final] \
+    "check vs13 initial versus final"
+
+gdb_assert ![string compare $acc_3_2_initial $acc_3_2_final] \
+    "check vs14 initial versus final"
+
+gdb_assert ![string compare $acc_3_3_initial $acc_3_3_final] \
+    "check vs15 initial versus final"
+
+gdb_assert ![string compare $acc_4_0_initial $acc_4_0_final] \
+    "check vs16 initial versus final"
+
+gdb_assert ![string compare $acc_4_1_initial $acc_4_1_final] \
+    "check vs17 initial versus final"
+
+gdb_assert ![string compare $acc_4_2_initial $acc_4_2_final] \
+    "check vs18 initial versus final"
+
+gdb_assert ![string compare $acc_4_3_initial $acc_4_3_final] \
+    "check vs19 initial versus final"
+
+gdb_assert ![string compare $acc_5_0_initial $acc_5_0_final] \
+    "check vs20 initial versus final"
+
+gdb_assert ![string compare $acc_5_1_initial $acc_5_1_final] \
+    "check vs21 initial versus final"
+
+gdb_assert ![string compare $acc_5_2_initial $acc_5_2_final] \
+    "check vs22 initial versus final"
+
+gdb_assert ![string compare $acc_5_3_initial $acc_5_3_final] \
+    "check vs23 initial versus final"
+
+gdb_assert ![string compare $acc_6_0_initial $acc_6_0_final] \
+    "check vs24 initial versus final"
+
+gdb_assert ![string compare $acc_6_1_initial $acc_6_1_final] \
+    "check vs25 initial versus final"
+
+gdb_assert ![string compare $acc_6_2_initial $acc_6_2_final] \
+    "check vs26 initial versus final"
+
+gdb_assert ![string compare $acc_6_3_initial $acc_6_3_final] \
+    "check vs27 initial versus final"
+
+gdb_assert ![string compare $acc_7_0_initial $acc_7_0_final] \
+    "check vs28 initial versus final"
+
+gdb_assert ![string compare $acc_7_1_initial $acc_7_1_final] \
+    "check vs29 initial versus final"
+
+gdb_assert ![string compare $acc_7_2_initial $acc_7_2_final] \
+    "check !vs30 initial versus final"
+
+gdb_assert ![string compare $acc_7_3_initial $acc_7_3_final] \
+    "check !vs31 initial versus final"
+
+gdb_assert ![string compare $fpscr_initial $fpscr_final] \
+    "check fpscr initial versus final"
+
+
-- 
2.31.1



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/2 Version 5 PING] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-18 19:21                   ` [PATCH 2/2 Version 5] " Carl Love
@ 2022-04-22 19:47                     ` Carl Love
  2022-04-24 16:56                     ` [PATCH 2/2 Version 5] " Joel Brobecker
  1 sibling, 0 replies; 25+ messages in thread
From: Carl Love @ 2022-04-22 19:47 UTC (permalink / raw)
  To: Joel Brobecker, cel
  Cc: Pedro Alves, will schmidt, gdb-patches, Ulrich Weigand,
	Tulio Magno, Rogerio Alves


Joel, Pedro, Will, GDB maintainers:

Just wanted to check if there is any additional feedback on the patch
or is it ready to commit?   Thanks.

             Carl Love

On Mon, 2022-04-18 at 12:21 -0700, Carl Love wrote:
> Joel, Pedro, Will, GDB maintainers:
> 
> On Sun, 2022-04-17 at 09:48 -0700, Joel Brobecker wrote:
> > As mentioned by Pedro: PowerPC
> 
> <snip>
> 
> > > This patch adds Powerpc specific tests to verify recording of
> > > various
> > 
> > And here also.
> 
> Yup, missed them.  I went thru these patches and the rest of the
> patches I am working on to fix in in all of them. Have some
> additional
> posted patches that need to have this fixed as well.
> 
> 
> Fixed the additional space issues you mentioned.
> 
> <snip>
> > > +# Check initial and new of vs0 are different.
> > > +set test_vs0_init_new "check vs0 initial versus vs0 new"
> > > +if {[string compare $vs0_initial $vs0_new] == 0} {
> > > +    fail $test_vs0_init_new
> > > +} else {
> > > +    pass $test_vs0_init_new
> > > +}
> > 
> > I looked at gdb_assert following Pedro's suggestion, and I agree
> > it would really simplify your testcase. Any reason why you didn't
> > follow his advice?
> 
> I looked at his suggestion, but it didn't seem to me to make much
> difference as you would still need the if statement.  I looked at it
> again and realized that it really does make is a lot simpler then I
> initially thought since you don't need the if statement.  The
> gdb_assert takes care of doing the test pass/fail.   So, yea it is a
> good change.  I changed the string compares in both the ISA 2.07 and
> ISA 3.1 test cases.
> 
> <snip>
> 
> > > +# Execute in reverse to before test 1
> > > +gdb_test "set exec-direction reverse" "" "reverse to start of
> > > test
> > > 1"
> > > +#gdb_test_no_output "set exec-direction reverse"
> > 
> > I just noticied this, because we normally avoid commented-out code
> > without a good reason behind it (which we also would typically
> > provide as a comment next to the code).
> > 
> > But looking at it more closely, I think the commented-out
> > version seems to be the correct one, not the one you are using.
> > In particular, there is an implicit ".*" at the start of the
> > expected output's matching in gdb_test, which means using ""
> > as the expected output is the same as matching anything.
> 
> Don't remember if I was playing around with using the
> gdb_test_no_output or not.  I can't remember now.  I may have been
> and
> got distracted and never got back to it????   Yea, the
> gdb_test_no_output works just as well as the gdb_test.  Changed to
> following tests as well.  Note, looks like I did use the
> gdb_test_no_output in the ISA 2.07 test.
> 
> Again, retested this patch to make sure I didn't break anything.
> 
> Thanks for the detailed review.
> 
>                                 Carl 
> -----------------------------------------------------------
> GDB PowerPC record test cases for ISA 2.06 and ISA 3.1
> 
> This patch adds PowerPC specific tests to verify recording of various
> instructions.  The first test case checks the ISA 2.06 lxvd2x
> instruction.
> The second test case tests several of the ISA 3.01
> instructions.  Specifically,
> it checks the word and prefixed instructions and some of the Matrix
> Multiply Assist (MMA) instructions.
> 
> The patch has been run on both Power 10 and Power 9 to verify the ISA
> 2.06 test case runs on both platforms without errors.  The ISA 3.1
> test
> runs without errors on Power 10 and is skipped as expected on Power
> 9.
> ---
>  .../gdb.reverse/ppc_record_test_isa_2_06.c    |  39 ++
>  .../gdb.reverse/ppc_record_test_isa_2_06.exp  | 105 ++++++
>  .../gdb.reverse/ppc_record_test_isa_3_1.c     |  95 +++++
>  .../gdb.reverse/ppc_record_test_isa_3_1.exp   | 341
> ++++++++++++++++++
>  4 files changed, 580 insertions(+)
>  create mode 100644
> gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
>  create mode 100644
> gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
>  create mode 100644
> gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
>  create mode 100644
> gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> 
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
> b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
> new file mode 100644
> index 00000000000..45e58413da2
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
> @@ -0,0 +1,39 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2012-2022 Free Software Foundation, Inc.
> +
> +   This program is free software; you can redistribute it and/or
> modify
> +   it under the terms of the GNU General Public License as published
> by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <
> http://www.gnu.org/licenses/>.  */
> +
> +/* globals used for vector tests */
> +static vector unsigned long vec_xb;
> +static unsigned long ra, rb, rs;
> +
> +int
> +main ()
> +{
> +  ra = 0xABCDEF012;
> +  rb = 0;
> +  rs = 0x012345678;
> +
> +  /* 9.0, 16.0, 25.0, 36.0 */
> +  vec_xb = (vector unsigned long){0x4110000041800000,
> 0x41c8000042100000};
> +
> +  /* Test ISA 2.06 instructions.  Load source into vs1, result of
> sqrt
> +     put into vs0.  */
> +  ra = (unsigned long) & vec_xb;        /* stop 1 */
> +  __asm__ __volatile__ ("lxvd2x 1, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("xvsqrtsp 0, 1");
> +  ra = 0;                               /* stop 2 */
> +}
> +
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
> b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
> new file mode 100644
> index 00000000000..d68dd7b9049
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
> @@ -0,0 +1,105 @@
> +# Copyright 2008-2022 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or
> modify
> +# it under the terms of the GNU General Public License as published
> by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <
> http://www.gnu.org/licenses/>.
> +#
> +# Test instruction record for PowerPC, ISA 2.06.
> +#
> +
> +# The basic flow of the record tests are:
> +#    1) Stop before executing the instructions of interest.  Record
> +#       the initial value of the registers that the instruction will
> +#       change, i.e. the destination register.
> +#    2) Execute the instructions.  Record the new value of the
> +#       registers that changed.
> +#    3) Reverse the direction of the execution and execute back to
> +#       just before the instructions of interest.  Record the final
> +#       value of the registers of interest.
> +#    4) Check that the initial and new values of the registers are
> +#       different, i.e. the instruction changed the registers as
> expected.
> +#    5) Check that the initial and final values of the registers are
> +#       the same, i.e. gdb record restored the registers to their
> +#       original values.
> +
> +standard_testfile
> +
> +set gen_src record_test_isa_2_06.c
> +set executable record_test_isa_2_06
> +set options [list debug]
> +
> +if {![istarget "powerpc*"]} then {
> +    verbose "Skipping PowerPC ISA 2.06 instruction
> record_test_2_06."
> +    return
> +}
> +
> +if {[build_executable "failed to prepare" $executable $srcfile
> $options] == -1} then {
> +    return -1
> +}
> +
> +clean_restart $executable
> +
> +if ![runto_main] then {
> +    untested "could not run to main"
> +    continue
> +}
> +
> +gdb_test_no_output "record"
> +
> +###### Test: Test an ISA 2.06 load (lxvd2x) and square root
> instruction
> +###### (xvsqrtsp).  The load instruction will load vs1.  The sqrt
> instruction
> +###### will put its result into vs0.
> +
> +set stop1 [gdb_get_line_number "stop 1"]
> +set stop2 [gdb_get_line_number "stop 2"]
> +
> +gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 1"
> +
> +# Record the initial values in vs0, vs1.
> +set vs0_initial [capture_command_output "info register vs0" ""]
> +set vs1_initial [capture_command_output "info register vs1" ""]
> +
> +gdb_test "break $stop2" ".*Breakpoint .*" "executed lxvd2x,
> xvsqrtsp"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 2"
> +
> +# Record the new values of vs0 and vs1.
> +set vs0_new [capture_command_output "info register vs0" ""]
> +set vs1_new [capture_command_output "info register vs1" ""]
> +
> +# Reverse the execution direction.
> +gdb_test_no_output "set exec-direction reverse"
> +gdb_test "break $stop1" ".*Breakpoint .*" "un executed lxvd2x,
> xvsqrtsp"
> +
> +# Execute in reverse to before the lxvd2x instruction.
> +gdb_test "continue"  ".*Breakpoint.*" "at stop 1 in reverse"
> +
> +# Record the final values of vs0, vs1.
> +set vs0_final [capture_command_output "info register vs0" ""]
> +set vs1_final [capture_command_output "info register vs1" ""]
> +
> +# Check initial and new of vs0 are different.
> +gdb_assert [string compare $vs0_initial $vs1_new] \
> +    "check vs0 initial versus vs0 new"
> +
> +# Check initial and new of vs1 are different.
> +gdb_assert [string compare $vs1_initial $vs1_new] \
> +    "check vs0 initial versus vs1 new"
> +
> +# Check initial and final are the same.
> +gdb_assert ![string compare $vs0_initial $vs0_final] \
> +    "check vs0 initial versus vs0 final"
> +
> +# Check initial and final are the same.
> +gdb_assert ![string compare $vs1_initial $vs1_final] \
> +    "check vs1 initial versus vs1 final"
> +
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
> b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
> new file mode 100644
> index 00000000000..c0d65d944af
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
> @@ -0,0 +1,95 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2012-2022 Free Software Foundation, Inc.
> +
> +   This program is free software; you can redistribute it and/or
> modify
> +   it under the terms of the GNU General Public License as published
> by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <
> http://www.gnu.org/licenses/>.  */
> +
> +/* Globals used for vector tests.  */
> +static vector unsigned long vec_xa, vec_xb, vec_xt;
> +static unsigned long ra, rb, rs;
> +
> +int
> +main ()
> +{
> +  ra = 0xABCDEF012;
> +  rb = 0;
> +  rs = 0x012345678;
> +
> +  /* 9.0, 16.0, 25.0, 36.0 */
> +  vec_xb = (vector unsigned long){0x4110000041800000,
> 0x41c8000042100000};
> +
> +  vec_xt = (vector unsigned long){0xFF00FF00FF00FF00,
> 0xAA00AA00AA00AA00};
> +
> +  /* Test 1, ISA 3.1 word instructions. Load source into r1, result
> of brh
> +     put in r0.  */
> +  ra = 0xABCDEF012;                     /* stop 1 */
> +  __asm__ __volatile__ ("pld 1, %0" :: "r" (ra ));
> +  __asm__ __volatile__ ("brh 0, 1" );
> +  ra = 0;                               /* stop 2 */
> +
> +  /* Test 2, ISA 3.1 MMA instructions with results in various ACC
> entries
> +     xxsetaccz    - ACC[3]
> +     xvi4ger8     - ACC[4]
> +     xvf16ger2pn  - ACC[5]
> +     pmxvi8ger4   - ACC[6]
> +     pmxvf32gerpp - ACC[7] and fpscr */
> +  /* Need to initialize the vs registers to a non zero value.  */
> +  ra = (unsigned long) & vec_xb;
> +  __asm__ __volatile__ ("lxvd2x 12, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 13, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 14, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 15, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xa = (vector unsigned long){0x333134343987601,
> 0x9994bbbc9983307};
> +  vec_xb = (vector unsigned long){0x411234041898760,
> 0x41c833042103400};
> +  __asm__ __volatile__ ("lxvd2x 16, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x123456789987650,
> 0x235676546989807};
> +  __asm__ __volatile__ ("lxvd2x 17, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x878363439823470,
> 0x413434c99839870};
> +  __asm__ __volatile__ ("lxvd2x 18, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x043765434398760,
> 0x419876555558850};
> +  __asm__ __volatile__ ("lxvd2x 19, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x33313434398760,
> 0x9994bbbc99899330};
> +  __asm__ __volatile__ ("lxvd2x 20, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 21, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 22, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 23, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 24, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 25, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 26, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 27, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xa = (vector unsigned long){0x33313434398760,
> 0x9994bbbc998330};
> +  vec_xb = (vector unsigned long){0x4110000041800000,
> 0x41c8000042100000};
> +  __asm__ __volatile__ ("lxvd2x 28, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x4567000046800000,
> 0x4458000048700000};
> +  __asm__ __volatile__ ("lxvd2x 29, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x41dd000041e00000,
> 0x41c8000046544400};
> +  __asm__ __volatile__ ("lxvd2x 30, %0, %1" :: "r" (ra ), "r" (rb));
> +
> +  /* SNAN */
> +  vec_xb = (vector unsigned long){0x7F8F00007F8F0000,
> 0x7F8F00007F8F0000};
> +
> +  __asm__ __volatile__ ("lxvd2x 31, %0, %1" :: "r" (ra ), "r" (rb));
> +
> +  ra = 0xAB;                            /* stop 3 */
> +  __asm__ __volatile__ ("xxsetaccz 3");
> +  __asm__ __volatile__ ("xvi4ger8 4, %x0, %x1" :: "wa" (vec_xa), \
> +			"wa" (vec_xb) );
> +  __asm__ __volatile__ ("xvf16ger2pn 5, %x0, %x1" :: "wa" (vec_xa),\
> +			"wa" (vec_xb) );
> +  __asm__ __volatile__ ("pmxvi8ger4spp  6, %x0, %x1, 11, 13, 5"
> +                                :: "wa" (vec_xa), "wa" (vec_xb) );
> +  __asm__ __volatile__ ("pmxvf32gerpp  7, %x0, %x1, 11, 13"
> +                                :: "wa" (vec_xa), "wa" (vec_xb) );
> +  ra = 0;                               /* stop 4 */
> +}
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> new file mode 100644
> index 00000000000..9ea8931e9cf
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> @@ -0,0 +1,341 @@
> +# Copyright 2008-2022 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or
> modify
> +# it under the terms of the GNU General Public License as published
> by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <
> http://www.gnu.org/licenses/>.
> +#
> +# Test instruction record for PowerPC, ISA 3.1.
> +#
> +
> +# The basic flow of the record tests are:
> +#    1) Stop before executing the instructions of interest.  Record
> +#       the initial value of the registers that the instruction will
> +#       change, i.e. the destination register.
> +#    2) Execute the instructions.  Record the new value of the
> +#       registers that changed.
> +#    3) Reverse the direction of the execution and execute back to
> +#       just before the instructions of interest.  Record the final
> +#       value of the registers of interest.
> +#    4) Check that the initial and new values of the registers are
> +#       different, i.e. the instruction changed the registers as
> expected.
> +#    5) Check that the initial and final values of the registers are
> +#       the same, i.e. gdb record restored the registers to their
> +#       original values.
> +
> +
> +standard_testfile
> +
> +set gen_src record_test_isa_3_1.c
> +set executable record_test_isa_3_1
> +
> +if {![istarget "powerpc*"] || [skip_power_isa_3_1_tests] } then  {
> +    verbose "Skipping PowerPC ISA 3.1 instruction record_test."
> +    return
> +}
> +
> +set options [list additional_flags=-mcpu=power10 debug]
> +if {[build_executable "failed to prepare" $executable $srcfile
> $options] == -1} then {
> +    return -1
> +}
> +
> +clean_restart $executable
> +
> +if ![runto_main] then {
> +    untested "could not run to main"
> +    continue
> +}
> +
> +gdb_test_no_output "record"
> +
> +######  Test 1:  Test an ISA 3.1 byte reverse word instruction (brd)
> and a
> +######  prefixed load double (pld) instruction.
> +set stop1 [gdb_get_line_number "stop 1"]
> +set stop2 [gdb_get_line_number "stop 2"]
> +
> +gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test 1"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 1"
> +
> +# Record the initial values in r0, r1
> +# Load the argument into r1, result of byte reverse is put into r0.
> +set r0_initial [capture_command_output "info register r0" ""]
> +set r1_initial [capture_command_output "info register r1" ""]
> +
> +gdb_test "break $stop2" ".*Breakpoint .*" "executed test 1"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 2"
> +
> +# Record the new values of r0 and r1
> +set r0_new [capture_command_output "info register r0" ""]
> +set r1_new [capture_command_output "info register r1" ""]
> +
> +# Execute in reverse to before test 1
> +gdb_test_no_output "set exec-direction reverse"
> +
> +gdb_test "break $stop1" ".*Breakpoint .*" "reverse stop at test 1
> start"
> +gdb_test "continue"  ".*Breakpoint.*" "at stop 1 in reverse"
> +
> +# Record the final values of r0, r1
> +set r0_final [capture_command_output "info register r0" ""]
> +set r1_final [capture_command_output "info register r1" ""]
> +
> +# Check initial and new of r0 are different.
> +gdb_assert [string compare $r0_initial $r0_new] \
> +    "check r0 initial versus r0 new"
> +
> +# Check initial and new of r1 are different.
> +gdb_assert [string compare $r1_initial $r1_new] \
> +    "check r0 initial versus r1 new"
> +
> +# Check initial and final are the same.
> +gdb_assert ![string compare $r0_initial $r0_final] \
> +    "check r0 initial versus r0 final"
> +
> +# Check initial and final are the same.
> +gdb_assert ![string compare $r1_initial $r1_final] \
> +    "check r1 initial versus r1 final"
> +
> +
> +# Change execution direction to forward for next test.
> +gdb_test_no_output "set exec-direction forward" "start forward
> test3"
> +gdb_test "record stop" ".*Process record is stopped.*" "stopped
> recording 2"
> +set test_del_bkpts "delete breakpoints, answer prompt 2"
> +
> +# Delete all breakpoints and catchpoints.
> +delete_breakpoints
> +
> +gdb_test_no_output "record" "start recording test2"
> +
> +
> +######  Test 2:  Test the ISA 3.1 MMA instructions xxsetaccz,
> xvi4ger8,
> +######  xvf16ger2pn, pmxvi8ger4, and pmxvf32gerpp.  Goal here is to
> hit all
> +######  the places where ppc_record_ACC_fpscr() gets called.
> +##
> +##       xxsetaccz    - ACC[3], vs[12] to vs[15]
> +##       xvi4ger8     - ACC[4], vs[16] to vs[19]
> +##       xvf16ger2pn  - ACC[5], vs[20] to vs[23]
> +##       pmxvi8ger4   - ACC[6], vs[21] to vs[27]
> +##       pmxvf32gerpp - ACC[7], vs[28] to vs[31] and fpscr
> +
> +set stop3 [gdb_get_line_number "stop 3"]
> +set stop4 [gdb_get_line_number "stop 4"]
> +
> +gdb_test "break $stop3" ".*Breakpoint .*" "about to execute test 2"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 3"
> +
> +# Record the initial values of vs's that correspond to the ACC
> entries,
> +# and fpscr.
> +set acc_3_0_initial [capture_command_output "info register vs12" ""]
> +set acc_3_1_initial [capture_command_output "info register vs13" ""]
> +set acc_3_2_initial [capture_command_output "info register vs14" ""]
> +set acc_3_3_initial [capture_command_output "info register vs15" ""]
> +set acc_4_0_initial [capture_command_output "info register vs16" ""]
> +set acc_4_1_initial [capture_command_output "info register vs17" ""]
> +set acc_4_2_initial [capture_command_output "info register vs18" ""]
> +set acc_4_3_initial [capture_command_output "info register vs19" ""]
> +set acc_5_0_initial [capture_command_output "info register vs20" ""]
> +set acc_5_1_initial [capture_command_output "info register vs21" ""]
> +set acc_5_2_initial [capture_command_output "info register vs22" ""]
> +set acc_5_3_initial [capture_command_output "info register vs23" ""]
> +set acc_6_0_initial [capture_command_output "info register vs24" ""]
> +set acc_6_1_initial [capture_command_output "info register vs25" ""]
> +set acc_6_2_initial [capture_command_output "info register vs26" ""]
> +set acc_6_3_initial [capture_command_output "info register vs27" ""]
> +set acc_7_0_initial [capture_command_output "info register vs28" ""]
> +set acc_7_1_initial [capture_command_output "info register vs29" ""]
> +set acc_7_2_initial [capture_command_output "info register vs30" ""]
> +set acc_7_3_initial [capture_command_output "info register vs31" ""]
> +set fpscr_initial [capture_command_output "info register fpscr" ""]
> +
> +gdb_test "break $stop4" ".*Breakpoint .*" "executed test 2"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 4"
> +
> +# Record the new values of the ACC entries and fpscr.
> +set acc_3_0_new [capture_command_output "info register vs12" ""]
> +set acc_3_1_new [capture_command_output "info register vs13" ""]
> +set acc_3_2_new [capture_command_output "info register vs14" ""]
> +set acc_3_3_new [capture_command_output "info register vs15" ""]
> +set acc_4_0_new [capture_command_output "info register vs16" ""]
> +set acc_4_1_new [capture_command_output "info register vs17" ""]
> +set acc_4_2_new [capture_command_output "info register vs18" ""]
> +set acc_4_3_new [capture_command_output "info register vs19" ""]
> +set acc_5_0_new [capture_command_output "info register vs20" ""]
> +set acc_5_1_new [capture_command_output "info register vs21" ""]
> +set acc_5_2_new [capture_command_output "info register vs22" ""]
> +set acc_5_3_new [capture_command_output "info register vs23" ""]
> +set acc_6_0_new [capture_command_output "info register vs24" ""]
> +set acc_6_1_new [capture_command_output "info register vs25" ""]
> +set acc_6_2_new [capture_command_output "info register vs26" ""]
> +set acc_6_3_new [capture_command_output "info register vs27" ""]
> +set acc_7_0_new [capture_command_output "info register vs28" ""]
> +set acc_7_1_new [capture_command_output "info register vs29" ""]
> +set acc_7_2_new [capture_command_output "info register vs30" ""]
> +set acc_7_3_new [capture_command_output "info register vs31" ""]
> +set fpscr_new [capture_command_output "info register fpscr" ""]
> +
> +# Execute in reverse to before test 2.
> +gdb_test_no_output "set exec-direction reverse" "reverse to start of
> test 2"
> +
> +gdb_test "break $stop3" ".*Breakpoint .*" "reverse stop at test 2
> start"
> +gdb_test "continue"  ".*Breakpoint.*" "at stop 3 in reverse"
> +
> +# Record the final values of the ACC entries and fpscr.
> +set acc_3_0_final [capture_command_output "info register vs12" ""]
> +set acc_3_1_final [capture_command_output "info register vs13" ""]
> +set acc_3_2_final [capture_command_output "info register vs14" ""]
> +set acc_3_3_final [capture_command_output "info register vs15" ""]
> +set acc_4_0_final [capture_command_output "info register vs16" ""]
> +set acc_4_1_final [capture_command_output "info register vs17" ""]
> +set acc_4_2_final [capture_command_output "info register vs18" ""]
> +set acc_4_3_final [capture_command_output "info register vs19" ""]
> +set acc_5_0_final [capture_command_output "info register vs20" ""]
> +set acc_5_1_final [capture_command_output "info register vs21" ""]
> +set acc_5_2_final [capture_command_output "info register vs22" ""]
> +set acc_5_3_final [capture_command_output "info register vs23" ""]
> +set acc_6_0_final [capture_command_output "info register vs24" ""]
> +set acc_6_1_final [capture_command_output "info register vs25" ""]
> +set acc_6_2_final [capture_command_output "info register vs26" ""]
> +set acc_6_3_final [capture_command_output "info register vs27" ""]
> +set acc_7_0_final [capture_command_output "info register vs28" ""]
> +set acc_7_1_final [capture_command_output "info register vs29" ""]
> +set acc_7_2_final [capture_command_output "info register vs30" ""]
> +set acc_7_3_final [capture_command_output "info register vs31" ""]
> +set fpscr_final [capture_command_output "info register fpscr" ""]
> +
> +# check initial and new ACC entries are different.
> +gdb_assert [string compare $acc_3_0_initial $acc_3_0_new] \
> +    "check vs12 initial versus new"
> +
> +gdb_assert [string compare $acc_3_1_initial $acc_3_1_new] \
> +    "check vs13 initial versus new"
> +
> +gdb_assert [string compare $acc_3_2_initial $acc_3_2_new] \
> +    "check vs14 initial versus new"
> +
> +gdb_assert [string compare $acc_3_3_initial $acc_3_3_new] \
> +    "check vs15 initial versus new"
> +
> +gdb_assert [string compare $acc_4_0_initial $acc_4_0_new] \
> +    "check vs16 initial versus new"
> +
> +gdb_assert [string compare $acc_4_1_initial $acc_4_1_new] \
> +    "check vs17 initial versus new"
> +
> +gdb_assert [string compare $acc_4_2_initial $acc_4_2_new] \
> +    "check vs18 initial versus new"
> +
> +gdb_assert [string compare $acc_4_3_initial $acc_4_3_new] \
> +    "check vs19 initial versus new"
> +
> +gdb_assert [string compare $acc_5_0_initial $acc_5_0_new] \
> +    "check vs20 initial versus new"
> +
> +gdb_assert [string compare $acc_5_1_initial $acc_5_1_new] \
> +    "check vs21 initial versus new"
> +
> +gdb_assert [string compare $acc_5_2_initial $acc_5_2_new] \
> +    "check vs22 initial versus new"
> +
> +gdb_assert [string compare $acc_5_3_initial $acc_5_3_new] \
> +    "check vs23 initial versus new"
> +
> +gdb_assert [string compare $acc_6_0_initial $acc_6_0_new] \
> +    "check vs24 initial versus new"
> +
> +gdb_assert [string compare $acc_6_1_initial $acc_6_1_new] \
> +    "check vs25 initial versus new"
> +
> +gdb_assert [string compare $acc_6_2_initial $acc_6_2_new] \
> +    "check vs26 initial versus new"
> +
> +gdb_assert [string compare $acc_6_3_initial $acc_6_3_new] \
> +    "check vs27 initial versus new"
> +
> +gdb_assert [string compare $acc_7_0_initial $acc_7_0_new] \
> +    "check vs28 initial versus new"
> +
> +gdb_assert [string compare $acc_7_1_initial $acc_7_1_new] \
> +    "check vs29 initial versus new"
> +
> +gdb_assert [string compare $acc_7_2_initial $acc_7_2_new] \
> +    "check vs30 initial versus new"
> +
> +gdb_assert [string compare $acc_7_3_initial $acc_7_3_new] \
> +    "check vs31 initial versus new"
> +
> +gdb_assert [string compare $fpscr_initial $fpscr_new] \
> +    "check fpscr initial versus new"
> +
> +
> +# Check initial and final ACC entries are the same.
> +gdb_assert ![string compare $acc_3_0_initial $acc_3_0_final] \
> +    "check vs12 initial versus final"
> +
> +gdb_assert ![string compare $acc_3_1_initial $acc_3_1_final] \
> +    "check vs13 initial versus final"
> +
> +gdb_assert ![string compare $acc_3_2_initial $acc_3_2_final] \
> +    "check vs14 initial versus final"
> +
> +gdb_assert ![string compare $acc_3_3_initial $acc_3_3_final] \
> +    "check vs15 initial versus final"
> +
> +gdb_assert ![string compare $acc_4_0_initial $acc_4_0_final] \
> +    "check vs16 initial versus final"
> +
> +gdb_assert ![string compare $acc_4_1_initial $acc_4_1_final] \
> +    "check vs17 initial versus final"
> +
> +gdb_assert ![string compare $acc_4_2_initial $acc_4_2_final] \
> +    "check vs18 initial versus final"
> +
> +gdb_assert ![string compare $acc_4_3_initial $acc_4_3_final] \
> +    "check vs19 initial versus final"
> +
> +gdb_assert ![string compare $acc_5_0_initial $acc_5_0_final] \
> +    "check vs20 initial versus final"
> +
> +gdb_assert ![string compare $acc_5_1_initial $acc_5_1_final] \
> +    "check vs21 initial versus final"
> +
> +gdb_assert ![string compare $acc_5_2_initial $acc_5_2_final] \
> +    "check vs22 initial versus final"
> +
> +gdb_assert ![string compare $acc_5_3_initial $acc_5_3_final] \
> +    "check vs23 initial versus final"
> +
> +gdb_assert ![string compare $acc_6_0_initial $acc_6_0_final] \
> +    "check vs24 initial versus final"
> +
> +gdb_assert ![string compare $acc_6_1_initial $acc_6_1_final] \
> +    "check vs25 initial versus final"
> +
> +gdb_assert ![string compare $acc_6_2_initial $acc_6_2_final] \
> +    "check vs26 initial versus final"
> +
> +gdb_assert ![string compare $acc_6_3_initial $acc_6_3_final] \
> +    "check vs27 initial versus final"
> +
> +gdb_assert ![string compare $acc_7_0_initial $acc_7_0_final] \
> +    "check vs28 initial versus final"
> +
> +gdb_assert ![string compare $acc_7_1_initial $acc_7_1_final] \
> +    "check vs29 initial versus final"
> +
> +gdb_assert ![string compare $acc_7_2_initial $acc_7_2_final] \
> +    "check !vs30 initial versus final"
> +
> +gdb_assert ![string compare $acc_7_3_initial $acc_7_3_final] \
> +    "check !vs31 initial versus final"
> +
> +gdb_assert ![string compare $fpscr_initial $fpscr_final] \
> +    "check fpscr initial versus final"
> +
> +


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/2  Version 5 Ping] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-18 19:21             ` [PATCH 1/2 Version 5] " Carl Love
@ 2022-04-22 19:49               ` Carl Love
  2022-04-24 16:50               ` [PATCH 1/2 Version 5] " Joel Brobecker
  1 sibling, 0 replies; 25+ messages in thread
From: Carl Love @ 2022-04-22 19:49 UTC (permalink / raw)
  To: Joel Brobecker, cel
  Cc: will schmidt, gdb-patches, Ulrich Weigand, Tulio Magno, Rogerio Alves

On Mon, 2022-04-18 at 12:21 -0700, Carl Love wrote:

Joel, Pedro, Will, GDB maintainers:

Just checking to see if the patch is OK now.  Haven't heard anything on
this version.   Thanks.

                  Carl Love


> 
> Joel, Pedro, Will, GDB maintainers:
> 
> On Sun, 2022-04-17 at 09:23 -0700, Joel Brobecker wrote:
> > On Wed, Apr 13, 2022 at 10:26:47AM -0700, Carl Love wrote:
> > 
> > > Add recording support for the ISA 3.1 Powerpc instructions.
> > 
> > Thanks for the updated version. I have a few more requests of
> > a trivial natural (Coding Style, and I apologize if this is a bit
> > frustrating for you - I wish we had a tool like in python that
> > we could use to just automate the whole thing...).
> 
> Yea, it would speed things up.  GCC has a script that runs when you
> try
> to checkin a patch.  Not sure how much coding style it checks.  It
> does
> check the change log entries.  It would be nice to have a stand alone
> script that could be run on a patch to check coding style before
> posting or committing a patch.  It would save a lot of time and
> effort.
> 
> 
> I updated the patch with the typos you mentioned and found an
> additional one as well.  I updated the header comment for
> ppc_record_ACC_fpscr().  I think it is simpler and cleaner now.
> 
> This patch was retested with the updated (version 5) testcases to
> verify the patch is still ok.
> 
>                      Carl 
> 
> -----------------------------------------------------------------
> Add recording support for the ISA 3.1 PowerPC instructions.
> 
> This patch adds support for the PowerPC ISA 3.1 instructions to the
> PowerPC
> gdb instruction recording routines.  Case statement entries are added
> to a
> number of the existing routines for recording the 32-bit word
> instructions.
> A few new functions were added to handle the new word
> instructions.  The 64-bit
> prefix instructions are all handled by a set of new routines.  The
> function
> ppc_process_prefix_instruction() is the primary function to handle
> the
> prefixed instructions. It calls additional functions to handle
> specific
> sets of prefixed instructions.  These new functions are:
>   ppc_process_record_prefix_vsx_d_form(),
>   ppc_process_record_prefix_store_vsx_ds_form(),
>   ppc_process_record_prefix_op34(),
>   ppc_process_record_prefix_op33(),
>   ppc_process_record_prefix_op32(),
>   ppc_process_record_prefix_store(),
>   ppc_process_record_prefix_op59_XX3(),
>   ppc_process_record_prefix_op42().
> ---
>  gdb/rs6000-tdep.c | 1197
> ++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 1171 insertions(+), 26 deletions(-)
> 
> diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
> index 44828bcff6d..8259d9d8454 100644
> --- a/gdb/rs6000-tdep.c
> +++ b/gdb/rs6000-tdep.c
> @@ -4123,8 +4123,25 @@ bfd_uses_spe_extensions (bfd *abfd)
>  #define PPC_LEV(insn)	PPC_FIELD (insn, 20, 7)
> 
>  #define PPC_XT(insn)	((PPC_TX (insn) << 5) | PPC_T (insn))
> +#define PPC_XTp(insn)	((PPC_BIT (insn, 10) << 5)	\
> +			 | PPC_FIELD (insn, 6, 4) << 1)
> +#define PPC_XSp(insn)	((PPC_BIT (insn, 10) << 5)	\
> +			 | PPC_FIELD (insn, 6, 4) << 1)
>  #define PPC_XER_NB(xer)	(xer & 0x7f)
> 
> +/* The following macros are for the prefixed instructions.  */
> +#define P_PPC_D(insn_prefix, insn_suffix) \
> +  PPC_SEXT (PPC_FIELD (insn_prefix, 14, 18) << 16 \
> +	    | PPC_FIELD (insn_suffix, 16, 16), 34)
> +#define P_PPC_TX5(insn_sufix)	PPC_BIT (insn_suffix, 5)
> +#define P_PPC_TX15(insn_suffix) PPC_BIT (insn_suffix, 15)
> +#define P_PPC_XT(insn_suffix)	((PPC_TX (insn_suffix) << 5) \
> +				 | PPC_T (insn_suffix))
> +#define P_PPC_XT5(insn_suffix) ((P_PPC_TX5 (insn_suffix) << 5) \
> +				| PPC_T (insn_suffix))
> +#define P_PPC_XT15(insn_suffix) \
> +  ((P_PPC_TX15 (insn_suffix) << 5) | PPC_T (insn_suffix))
> +
>  /* Record Vector-Scalar Registers.
>     For VSR less than 32, it's represented by an FPR and an VSR-upper 
> register.
>     Otherwise, it's just a VR register.  Record them accordingly.  */
> @@ -4152,6 +4169,61 @@ ppc_record_vsr (struct regcache *regcache,
> ppc_gdbarch_tdep *tdep, int vsr)
>    return 0;
>  }
> 
> +/* The ppc_record_ACC_fpscr() records the changes to the VSR
> registers
> +   modified by a floating point instruction.  The at argument gives
> which of
> +   the 8 AT entries to record.  The save_fpscr argument is used to
> indicate
> +   if the FPSCR also needs to be recorded.  The function returns 0
> on
> +   success.  */
> +
> +#define RECORD_FPSCR 1
> +#define DO_NOT_RECORD_FPSCR 0
> +
> +static int
> +ppc_record_ACC_fpscr (struct regcache *regcache, ppc_gdbarch_tdep
> *tdep,
> +		      int at, int save_fpscr)
> +{
> +  int i;
> +  if (at < 0 || at >= 8)
> +    return -1;
> +
> +  /* The ACC register file consists of 8 register entries, each
> register
> +     entry consist of four 128-bit rows.
> +
> +     The ACC rows map to specific VSR registers.
> +         ACC[0][0] -> VSR[0]
> +         ACC[0][1] -> VSR[1]
> +         ACC[0][2] -> VSR[2]
> +         ACC[0][3] -> VSR[3]
> +              ...
> +         ACC[7][0] -> VSR[28]
> +         ACC[7][1] -> VSR[29]
> +         ACC[7][2] -> VSR[30]
> +         ACC[7][3] -> VSR[31]
> +
> +     NOTE:
> +     In ISA 3.1 the ACC is mapped on top of VSR[0] thru VSR[31].
> +
> +     In the future, the ACC may be implemented as an independent
> register file
> +     rather than mapping on top of the VSRs.  This will then require
> the ACC to
> +     be assigned its own register number and the ptrace interface to
> be able
> +     access the ACC.  Note the ptrace interface for the ACC will
> also need to
> +     be implemented.  */
> +
> +  /* ACC maps over the same VSR space as the fp registers.  */
> +  for (i = 0; i < 4; i++)
> +    {
> +      record_full_arch_list_add_reg (regcache, tdep->ppc_fp0_regnum
> +				     + at * 4 + i);
> +      record_full_arch_list_add_reg (regcache,
> +				     tdep->ppc_vsr0_upper_regnum + at *
> 4 + i);
> +    }
> +
> +  if (save_fpscr)
> +    record_full_arch_list_add_reg (regcache, tdep-
> >ppc_fpscr_regnum);
> +
> +  return 0;
> +}
> +
>  /* Parse and record instructions primary opcode-4 at ADDR.
>     Return 0 if successful.  */
> 
> @@ -4171,9 +4243,34 @@ ppc_process_record_op4 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>      case 41:		/* Vector Multiply-Sum Signed Halfword Saturate
> */
>        record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
>        /* FALL-THROUGH */
> +    case 20:		/* Move To VSR Byte Mask Immediate opcode, b2 =
> 0,
> +			   ignore bit 31 */
> +    case 21:		/* Move To VSR Byte Mask Immediate opcode, b2 =
> 1,
> +			   ignore bit 31 */
> +    case 23:		/* Vector Multiply-Sum & write Carry-out
> Unsigned
> +			   Doubleword */
> +    case 24:		/* Vector Extract Double Unsigned Byte to VSR
> +			   using GPR-specified Left-Index */
> +    case 25:		/* Vector Extract Double Unsigned Byte to VSR
> +			   using GPR-specified Right-Index */
> +    case 26:		/* Vector Extract Double Unsigned Halfword to
> VSR
> +			   using GPR-specified Left-Index */
> +    case 27:		/* Vector Extract Double Unsigned Halfword to
> VSR
> +			   using GPR-specified Right-Index */
> +    case 28:		/* Vector Extract Double Unsigned Word to VSR
> +			   using GPR-specified Left-Index */
> +    case 29:		/* Vector Extract Double Unsigned Word to VSR
> +			   using GPR-specified Right-Index */
> +    case 30:		/* Vector Extract Double Unsigned Doubleword to
> VSR
> +			   using GPR-specified Left-Index */
> +    case 31:		/* Vector Extract Double Unsigned Doubleword to
> VSR
> +			   using GPR-specified Right-Index */
>      case 42:		/* Vector Select */
>      case 43:		/* Vector Permute */
>      case 59:		/* Vector Permute Right-indexed */
> +    case 22: 		/* Vector Shift
> +			      Left  Double by Bit Immediate if insn[21]
> = 0
> +			      Right Double by Bit Immediate if insn[21]
> = 1 */
>      case 44:		/* Vector Shift Left Double by Octet Immediate
> */
>      case 45:		/* Vector Permute and Exclusive-OR */
>      case 60:		/* Vector Add Extended Unsigned Quadword Modulo
> */
> @@ -4236,6 +4333,9 @@ ppc_process_record_op4 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>    /* Bit-21 is used for RC */
>    switch (ext & 0x3ff)
>      {
> +    case 5:		/* Vector Rotate Left Quadword */
> +    case 69:		/* Vector Rotate Left Quadword then Mask Insert
> */
> +    case 325:		/* Vector Rotate Left Quadword then AND
> with Mask */
>      case 6:		/* Vector Compare Equal To Unsigned Byte */
>      case 70:		/* Vector Compare Equal To Unsigned Halfword */
>      case 134:		/* Vector Compare Equal To Unsigned
> Word */
> @@ -4244,13 +4344,16 @@ ppc_process_record_op4 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>      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 903:		/* Vector Compare Greater Than Signed
> Quadword */
>      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 647:		/* Vector Compare Greater Than Unsigned
> Quadword */
>      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 455:		/* Vector Compare Equal Quadword */
>      case 710:		/* Vector Compare Greater Than Single-
> Precision */
>      case 7:		/* Vector Compare Not Equal Byte */
>      case 71:		/* Vector Compare Not Equal Halfword */
> @@ -4263,6 +4366,21 @@ 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 13:
> +      switch (vra)    /* Bit-21 is used for RC */
> +	{
> +	case 0:       /* Vector String Isolate Byte Left-justified */
> +	case 1:       /* Vector String Isolate Byte Right-justified */
> +	case 2:       /* Vector String Isolate Halfword Left-justified
> */
> +	case 3:       /* Vector String Isolate Halfword Right-justified 
> */
> +	  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;
> +	}
>      }
> 
>    if (ext  == 1538)
> @@ -4287,6 +4405,7 @@ ppc_process_record_op4 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>  	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 27:	/* Vector Extend Sign Doubleword To Quadword */
>  	case 28:	/* Vector Count Trailing Zeros Byte */
>  	case 29:	/* Vector Count Trailing Zeros Halfword */
>  	case 30:	/* Vector Count Trailing Zeros Word */
> @@ -4297,8 +4416,57 @@ ppc_process_record_op4 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>  	}
>      }
> 
> +  if (ext == 1602)
> +    {
> +      switch (vra)
> +	{
> +	case 0: 	/* Vector Expand Byte Mask */
> +	case 1: 	/* Vector Expand Halfword Mask */
> +	case 2: 	/* Vector Expand Word Mask */
> +	case 3: 	/* Vector Expand Doubleword Mask */
> +	case 4: 	/* Vector Expand Quadword Mask */
> +	case 16:	/* Move to VSR Byte Mask */
> +	case 17:	/* Move to VSR Halfword Mask */
> +	case 18:	/* Move to VSR Word Mask */
> +	case 19:	/* Move to VSR Doubleword Mask */
> +	case 20:	/* Move to VSR Quadword Mask */
> +	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
> +	  return 0;
> +
> +	case 8: 	/* Vector Extract Byte Mask */
> +	case 9: 	/* Vector Extract Halfword Mask */
> +	case 10: 	/* Vector Extract Word Mask */
> +	case 11: 	/* Vector Extract Doubleword Mask */
> +	case 12: 	/* Vector Extract Quadword Mask */
> +
> +	/* Ignore the MP bit in the LSB position of the vra value. */
> +	case 24:	/* Vector Count Mask Bits Byte, MP = 0 */
> +	case 25:	/* Vector Count Mask Bits Byte, MP = 1 */
> +	case 26:	/* Vector Count Mask Bits Halfword, MP = 0 */
> +	case 27:	/* Vector Count Mask Bits Halfword, MP = 1 */
> +	case 28:	/* Vector Count Mask Bits Word, MP = 0 */
> +	case 29:	/* Vector Count Mask Bits Word, MP = 1 */
> +	case 30:	/* Vector Count Mask Bits Doubleword, MP = 0 */
> +	case 31:	/* Vector Count Mask Bits Doubleword, MP = 1 */
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_gp0_regnum + PPC_RT
> (insn));
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_gp0_regnum + PPC_RT
> (insn));
> +	  return 0;
> +	}
> +    }
> +
>    switch (ext)
>      {
> +
> +    case 257:		/* Vector Compare Unsigned Quadword */
> +    case 321:		/* Vector Compare Signed Quadword */
> +      /* Comparison tests that always set CR field BF */
> +      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;
> +
>      case 142:		/* Vector Pack Unsigned Halfword
> Unsigned Saturate */
>      case 206:		/* Vector Pack Unsigned Word Unsigned
> Saturate */
>      case 270:		/* Vector Pack Signed Halfword Unsigned
> Saturate */
> @@ -4338,6 +4506,8 @@ ppc_process_record_op4 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>      case 268:		/* Vector Merge Low Byte */
>      case 332:		/* Vector Merge Low Halfword */
>      case 396:		/* Vector Merge Low Word */
> +    case 397:		/* Vector Clear Leftmost Bytes */
> +    case 461:		/* Vector Clear Rightmost Bytes */
>      case 526:		/* Vector Unpack High Signed Byte */
>      case 590:		/* Vector Unpack High Signed Halfword
> */
>      case 654:		/* Vector Unpack Low Signed Byte */
> @@ -4356,8 +4526,11 @@ ppc_process_record_op4 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>      case 780:		/* Vector Splat Immediate Signed Byte
> */
>      case 844:		/* Vector Splat Immediate Signed
> Halfword */
>      case 908:		/* Vector Splat Immediate Signed Word
> */
> +    case 261:		/* Vector Shift Left Quadword */
>      case 452:		/* Vector Shift Left */
> +    case 517:		/* Vector Shift Right Quadword */
>      case 708:		/* Vector Shift Right */
> +    case 773:		/* Vector Shift Right Algebraic
> Quadword */
>      case 1036:		/* Vector Shift Left by Octet */
>      case 1100:		/* Vector Shift Right by Octet */
>      case 0:		/* Vector Add Unsigned Byte Modulo */
> @@ -4370,15 +4543,43 @@ ppc_process_record_op4 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>      case 8:		/* Vector Multiply Odd Unsigned Byte */
>      case 72:		/* Vector Multiply Odd Unsigned Halfword */
>      case 136:		/* Vector Multiply Odd Unsigned Word */
> +    case 200:		/* Vector Multiply Odd Unsigned
> Doubleword */
>      case 264:		/* Vector Multiply Odd Signed Byte */
>      case 328:		/* Vector Multiply Odd Signed Halfword
> */
>      case 392:		/* Vector Multiply Odd Signed Word */
> +    case 456:		/* Vector Multiply Odd Signed
> Doubleword */
>      case 520:		/* Vector Multiply Even Unsigned Byte
> */
>      case 584:		/* Vector Multiply Even Unsigned
> Halfword */
>      case 648:		/* Vector Multiply Even Unsigned Word
> */
> +    case 712:		/* Vector Multiply Even Unsigned
> Doubleword */
>      case 776:		/* Vector Multiply Even Signed Byte */
>      case 840:		/* Vector Multiply Even Signed Halfword
> */
>      case 904:		/* Vector Multiply Even Signed Word */
> +    case 968:		/* Vector Multiply Even Signed
> Doubleword */
> +    case 457:		/* Vector Multiply Low Doubleword */
> +    case 649:		/* Vector Multiply High Unsigned Word
> */
> +    case 713:		/* Vector Multiply High Unsigned
> Doubleword */
> +    case 905:		/* Vector Multiply High Signed Word */
> +    case 969:		/* Vector Multiply High Signed
> Doubleword */
> +    case 11:		/* Vector Divide Unsigned Quadword */
> +    case 203:		/* Vector Divide Unsigned Doubleword */
> +    case 139:		/* Vector Divide Unsigned Word */
> +    case 267:		/* Vector Divide Signed Quadword */
> +    case 459:		/* Vector Divide Signed Doubleword */
> +    case 395:		/* Vector Divide Signed Word */
> +    case 523:		/* Vector Divide Extended Unsigned
> Quadword */
> +    case 715:		/* Vector Divide Extended Unsigned
> Doubleword */
> +    case 651:		/* Vector Divide Extended Unsigned Word
> */
> +    case 779:		/* Vector Divide Extended Signed
> Quadword */
> +    case 971:		/* Vector Divide Extended Signed
> Doubleword */
> +    case 907:		/* Vector Divide Extended Unsigned Word
> */
> +    case 1547:		/* Vector Modulo Unsigned Quadword */
> +    case 1675:		/* Vector Modulo Unsigned Word */
> +    case 1739:		/* Vector Modulo Unsigned Doubleword */
> +    case 1803:		/* Vector Modulo Signed Quadword */
> +    case 1931:		/* Vector Modulo Signed Word */
> +    case 1995:		/* Vector Modulo Signed Doubleword */
> +
>      case 137:		/* Vector Multiply Unsigned Word Modulo
> */
>      case 1024:		/* Vector Subtract Unsigned Byte Modulo
> */
>      case 1088:		/* Vector Subtract Unsigned Halfword
> Modulo */
> @@ -4462,7 +4663,11 @@ ppc_process_record_op4 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>      case 1794:		/* Vector Count Leading Zeros Byte */
>      case 1858:		/* Vector Count Leading Zeros Halfword
> */
>      case 1922:		/* Vector Count Leading Zeros Word */
> +    case 1924:		/* Vector Count Leading Zeros
> Doubleword under
> +			   bit Mask*/
>      case 1986:		/* Vector Count Leading Zeros
> Doubleword */
> +    case 1988:		/* Vector Count Trailing Zeros
> Doubleword under bit
> +			   Mask */
>      case 1795:		/* Vector Population Count Byte */
>      case 1859:		/* Vector Population Count Halfword */
>      case 1923:		/* Vector Population Count Word */
> @@ -4488,14 +4693,50 @@ ppc_process_record_op4 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>      case 589:		/* Vector Extract Unsigned Halfword */
>      case 653:		/* Vector Extract Unsigned Word */
>      case 717:		/* Vector Extract Doubleword */
> +    case 15:		/* Vector Insert Byte from VSR using GPR-
> specified
> +			   Left-Index */
> +    case 79:		/* Vector Insert Halfword from VSR using GPR-
> specified
> +			   Left-Index */
> +    case 143:		/* Vector Insert Word from VSR using
> GPR-specified
> +			   Left-Index */
> +    case 207:		/* Vector Insert Word from GPR using
> +			   immediate-specified index */
> +    case 463:		/* Vector Insert Doubleword from GPR
> using
> +			   immediate-specified index */
> +    case 271:		/* Vector Insert Byte from VSR using
> GPR-specified
> +			   Right-Index */
> +    case 335:		/* Vector Insert Halfword from VSR
> using GPR-specified
> +			   Right-Index */
> +    case 399:		/* Vector Insert Word from VSR using
> GPR-specified
> +			   Right-Index */
> +    case 527:		/* Vector Insert Byte from GPR using
> GPR-specified
> +			   Left-Index */
> +    case 591:		/* Vector Insert Halfword from GPR
> using GPR-specified
> +			   Left-Index */
> +    case 655:		/* Vector Insert Word from GPR using
> GPR-specified
> +			   Left-Index */
> +    case 719:		/* Vector Insert Doubleword from GPR
> using
> +			    GPR-specified Left-Index */
> +    case 783:		/* Vector Insert Byte from GPR using
> GPR-specified
> +			   Right-Index */
> +    case 847:		/* Vector Insert Halfword from GPR
> using GPR-specified
> +			   Left-Index */
> +    case 911:		/* Vector Insert Word from GPR using
> GPR-specified
> +			   Left-Index */
> +    case 975:		/* Vector Insert Doubleword from GPR
> using
> +			    GPR-specified Right-Index */
>      case 781:		/* Vector Insert Byte */
>      case 845:		/* Vector Insert Halfword */
>      case 909:		/* Vector Insert Word */
>      case 973:		/* Vector Insert Doubleword */
> +    case 1357:		/* Vector Centrifuge Doubleword */
> +    case 1421:		/* Vector Parallel Bits Extract
> Doubleword */
> +    case 1485:		/* Vector Parallel Bits Deposit
> Doubleword */
>        record_full_arch_list_add_reg (regcache,
>  				     tdep->ppc_vr0_regnum + PPC_VRT
> (insn));
>        return 0;
> 
> +    case 1228:		/* Vector Gather every Nth Bit */
>      case 1549:		/* Vector Extract Unsigned Byte Left-
> Indexed */
>      case 1613:		/* Vector Extract Unsigned Halfword
> Left-Indexed */
>      case 1677:		/* Vector Extract Unsigned Word Left-
> Indexed */
> @@ -4525,6 +4766,34 @@ ppc_process_record_op4 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>    return -1;
>  }
> 
> +/* Parse and record instructions of primary opcode 6 at ADDR.
> +   Return 0 if successful.  */
> +
> +static int
> +ppc_process_record_op6 (struct gdbarch *gdbarch, struct regcache
> *regcache,
> +			CORE_ADDR addr, uint32_t insn)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
> +  int subtype = PPC_FIELD (insn, 28, 4);
> +  CORE_ADDR ea = 0;
> +
> +  switch (subtype)
> +    {
> +    case 0:    /* Load VSX Vector Paired */
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
> +      return 0;
> +    case 1:    /* Store VSX Vector Paired */
> +      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, 32);
> +      return 0;
> +    }
> +  return -1;
> +}
> +
>  /* Parse and record instructions of primary opcode-19 at ADDR.
>     Return 0 if successful.  */
> 
> @@ -4577,6 +4846,30 @@ ppc_process_record_op19 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>    return -1;
>  }
> 
> +/* Parse and record instructions of primary opcode-31 with the
> extended opcode
> +   177.  The argument is the word instruction (insn).  Return 0 if
> successful.
> +*/
> +
> +static int
> +ppc_process_record_op31_177 (struct gdbarch *gdbarch,
> +			     struct regcache *regcache,
> +			     uint32_t insn)
> +{
> +  int RA_opcode = PPC_RA(insn);
> +  int as = PPC_FIELD (insn, 6, 3);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
> +
> +  switch (RA_opcode)
> +    {
> +    case 0: 		/* VSX Move From Accumulator, xxmfacc */
> +    case 1: 		/* VSX Move To Accumulator, xxmtacc */
> +    case 3: 		/* VSX Set Accumulator to Zero, xxsetaccz */
> +      ppc_record_ACC_fpscr (regcache, tdep, as,
> DO_NOT_RECORD_FPSCR);
> +      return 0;
> +    }
> +  return -1;
> +}
> +
>  /* Parse and record instructions of primary opcode-31 at ADDR.
>     Return 0 if successful.  */
> 
> @@ -4586,7 +4879,7 @@ ppc_process_record_op31 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>  {
>    ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
>    int ext = PPC_EXTOP (insn);
> -  int tmp, nr, nb, i;
> +  int tmp, nr, nb = 0, i;
>    CORE_ADDR at_dcsz, ea = 0;
>    ULONGEST rb, ra, xer;
>    int size = 0;
> @@ -4677,6 +4970,10 @@ ppc_process_record_op31 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>      case 371:		/* Move From Time Base [Phased-Out]  */
>      case 309:		/* Load Doubleword Monitored
> Indexed  */
>      case 128:		/* Set Boolean */
> +    case 384:		/* Set Boolean Condition */
> +    case 416:		/* Set Boolean Condition Reverse */
> +    case 448:		/* Set Negative Boolean Condition */
> +    case 480:		/* Set Negative Boolean Condition
> Reverse */
>      case 755:		/* Deliver A Random Number */
>        record_full_arch_list_add_reg (regcache,
>  				     tdep->ppc_gp0_regnum + PPC_RT
> (insn));
> @@ -4684,8 +4981,15 @@ ppc_process_record_op31 (struct gdbarch
> *gdbarch, struct regcache *regcache,
> 
>      /* These only write to RA.  */
>      case 51:		/* Move From VSR Doubleword */
> +    case 59:		/* Count Leading Zeros Doubleword under bit
> Mask */
>      case 115:		/* Move From VSR Word and Zero */
>      case 122:		/* Population count bytes */
> +    case 155:		/* Byte-Reverse Word */
> +    case 156:		/* Parallel Bits Deposit Doubleword */
> +    case 187:		/* Byte-Reverse Doubleword */
> +    case 188:		/* Parallel Bits Extract Doubleword */
> +    case 219:		/* Byte-Reverse Halfword */
> +    case 220:		/* Centrifuge Doubleword */
>      case 378:		/* Population count words */
>      case 506:		/* Population count doublewords */
>      case 154:		/* Parity Word */
> @@ -4695,6 +4999,7 @@ ppc_process_record_op31 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>      case 314:		/* Convert Binary Coded Decimal To
> Declets */
>      case 508:		/* Compare bytes */
>      case 307:		/* Move From VSR Lower Doubleword */
> +    case 571:		/* Count Trailing Zeros Doubleword
> under bit Mask */
>        record_full_arch_list_add_reg (regcache,
>  				     tdep->ppc_gp0_regnum + PPC_RA
> (insn));
>        return 0;
> @@ -4819,6 +5124,7 @@ ppc_process_record_op31 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>        record_full_arch_list_add_reg (regcache, tmp + 1);
>        return 0;
> 
> +    /* These write to destination register PPC_XT. */
>      case 179:		/* Move To VSR Doubleword */
>      case 211:		/* Move To VSR Word Algebraic */
>      case 243:		/* Move To VSR Word and Zero */
> @@ -4826,6 +5132,10 @@ ppc_process_record_op31 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>      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 13:		/* Load VSX Vector Rightmost Byte Indexed */
> +    case 45:		/* Load VSX Vector Rightmost Halfword Indexed
> */
> +    case 77:		/* Load VSX Vector Rightmost Word Indexed */
> +    case 109:		/* Load VSX Vector Rightmost Doubleword
> 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 */
> @@ -4842,6 +5152,11 @@ ppc_process_record_op31 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>        ppc_record_vsr (regcache, tdep, PPC_XT (insn));
>        return 0;
> 
> +    case 333:		/* Load VSX Vector Paired Indexed */
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
> +      return 0;
> +
>      /* These write RA.  Update CR if RC is set.  */
>      case 24:		/* Shift Left Word */
>      case 26:		/* Count Leading Zeros Word */
> @@ -5006,6 +5321,31 @@ ppc_process_record_op31 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>        record_full_arch_list_add_mem (ea, size);
>        return 0;
> 
> +    case 141:		/* Store VSX Vector Rightmost Byte
> Indexed */
> +    case 173:		/* Store VSX Vector Rightmost Halfword
> Indexed */
> +    case 205:		/* Store VSX Vector Rightmost Word
> Indexed */
> +    case 237:		/* Store VSX Vector Rightmost
> Doubleword Indexed */
> +      switch(ext)
> +	{
> +	  case 141: nb = 1;
> +	  break;
> +	  case 173: nb = 2;
> +	  break;
> +	  case 205: nb = 4;
> +	  break;
> +	  case 237: nb = 8;
> +	  break;
> +	}
> +      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;
> +      record_full_arch_list_add_mem (ea, nb);
> +      return 0;
> +
>      case 397:		/* Store VSX Vector with Length */
>      case 429:		/* Store VSX Vector Left-justified with
> Length */
>        ra = 0;
> @@ -5021,6 +5361,19 @@ ppc_process_record_op31 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>  	record_full_arch_list_add_mem (ea, nb);
>        return 0;
> 
> +    case 461:		/* Store VSX Vector Paired Indexed */
> +      {
> +	if (PPC_RA (insn) != 0)
> +	  regcache_raw_read_unsigned (regcache,
> +				      tdep->ppc_gp0_regnum
> +				      + PPC_RA (insn), &ea);
> +	regcache_raw_read_unsigned (regcache,
> +				    tdep->ppc_gp0_regnum + PPC_RB
> (insn), &rb);
> +	ea += rb;
> +	record_full_arch_list_add_mem (ea, 32);
> +	return 0;
> +      }
> +
>      case 710:		/* Store Word Atomic */
>      case 742:		/* Store Doubleword Atomic */
>        ra = 0;
> @@ -5166,6 +5519,10 @@ ppc_process_record_op31 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>        ea = (ra + rb) & ~((ULONGEST) (at_dcsz - 1));
>        record_full_arch_list_add_mem (ea, at_dcsz);
>        return 0;
> +
> +    case 177:
> +      if (ppc_process_record_op31_177 (gdbarch, regcache, insn) ==
> 0)
> +	return 0;
>      }
> 
>  UNKNOWN_OP:
> @@ -5179,10 +5536,11 @@ ppc_process_record_op31 (struct gdbarch
> *gdbarch, struct regcache *regcache,
> 
>  static int
>  ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache
> *regcache,
> -			   CORE_ADDR addr, uint32_t insn)
> +			 CORE_ADDR addr, uint32_t insn)
>  {
>    ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
>    int ext = PPC_EXTOP (insn);
> +  int at = PPC_FIELD (insn, 6, 3);
> 
>    switch (ext & 0x1f)
>      {
> @@ -5206,6 +5564,75 @@ ppc_process_record_op59 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>        return 0;
>      }
> 
> +  /* MMA instructions, keep looking.  */
> +  switch (ext >> 2)    /* Additional opcode field is upper 8-bits of
> ext */
> +    {
> +    case 3:	/* VSX Vector 8-bit Signed/Unsigned Integer GER,
> xvi8ger4 */
> +    case 2:	/* VSX Vector 8-bit Signed/Unsigned Integer GER
> Positive
> +		   multiply, Positive accumulate, xvi8ger4pp */
> +
> +    case 99:	/* VSX Vector 8-bit Signed/Unsigned Integer GER with
> +		   Saturate Positive multiply, Positive accumulate,
> +		   xvi8ger4spp */
> +
> +    case 35:	/* VSX Vector 4-bit Signed Integer GER, xvi4ger8 */
> +    case 34:	/* VSX Vector 4-bit Signed Integer GER Positive
> multiply,
> +		   Positive accumulate, xvi4ger8pp */
> +
> +    case 75:	/* VSX Vector 16-bit Signed Integer GER, xvi16ger2 */
> +    case 107:	/* VSX Vector 16-bit Signed Integer
> GER  Positive multiply,
> +		   Positive accumulate, xvi16ger2pp */
> +
> +    case 43:	/* VSX Vector 16-bit Signed Integer GER with
> Saturation,
> +		   xvi16ger2s */
> +    case 42:	/* VSX Vector 16-bit Signed Integer GER with Saturation
> +		   Positive multiply, Positive accumulate, xvi16ger2spp
> */
> +      ppc_record_ACC_fpscr (regcache, tdep, at,
> DO_NOT_RECORD_FPSCR);
> +      return 0;
> +
> +    case 19:	/* VSX Vector 16-bit Floating-Point GER, xvf16ger2 */
> +    case 18:	/* VSX Vector 16-bit Floating-Point GER Positive
> multiply,
> +		   Positive accumulate, xvf16ger2pp */
> +    case 146:	/* VSX Vector 16-bit Floating-Point GER
> Positive multiply,
> +		   Negative accumulate, xvf16ger2pn */
> +    case 82:	/* VSX Vector 16-bit Floating-Point GER Negative
> multiply,
> +		   Positive accumulate, xvf16ger2np */
> +    case 210:	/* VSX Vector 16-bit Floating-Point GER
> Negative multiply,
> +		   Negative accumulate, xvf16ger2nn */
> +
> +    case 27:	/* VSX Vector 32-bit Floating-Point GER, xvf32ger */
> +    case 26:	/* VSX Vector 32-bit Floating-Point GER Positive
> multiply,
> +		   Positive accumulate, xvf32gerpp */
> +    case 154:	/* VSX Vector 32-bit Floating-Point GER
> Positive multiply,
> +		   Negative accumulate, xvf32gerpn */
> +    case 90:	/* VSX Vector 32-bit Floating-Point GER Negative
> multiply,
> +		   Positive accumulate, xvf32gernp */
> +    case 218:	/* VSX Vector 32-bit Floating-Point GER
> Negative multiply,
> +		   Negative accumulate, xvf32gernn */
> +
> +    case 59:	/* VSX Vector 64-bit Floating-Point GER, pmxvf64ger */
> +    case 58:	/* VSX Vector 64-bit Floating-Point GER Positive
> multiply,
> +		   Positive accumulate, xvf64gerpp */
> +    case 186:	/* VSX Vector 64-bit Floating-Point GER
> Positive multiply,
> +		   Negative accumulate, xvf64gerpn */
> +    case 122:	/* VSX Vector 64-bit Floating-Point GER
> Negative multiply,
> +		   Positive accumulate, xvf64gernp */
> +    case 250:	/* VSX Vector 64-bit Floating-Point GER
> Negative multiply,
> +		   Negative accumulate, pmxvf64gernn */
> +
> +    case 51:	/* VSX Vector bfloat16 GER, xvbf16ger2 */
> +    case 50:	/* VSX Vector bfloat16 GER Positive multiply,
> +		   Positive accumulate, xvbf16ger2pp */
> +    case 178:	/* VSX Vector bfloat16 GER Positive multiply,
> +		   Negative accumulate, xvbf16ger2pn */
> +    case 114:	/* VSX Vector bfloat16 GER Negative multiply,
> +		   Positive accumulate, xvbf16ger2np */
> +    case 242:	/* VSX Vector bfloat16 GER Negative multiply,
> +		   Negative accumulate, xvbf16ger2nn */
> +      ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
> +      return 0;
> +    }
> +
>    switch (ext)
>      {
>      case 2:		/* DFP Add */
> @@ -5268,6 +5695,48 @@ ppc_process_record_op59 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>    return -1;
>  }
> 
> +/* Parse and record an XX2-Form instruction with opcode 60 at
> ADDR.  The
> +   word instruction is an argument insn.  Return 0 if
> successful.  */
> +
> +static int
> +ppc_process_record_op60_XX2 (struct gdbarch *gdbarch,
> +			     struct regcache *regcache,
> +			     CORE_ADDR addr, uint32_t insn)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
> +  int RA_opcode = PPC_RA(insn);
> +
> +  switch (RA_opcode)
> +    {
> +    case 2:	/* VSX Vector Test Least-Significant Bit by Byte */
> +    case 25:	/* VSX Vector round and Convert Single-Precision format
> +		   to Half-Precision format.  Only changes the CR
> +		   field.  */
> +      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
> +      return 0;
> +    case 17:	/* VSX Vector Convert with round Single-Precision
> +		   to bfloat16 format */
> +    case 24:	/* VSX Vector Convert Half-Precision format to
> +		   Single-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 16:	/* VSX Vector Convert bfloat16 to Single-Precision
> +		   format Non-signaling */
> +    case 23:	/* VSX Vector Byte-Reverse Doubleword */
> +    case 31:	/* VSX Vector Byte-Reverse Quadword */
> +      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
> +      return 0;
> +    }
> +
> +  return -1;
> +}
> +
>  /* Parse and record instructions of primary opcode-60 at ADDR.
>     Return 0 if successful.  */
> 
> @@ -5583,37 +6052,30 @@ ppc_process_record_op60 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>        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;
> +      if (ppc_process_record_op60_XX2 (gdbarch, regcache, addr,
> insn) != 0)
> +	return -1;
> +      return 0;
>      }
> 
>    switch (ext)
>      {
> -    case 360:		/* VSX Vector Splat Immediate Byte */
> -      if (PPC_FIELD (insn, 11, 2) == 0)
> +    case 360:
> +      if (PPC_FIELD (insn, 11, 2) == 0)  /* VSX Vector Splat
> Immediate Byte */
> +	{
> +	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
> +	  return 0;
> +	}
> +      if (PPC_FIELD (insn, 11, 5) == 31)  /* Load VSX Vector Special
> Value
> +					     Quadword */
>  	{
>  	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
>  	  return 0;
>  	}
>        break;
> +    case 916:		/* VSX Vector Generate PCV from Byte
> Mask */
> +    case 917:		/* VSX Vector Generate PCV from
> Halfword Mask */
> +    case 948:		/* VSX Vector Generate PCV from Word
> Mask */
> +    case 949:		/* VSX Vector Generate PCV from
> Doubleword Mask */
>      case 918:		/* VSX Scalar Insert Exponent Double-
> Precision */
>        ppc_record_vsr (regcache, tdep, PPC_XT (insn));
>        return 0;
> @@ -5894,6 +6356,35 @@ ppc_process_record_op63 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>  			   Quad-Precision */
>      case 516:		/* VSX Scalar Subtract Quad-Precision
> */
>      case 548:		/* VSX Scalar Divide Quad-Precision */
> +    case 994:
> +      {
> +      switch (PPC_FIELD (insn, 11, 5))
> +	{
> +	case 0:	/* DFP Convert From Fixed Quadword Quad */
> +	  record_full_arch_list_add_reg (regcache, tdep-
> >ppc_fpscr_regnum);
> +
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_fp0_regnum
> +					 + PPC_FRT (insn));
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_fp0_regnum
> +					 + PPC_FRT (insn) + 1);
> +	  return 0;
> +	case 1:	/* DFP Convert To Fixed Quadword Quad */
> +	  record_full_arch_list_add_reg (regcache, tdep-
> >ppc_fpscr_regnum);
> +	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
> +	  return 0;
> +	}
> +      }
> +
> +      record_full_arch_list_add_reg (regcache, tdep-
> >ppc_fpscr_regnum);
> +      /* FALL-THROUGH */
> +    case 68:		/* VSX Scalar Compare Equal Quad-Precision */
> +    case 196:		/* VSX Scalar Compare Greater Than or
> Equal
> +			   Quad-Precision */
> +    case 228:		/* VSX Scalar Compare Greater Than
> Quad-Precision */
> +    case 676:		/* VSX Scalar Maximum Type-C Quad-
> Precision */
> +    case 740:		/* VSX Scalar Minimum Type-C Quad-
> Precision */
>        record_full_arch_list_add_reg (regcache, tdep-
> >ppc_fpscr_regnum);
>        /* FALL-THROUGH */
>      case 100:		/* VSX Scalar Copy Sign Quad-Precision
> */
> @@ -5920,14 +6411,22 @@ ppc_process_record_op63 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>      case 836:
>        switch (PPC_FIELD (insn, 11, 5))
>  	{
> +	case 0:		/* VSX Scalar Convert with round to zero
> +			   Quad-Precision to Unsigned Quadword  */
>  	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 3:		/* VSX Scalar Convert with round
> +			   Unsigned Quadword to Quad-Precision  */
> +	case 8:		/* VSX Scalar Convert with round to zero
> +			   Quad-Precision to Signed Quadword  */
>  	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 11:	/* VSX Scalar Convert with round
> +			   Signed Quadword to Quad-Precision */
>  	case 17:	/* VSX Scalar truncate & Convert Quad-Precision
> format
>  			   to Unsigned Doubleword format */
>  	case 20:	/* VSX Scalar round & Convert Quad-Precision format
> to
> @@ -5947,17 +6446,651 @@ ppc_process_record_op63 (struct gdbarch
> *gdbarch, struct regcache *regcache,
>    return -1;
>  }
> 
> +/* Record the prefixed instructions with primary opcode 32.  The
> arguments are
> +   the first 32-bits of the instruction (insn_prefix), and the
> second 32-bits
> +   of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_op42 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t
> insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +
> +  if (ST1 != 0)
> +    return -1;
> +
> +  switch (type)
> +    {
> +    case 0:  /* Prefixed Load VSX Scalar Doubleword, plxsd */
> +      ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
> +      break;
> +    case 2:  /* Prefixed Load Halfword Algebraic, plha */
> +      record_full_arch_list_add_reg (regcache,
> +				     tdep->ppc_gp0_regnum
> +				     + PPC_RT (insn_suffix));
> +      break;
> +    default:
> +      return -1;
> +    }
> +  return 0;
> +}
> +
> +/* Record the prefixed XX3-Form instructions with primary opcode
> 59.  The
> +   arguments are the first 32-bits of the instruction (insn_prefix),
> and the
> +   second 32-bits of the instruction (insn_suffix).  Return 0 on
> success.  */
> +
> +static int
> +ppc_process_record_prefix_op59_XX3 (struct gdbarch *gdbarch,
> +				    struct regcache *regcache,
> +				    uint32_t insn_prefix, uint32_t
> insn_suffix)
> +{
> +  int opcode = PPC_FIELD (insn_suffix, 21, 8);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  int at = PPC_FIELD (insn_suffix, 6, 3);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
> +
> +  if (type == 3)
> +    {
> +      if (ST4 == 9)
> +	switch (opcode)
> +	  {
> +	  case 35:	/* Prefixed Masked VSX Vector 4-bit Signed
> Integer GER
> +			   MMIRR, pmxvi4ger8 */
> +	  case 34:	/* Prefixed Masked VSX Vector 4-bit Signed
> Integer GER
> +			   MMIRR, pmxvi4ger8pp */
> +
> +	  case 99:	/* Prefixed Masked VSX Vector 8-bit
> Signed/Unsigned
> +			   Integer GER with Saturate Positive multiply,
> +			   Positive accumulate, xvi8ger4spp */
> +
> +	  case 3:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
> +			   Integer GER MMIRR, pmxvi8ger4 */
> +	  case 2:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
> +			   Integer GER Positive multiply, Positive
> accumulate
> +			   MMIRR, pmxvi8ger4pp */
> +
> +	  case 75:	/* Prefixed Masked VSX Vector 16-bit Signed
> Integer
> +			   GER MMIRR, pmxvi16ger2 */
> +	  case 107:	/* Prefixed Masked VSX Vector 16-bit Signed
> Integer
> +			   GER  Positive multiply, Positive accumulate,
> +			   pmxvi16ger2pp */
> +
> +	  case 43:	/* Prefixed Masked VSX Vector 16-bit Signed
> Integer
> +			   GER with Saturation MMIRR, pmxvi16ger2s */
> +	  case 42:	/* Prefixed Masked VSX Vector 16-bit Signed
> Integer
> +			   GER with Saturation Positive multiply,
> Positive
> +			   accumulate MMIRR, pmxvi16ger2spp */
> +	    ppc_record_ACC_fpscr (regcache, tdep, at,
> DO_NOT_RECORD_FPSCR);
> +	    return 0;
> +
> +	  case 19:	/* Prefixed Masked VSX Vector 16-bit
> Floating-Point
> +			   GER MMIRR, pmxvf16ger2 */
> +	  case 18:	/* Prefixed Masked VSX Vector 16-bit
> Floating-Point
> +			   GER Positive multiply, Positive accumulate
> MMIRR,
> +			   pmxvf16ger2pp */
> +	  case 146:	/* Prefixed Masked VSX Vector 16-bit
> Floating-Point
> +			   GER Positive multiply, Negative accumulate
> MMIRR,
> +			   pmxvf16ger2pn */
> +	  case 82:	/* Prefixed Masked VSX Vector 16-bit
> Floating-Point
> +			   GER Negative multiply, Positive accumulate
> MMIRR,
> +			   pmxvf16ger2np */
> +	  case 210:	/* Prefixed Masked VSX Vector 16-bit
> Floating-Point
> +			   GER Negative multiply, Negative accumulate
> MMIRR,
> +			   pmxvf16ger2nn */
> +
> +	  case 27:	/* Prefixed Masked VSX Vector 32-bit
> Floating-Point
> +			   GER MMIRR, pmxvf32ger */
> +	  case 26:	/* Prefixed Masked VSX Vector 32-bit
> Floating-Point
> +			   GER Positive multiply, Positive accumulate
> MMIRR,
> +			   pmxvf32gerpp */
> +	  case 154:	/* Prefixed Masked VSX Vector 32-bit
> Floating-Point
> +			   GER Positive multiply, Negative accumulate
> MMIRR,
> +			   pmxvf32gerpn */
> +	  case 90:	/* Prefixed Masked VSX Vector 32-bit
> Floating-Point
> +			   GER Negative multiply, Positive accumulate
> MMIRR,
> +			   pmxvf32gernp */
> +	  case 218:	/* Prefixed Masked VSX Vector 32-bit
> Floating-Point
> +			   GER Negative multiply, Negative accumulate
> MMIRR,
> +			   pmxvf32gernn */
> +
> +	  case 59:	/* Prefixed Masked VSX Vector 64-bit
> Floating-Point
> +			   GER MMIRR, pmxvf64ger */
> +	  case 58:	/* Floating-Point GER Positive multiply,
> Positive
> +			   accumulate MMIRR, pmxvf64gerpp */
> +	  case 186:	/* Prefixed Masked VSX Vector 64-bit
> Floating-Point
> +			   GER Positive multiply, Negative accumulate
> MMIRR,
> +			   pmxvf64gerpn */
> +	  case 122:	/* Prefixed Masked VSX Vector 64-bit
> Floating-Point
> +			   GER Negative multiply, Positive accumulate
> MMIRR,
> +			   pmxvf64gernp */
> +	  case 250:	/* Prefixed Masked VSX Vector 64-bit
> Floating-Point
> +			   GER Negative multiply, Negative accumulate
> MMIRR,
> +			   pmxvf64gernn */
> +
> +	  case 51:	/* Prefixed Masked VSX Vector bfloat16 GER
> MMIRR,
> +			   pmxvbf16ger2 */
> +	  case 50:	/* Prefixed Masked VSX Vector bfloat16 GER
> Positive
> +			   multiply, Positive accumulate MMIRR,
> +			   pmxvbf16ger2pp */
> +	  case 178:	/* Prefixed Masked VSX Vector bfloat16 GER
> Positive
> +			   multiply, Negative accumulate MMIRR,
> +			   pmxvbf16ger2pn */
> +	  case 114:	/* Prefixed Masked VSX Vector bfloat16 GER
> Negative
> +			   multiply, Positive accumulate MMIRR,
> +			   pmxvbf16ger2np */
> +	  case 242:	/* Prefixed Masked VSX Vector bfloat16 GER
> Negative
> +			   multiply, Negative accumulate MMIRR,
> +			   pmxvbf16ger2nn */
> +	    ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
> +	    return 0;
> +	  }
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed store instructions.  The arguments are the
> instruction
> +   address, the first 32-bits of the instruction(insn_prefix) and
> the following
> +   32-bits of the instruction (insn_suffix).  Return 0 on
> success.  */
> +
> +static int
> +ppc_process_record_prefix_store (struct gdbarch *gdbarch,
> +				 struct regcache *regcache,
> +				 CORE_ADDR addr, uint32_t insn_prefix,
> +				 uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
> +  ULONGEST iaddr = 0;
> +  int size;
> +  int R = PPC_BIT (insn_prefix, 11);
> +  int op6 = PPC_OP6 (insn_suffix);
> +
> +  if (R == 0)
> +    {
> +      if (PPC_RA (insn_suffix) != 0)
> +	regcache_raw_read_unsigned (regcache, tdep->ppc_gp0_regnum
> +				    + PPC_RA (insn_suffix), &iaddr);
> +    }
> +  else
> +    {
> +      iaddr = addr;     /* PC relative */
> +    }
> +
> +  switch (op6)
> +    {
> +    case 38:
> +      size =  1;    /* store byte, pstb */
> +      break;
> +    case 44:
> +      size =  2;    /* store halfword, psth */
> +      break;
> +    case 36:
> +    case 52:
> +      size =  4;    /* store word, pstw, pstfs */
> +      break;
> +    case 54:
> +    case 61:
> +      size =  8;    /* store double word, pstd, pstfd */
> +      break;
> +    case 60:
> +      size = 16;    /* store quadword, pstq */
> +      break;
> +    default: return -1;
> +    }
> +
> +  iaddr += P_PPC_D (insn_prefix, insn_suffix);
> +  record_full_arch_list_add_mem (iaddr, size);
> +  return 0;
> +}
> +
> +/* Record the prefixed instructions with primary op code 32.  The
> arguments
> +   are the first 32-bits of the instruction (insn_prefix) and the
> following
> +   32-bits of the instruction (insn_suffix).  Return 0 on
> success.  */
> +
> +static int
> +ppc_process_record_prefix_op32 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t
> insn_suffix)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
> +
> +  if (type == 1)
> +    {
> +      if (ST4 == 0)
> +	{
> +	  switch (PPC_FIELD (insn_suffix, 11, 3))
> +	    {
> +	    case 0:  	/* VSX Vector Splat Immediate Word 8RR,
> xxsplti32dx */
> +	      ppc_record_vsr (regcache, tdep, P_PPC_XT15
> (insn_suffix));
> +	      return 0;
> +	    }
> +
> +	  switch (PPC_FIELD (insn_suffix, 11, 4))
> +	    {
> +	    case 2:  	/* VSX Vector Splat Immediate Double-
> Precision
> +			   8RR, xxspltidp */
> +	    case 3:  	/* VSX Vector Splat Immediate Word 8RR,
> xxspltiw */
> +	      ppc_record_vsr (regcache, tdep, P_PPC_XT15
> (insn_suffix));
> +	      return 0;
> +	    default:
> +	      return -1;
> +	    }
> +	}
> +      else
> +	return -1;
> +
> +    }
> +  else if (type == 2)
> +    {
> +      if (ST1 == 0)  		/* Prefixed Load Word and Zero,
> plwz */
> +	record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	return -1;
> +
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed instructions with primary op code 33.  The
> arguments
> +   are the first 32-bits of the instruction(insn_prefix) and the
> following
> +   32-bits of the instruction (insn_suffix).  Return 0 on
> success.  */
> +
> +static int
> +ppc_process_record_prefix_op33 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t
> insn_suffix)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
> +
> +  if (type == 1)
> +    {
> +      if (ST4 == 0)
> +	switch (PPC_FIELD (insn_suffix, 26, 2))
> +	  {
> +	  case 0:  	/* VSX Vector Blend Variable Byte 8RR,
> xxblendvb */
> +	  case 1:  	/* VSX Vector Blend Variable Halfword,
> xxblendvh */
> +	  case 2:  	/* VSX Vector Blend Variable Word, xxblendvw
> */
> +	  case 3:  	/* VSX Vector Blend Variable Doubleword,
> xxblendvd */
> +	    ppc_record_vsr (regcache, tdep, PPC_XT (insn_suffix));
> +	  break;
> +	  default:
> +	    return -1;
> +	  }
> +      else
> +	return -1;
> +
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed instructions with primary op code 34.  The
> arguments
> +   are the first 32-bits of the instruction(insn_prefix) and the
> following
> +   32-bits of the instruction (insn_suffix).  Return 0 on
> success.  */
> +
> +static int
> +ppc_process_record_prefix_op34 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t
> insn_suffix)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
> +
> +  if (type == 1)
> +    {
> +      if (ST4 == 0)
> +	switch (PPC_FIELD (insn_suffix, 26, 2))
> +	  {
> +	  case 0:  	/* VSX Vector Permute Extended 8RR, xxpermx
> */
> +	  case 1:  	/* VSX Vector Evaluate 8RR, xxeval */
> +	    ppc_record_vsr (regcache, tdep, P_PPC_XT (insn_suffix));
> +	    break;
> +	  default:
> +	    return -1;
> +	  }
> +      else
> +	return -1;
> +
> +    }
> +  else if (type == 2)
> +    {
> +      if (ST1 == 0)  		/* Prefixed Load Word and Zero,
> plbz */
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	return -1;
> +
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed VSX store, form DS, instructions.  The
> arguments are the
> +   instruction address (addr), the first 32-bits of the instruction
> +   (insn_prefix) followed by the 32-bit instruction suffix
> (insn_suffix).
> +   Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_store_vsx_ds_form (struct gdbarch
> *gdbarch,
> +					     struct regcache *regcache,
> +					     CORE_ADDR addr,
> +					     uint32_t insn_prefix,
> +					     uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
> +  ULONGEST ea = 0;
> +  int size;
> +  int R = PPC_BIT (insn_prefix, 11);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +
> +  if ((type == 0) && (ST1 == 0))
> +    {
> +      if (R == 0)
> +	{
> +	  if (PPC_RA (insn_suffix) != 0)
> +	    regcache_raw_read_unsigned (regcache,
> +					tdep->ppc_gp0_regnum
> +					+ PPC_RA (insn_suffix),
> +					&ea);
> +	}
> +      else
> +	{
> +	  ea = addr;     /* PC relative */
> +	}
> +
> +      ea += P_PPC_D (insn_prefix, insn_suffix);
> +      switch (PPC_FIELD (insn_suffix, 0, 6))
> +	{
> +	case 46:    /* Prefixed Store VSX Scalar Doubleword, pstxsd */
> +	  size = 8;
> +	  break;
> +	case 47:    /* Prefixed,Store VSX Scalar Single-Precision,
> pstxssp */
> +	  size = 4;
> +	  break;
> +	default:
> +	  return -1;
> +	}
> +      record_full_arch_list_add_mem (ea, size);
> +      return 0;
> +  }
> +  else
> +    return -1;
> +}
> +
> +/* Record the prefixed VSX, form D, instructions.  The arguments are
> the
> +   instruction address for PC-relative addresss (addr), the first
> 32-bits of
> +   the instruction (insn_prefix) and the following 32-bits of the
> instruction
> +   (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_vsx_d_form (struct gdbarch *gdbarch,
> +				      struct regcache *regcache,
> +				      CORE_ADDR addr,
> +				      uint32_t insn_prefix,
> +				      uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
> +  ULONGEST ea = 0;
> +  int size;
> +  int R = PPC_BIT (insn_prefix, 11);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +
> +  if ((type == 0) && (ST1 == 0))
> +    {
> +      switch (PPC_FIELD (insn_suffix, 0, 5))
> +	{
> +	case 25:	/* Prefixed Load VSX Vector, plxv */
> +	  ppc_record_vsr (regcache, tdep, P_PPC_XT5 (insn_prefix));
> +	  return 0;
> +	case 27:	/* Prefixed Store VSX Vector 8LS, pstxv */
> +	  {
> +	    size = 16;
> +	    if (R == 0)
> +	      {
> +		if (PPC_RA (insn_suffix) != 0)
> +		  regcache_raw_read_unsigned (regcache,
> +					      tdep->ppc_gp0_regnum
> +					      + PPC_RA (insn_suffix),
> +					      &ea);
> +	      }
> +	    else
> +	      {
> +		ea = addr;     /* PC relative */
> +	      }
> +
> +	    ea += P_PPC_D (insn_prefix, insn_suffix);
> +	    record_full_arch_list_add_mem (ea, size);
> +	    return 0;
> +	  }
> +	}
> +      return -1;
> +    }
> +  else
> +    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.  */
> 
> +/* This handles the recording of the various prefix
> instructions.  It takes
> +   the instruction address, the first 32-bits of the instruction
> (insn_prefix)
> +   and the following 32-bits of the instruction
> (insn_suffix).  Return 0 on
> +   success.  */
> +
> +static int
> +ppc_process_prefix_instruction (int insn_prefix, int insn_suffix,
> +				CORE_ADDR addr,	struct gdbarch
> *gdbarch,
> +				struct regcache *regcache)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
> +  int op6;
> +
> +  /* D-form has uses a 5-bit opcode in the instruction suffix */
> +  if (ppc_process_record_prefix_vsx_d_form ( gdbarch, regcache,
> addr,
> +					     insn_prefix, insn_suffix)
> == 0)
> +    goto SUCCESS;
> +
> +  op6 = PPC_OP6 (insn_suffix);  /* 6-bit opcode in the instruction
> suffix */
> +
> +  switch (op6)
> +    {
> +    case 14:		/* Prefixed Add Immediate, paddi */
> +      if ((type == 2) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 32:
> +      if (ppc_process_record_prefix_op32 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) !=
> 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 33:
> +      if (ppc_process_record_prefix_op33 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) !=
> 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 34:		/* Prefixed Load Byte and Zero, plbz */
> +      if (ppc_process_record_prefix_op34 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) !=
> 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +    case 40:		/* Prefixed Load Halfword and Zero, plhz */
> +      if ((type == 2) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +      break;
> +
> +    case 36:		/* Prefixed Store Word, pstw */
> +    case 38:		/* Prefixed Store Byte, pstb */
> +    case 44:		/* Prefixed Store Halfword, psth */
> +    case 52:		/* Prefixed Store Floating-Point Single, pstfs
> */
> +    case 54:		/* Prefixed Store Floating-Point Double, pstfd
> */
> +    case 60:		/* Prefixed Store Quadword, pstq */
> +    case 61:		/* Prefixed Store Doubleword, pstd */
> +      if (ppc_process_record_prefix_store (gdbarch, regcache, addr,
> +					   insn_prefix, insn_suffix) !=
> 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 42:
> +      if (ppc_process_record_prefix_op42 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) !=
> 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 43:          /* Prefixed Load VSX Scalar Single-Precision,
> plxssp */
> +      if ((type == 0) && (ST1 == 0))
> +	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
> +      else
> +	  goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 46:
> +    case 47:
> +      if (ppc_process_record_prefix_store_vsx_ds_form (gdbarch,
> regcache, addr,
> +					       insn_prefix,
> insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 56:		/* Prefixed Load Quadword, plq */
> +      {
> +	if ((type == 0) && (ST1 == 0))
> +	  {
> +	    int tmp;
> +	    tmp = tdep->ppc_gp0_regnum + (PPC_RT (insn_suffix) & ~1);
> +	    record_full_arch_list_add_reg (regcache, tmp);
> +	    record_full_arch_list_add_reg (regcache, tmp + 1);
> +	  }
> +	else
> +	  goto UNKNOWN_PREFIX_OP;
> +	break;
> +      }
> +
> +    case 41:		/* Prefixed Load Word Algebraic, plwa */
> +    case 57:  		/* Prefixed Load Doubleword, pld */
> +      if ((type == 0) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 48:		/* Prefixed Load Floating-Point Single, plfs */
> +    case 50:		/* Prefixed Load Floating-Point Double, plfd */
> +      if ((type == 2) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_fp0_regnum
> +				       + PPC_FRT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 58:		/* Prefixed Load VSX Vector Paired, plxvp */
> +      if ((type == 0) && (ST1 == 0))
> +	{
> +	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix));
> +	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix) + 1);
> +	}
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 59:
> +      if (ppc_process_record_prefix_op59_XX3 (gdbarch, regcache,
> insn_prefix,
> +					      insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 62:	    /* Prefixed Store VSX Vector Paired 8LS, pstxvp */
> +      if ((type == 0) && (ST1 == 0))
> +	{
> +	  int R = PPC_BIT (insn_prefix, 11);
> +	  CORE_ADDR ea = 0;
> +
> +	  if (R == 0)
> +	    {
> +	      if (PPC_RA (insn_suffix) != 0)
> +		regcache_raw_read_unsigned (regcache,
> +					    tdep->ppc_gp0_regnum
> +					    + PPC_RA (insn_suffix),
> &ea);
> +	    }
> +	  else
> +	    {
> +	      ea = addr;     /* PC relative */
> +	    }
> +
> +	  ea += P_PPC_D (insn_prefix, insn_suffix) << 4;
> +	  record_full_arch_list_add_mem (ea, 32);
> +	}
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    default:
> +UNKNOWN_PREFIX_OP:
> +      gdb_printf (gdb_stdlog,
> +		  "Warning: Don't know how to record prefix instruction
> "
> +		  "%08x %08x at %s, %d.\n",
> +		  insn_prefix, insn_suffix, paddress (gdbarch, addr),
> +		  op6);
> +      return -1;
> +    }
> +
> + SUCCESS:
> +  if (record_full_arch_list_add_reg (regcache, PPC_PC_REGNUM))
> +    return -1;
> +
> +  if (record_full_arch_list_add_end ())
> +    return -1;
> +  return 0;
> +}
> +
>  int
>  ppc_process_record (struct gdbarch *gdbarch, struct regcache
> *regcache,
>  		      CORE_ADDR addr)
>  {
>    ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep
> (gdbarch);
>    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
> -  uint32_t insn;
> +  uint32_t insn, insn_suffix;
>    int op6, tmp, i;
> 
>    insn = read_memory_unsigned_integer (addr, 4, byte_order);
> @@ -5965,16 +7098,28 @@ ppc_process_record (struct gdbarch *gdbarch,
> struct regcache *regcache,
> 
>    switch (op6)
>      {
> +    case 1:		/* prefixed instruction */
> +      {
> +	/* Get the lower 32-bits of the prefixed instruction. */
> +	insn_suffix = read_memory_unsigned_integer (addr+4, 4,
> byte_order);
> +	return ppc_process_prefix_instruction (insn, insn_suffix, addr,
> +					       gdbarch, regcache);
> +      }
>      case 2:		/* Trap Doubleword Immediate */
>      case 3:		/* Trap Word Immediate */
>        /* Do nothing.  */
>        break;
> 
> -    case 4:
> +    case 4:             /* Vector Integer, Compare, Logical, Shift,
> etc.  */
>        if (ppc_process_record_op4 (gdbarch, regcache, addr, insn) !=
> 0)
>  	return -1;
>        break;
> 
> +    case 6:             /* Vector Load and Store */
> +      if (ppc_process_record_op6 (gdbarch, regcache, addr, insn) !=
> 0)
> +	return -1;
> +      break;
> +
>      case 17:		/* System call */
>        if (PPC_LEV (insn) != 0)
>  	goto UNKNOWN_OP;


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/2  Version 5] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-18 19:21             ` [PATCH 1/2 Version 5] " Carl Love
  2022-04-22 19:49               ` [PATCH 1/2 Version 5 Ping] " Carl Love
@ 2022-04-24 16:50               ` Joel Brobecker
  2022-04-25 15:58                 ` [PATCH 1/2 Version 6] " Carl Love
  1 sibling, 1 reply; 25+ messages in thread
From: Joel Brobecker @ 2022-04-24 16:50 UTC (permalink / raw)
  To: Carl Love
  Cc: Joel Brobecker, will schmidt, gdb-patches, Ulrich Weigand,
	Tulio Magno, Rogerio Alves

> On Sun, 2022-04-17 at 09:23 -0700, Joel Brobecker wrote:
> > On Wed, Apr 13, 2022 at 10:26:47AM -0700, Carl Love wrote:
> > 
> > > Add recording support for the ISA 3.1 Powerpc instructions.
> > 
> > Thanks for the updated version. I have a few more requests of
> > a trivial natural (Coding Style, and I apologize if this is a bit
> > frustrating for you - I wish we had a tool like in python that
> > we could use to just automate the whole thing...).
> 
> Yea, it would speed things up.  GCC has a script that runs when you try
> to checkin a patch.  Not sure how much coding style it checks.  It does
> check the change log entries.  It would be nice to have a stand alone
> script that could be run on a patch to check coding style before
> posting or committing a patch.  It would save a lot of time and effort.
> 
> 
> I updated the patch with the typos you mentioned and found an
> additional one as well.  I updated the header comment for
> ppc_record_ACC_fpscr().  I think it is simpler and cleaner now.
> 
> This patch was retested with the updated (version 5) testcases to
> verify the patch is still ok.
> 
>                      Carl 
> 
> -----------------------------------------------------------------
> Add recording support for the ISA 3.1 PowerPC instructions.
> 
> This patch adds support for the PowerPC ISA 3.1 instructions to the PowerPC
> gdb instruction recording routines.  Case statement entries are added to a
> number of the existing routines for recording the 32-bit word instructions.
> A few new functions were added to handle the new word instructions.  The 64-bit
> prefix instructions are all handled by a set of new routines.  The function
> ppc_process_prefix_instruction() is the primary function to handle the
> prefixed instructions. It calls additional functions to handle specific
> sets of prefixed instructions.  These new functions are:
>   ppc_process_record_prefix_vsx_d_form(),
>   ppc_process_record_prefix_store_vsx_ds_form(),
>   ppc_process_record_prefix_op34(),
>   ppc_process_record_prefix_op33(),
>   ppc_process_record_prefix_op32(),
>   ppc_process_record_prefix_store(),
>   ppc_process_record_prefix_op59_XX3(),
>   ppc_process_record_prefix_op42().

Thank you for your patience going through all the iterations.

OK for me to push this patch to master. A couple of additional
remarks below, in the spirit of helping you become more familiar
with the GNU Coding Style and GDB's style as well.

> +/* The ppc_record_ACC_fpscr() records the changes to the VSR registers
> +   modified by a floating point instruction.  The at argument gives which of
> +   the 8 AT entries to record.  The save_fpscr argument is used to indicate
> +   if the FPSCR also needs to be recorded.  The function returns 0 on
> +   success.  */

One thing I wanted to mention is that the GNU Coding Style has a
convention whereby the all-caps spelling of an entity means the
value of that entity. E.g. "FOO" means "the value of foo". We use
that extensitively in GDB. So, you could say, for instance:

    AT provides which of the 8 AT entries to record.
    SAVE_FPSCR should be set to true if the FPSCR also needs to be
    recorded, false otherwise.

And FWIW, I have a comment which is a bit on the nit-picking side, but
said in the spirit of trying to raise awareness rather than a change
request, so I'll let you decide what to do with it:

    For me, "which of the 8 AT entries to record" is slightly
    confusing, because it leaves me wondering what kind of value
    this should be given. I mean, could multiple AT entries be
    recorded, and not just one, in which case I suppose AT would
    be some kind of mask. Or does the function only ever record
    one AT entry, in which case AT is the corresponding number?

If you do decide to act on it, I invite you to do so as a separate
commit, just so we don't delay this commit further for something
so minor, especially after the patch having gone through several
iterations already.

> +
> +#define RECORD_FPSCR 1
> +#define DO_NOT_RECORD_FPSCR 0
> +
> +static int
> +ppc_record_ACC_fpscr (struct regcache *regcache, ppc_gdbarch_tdep *tdep,
> +		      int at, int save_fpscr)

Given the description, I suspect that a better type for save_fpscr would
be bool. If you agree, you can address that as a separate patch, for
the same kind of reason as explained above.

> +{
> +  int i;
> +  if (at < 0 || at >= 8)
> +    return -1;
> +
> +  /* The ACC register file consists of 8 register entries, each register
> +     entry consist of four 128-bit rows.
> +
> +     The ACC rows map to specific VSR registers.
> +         ACC[0][0] -> VSR[0]
> +         ACC[0][1] -> VSR[1]
> +         ACC[0][2] -> VSR[2]
> +         ACC[0][3] -> VSR[3]
> +              ...
> +         ACC[7][0] -> VSR[28]
> +         ACC[7][1] -> VSR[29]
> +         ACC[7][2] -> VSR[30]
> +         ACC[7][3] -> VSR[31]
> +
> +     NOTE:
> +     In ISA 3.1 the ACC is mapped on top of VSR[0] thru VSR[31].
> +
> +     In the future, the ACC may be implemented as an independent register file
> +     rather than mapping on top of the VSRs.  This will then require the ACC to
> +     be assigned its own register number and the ptrace interface to be able
> +     access the ACC.  Note the ptrace interface for the ACC will also need to
> +     be implemented.  */
> +
> +  /* ACC maps over the same VSR space as the fp registers.  */
> +  for (i = 0; i < 4; i++)
> +    {
> +      record_full_arch_list_add_reg (regcache, tdep->ppc_fp0_regnum
> +				     + at * 4 + i);
> +      record_full_arch_list_add_reg (regcache,
> +				     tdep->ppc_vsr0_upper_regnum + at * 4 + i);
> +    }
> +
> +  if (save_fpscr)
> +    record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
> +
> +  return 0;
> +}
> +
>  /* Parse and record instructions primary opcode-4 at ADDR.
>     Return 0 if successful.  */
>  
> @@ -4171,9 +4243,34 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 41:		/* Vector Multiply-Sum Signed Halfword Saturate */
>        record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
>        /* FALL-THROUGH */
> +    case 20:		/* Move To VSR Byte Mask Immediate opcode, b2 = 0,
> +			   ignore bit 31 */
> +    case 21:		/* Move To VSR Byte Mask Immediate opcode, b2 = 1,
> +			   ignore bit 31 */
> +    case 23:		/* Vector Multiply-Sum & write Carry-out Unsigned
> +			   Doubleword */
> +    case 24:		/* Vector Extract Double Unsigned Byte to VSR
> +			   using GPR-specified Left-Index */
> +    case 25:		/* Vector Extract Double Unsigned Byte to VSR
> +			   using GPR-specified Right-Index */
> +    case 26:		/* Vector Extract Double Unsigned Halfword to VSR
> +			   using GPR-specified Left-Index */
> +    case 27:		/* Vector Extract Double Unsigned Halfword to VSR
> +			   using GPR-specified Right-Index */
> +    case 28:		/* Vector Extract Double Unsigned Word to VSR
> +			   using GPR-specified Left-Index */
> +    case 29:		/* Vector Extract Double Unsigned Word to VSR
> +			   using GPR-specified Right-Index */
> +    case 30:		/* Vector Extract Double Unsigned Doubleword to VSR
> +			   using GPR-specified Left-Index */
> +    case 31:		/* Vector Extract Double Unsigned Doubleword to VSR
> +			   using GPR-specified Right-Index */
>      case 42:		/* Vector Select */
>      case 43:		/* Vector Permute */
>      case 59:		/* Vector Permute Right-indexed */
> +    case 22: 		/* Vector Shift
> +			      Left  Double by Bit Immediate if insn[21] = 0
> +			      Right Double by Bit Immediate if insn[21] = 1 */
>      case 44:		/* Vector Shift Left Double by Octet Immediate */
>      case 45:		/* Vector Permute and Exclusive-OR */
>      case 60:		/* Vector Add Extended Unsigned Quadword Modulo */
> @@ -4236,6 +4333,9 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>    /* Bit-21 is used for RC */
>    switch (ext & 0x3ff)
>      {
> +    case 5:		/* Vector Rotate Left Quadword */
> +    case 69:		/* Vector Rotate Left Quadword then Mask Insert */
> +    case 325:		/* Vector Rotate Left Quadword then AND with Mask */
>      case 6:		/* Vector Compare Equal To Unsigned Byte */
>      case 70:		/* Vector Compare Equal To Unsigned Halfword */
>      case 134:		/* Vector Compare Equal To Unsigned Word */
> @@ -4244,13 +4344,16 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      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 903:		/* Vector Compare Greater Than Signed Quadword */
>      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 647:		/* Vector Compare Greater Than Unsigned Quadword */
>      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 455:		/* Vector Compare Equal Quadword */
>      case 710:		/* Vector Compare Greater Than Single-Precision */
>      case 7:		/* Vector Compare Not Equal Byte */
>      case 71:		/* Vector Compare Not Equal Halfword */
> @@ -4263,6 +4366,21 @@ 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 13:
> +      switch (vra)    /* Bit-21 is used for RC */
> +	{
> +	case 0:       /* Vector String Isolate Byte Left-justified */
> +	case 1:       /* Vector String Isolate Byte Right-justified */
> +	case 2:       /* Vector String Isolate Halfword Left-justified */
> +	case 3:       /* Vector String Isolate Halfword Right-justified */
> +	  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;
> +	}
>      }
>  
>    if (ext  == 1538)
> @@ -4287,6 +4405,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>  	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 27:	/* Vector Extend Sign Doubleword To Quadword */
>  	case 28:	/* Vector Count Trailing Zeros Byte */
>  	case 29:	/* Vector Count Trailing Zeros Halfword */
>  	case 30:	/* Vector Count Trailing Zeros Word */
> @@ -4297,8 +4416,57 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>  	}
>      }
>  
> +  if (ext == 1602)
> +    {
> +      switch (vra)
> +	{
> +	case 0: 	/* Vector Expand Byte Mask */
> +	case 1: 	/* Vector Expand Halfword Mask */
> +	case 2: 	/* Vector Expand Word Mask */
> +	case 3: 	/* Vector Expand Doubleword Mask */
> +	case 4: 	/* Vector Expand Quadword Mask */
> +	case 16:	/* Move to VSR Byte Mask */
> +	case 17:	/* Move to VSR Halfword Mask */
> +	case 18:	/* Move to VSR Word Mask */
> +	case 19:	/* Move to VSR Doubleword Mask */
> +	case 20:	/* Move to VSR Quadword Mask */
> +	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
> +	  return 0;
> +
> +	case 8: 	/* Vector Extract Byte Mask */
> +	case 9: 	/* Vector Extract Halfword Mask */
> +	case 10: 	/* Vector Extract Word Mask */
> +	case 11: 	/* Vector Extract Doubleword Mask */
> +	case 12: 	/* Vector Extract Quadword Mask */
> +
> +	/* Ignore the MP bit in the LSB position of the vra value. */
> +	case 24:	/* Vector Count Mask Bits Byte, MP = 0 */
> +	case 25:	/* Vector Count Mask Bits Byte, MP = 1 */
> +	case 26:	/* Vector Count Mask Bits Halfword, MP = 0 */
> +	case 27:	/* Vector Count Mask Bits Halfword, MP = 1 */
> +	case 28:	/* Vector Count Mask Bits Word, MP = 0 */
> +	case 29:	/* Vector Count Mask Bits Word, MP = 1 */
> +	case 30:	/* Vector Count Mask Bits Doubleword, MP = 0 */
> +	case 31:	/* Vector Count Mask Bits Doubleword, MP = 1 */
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_gp0_regnum + PPC_RT (insn));
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_gp0_regnum + PPC_RT (insn));
> +	  return 0;
> +	}
> +    }
> +
>    switch (ext)
>      {
> +
> +    case 257:		/* Vector Compare Unsigned Quadword */
> +    case 321:		/* Vector Compare Signed Quadword */
> +      /* Comparison tests that always set CR field BF */
> +      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;
> +
>      case 142:		/* Vector Pack Unsigned Halfword Unsigned Saturate */
>      case 206:		/* Vector Pack Unsigned Word Unsigned Saturate */
>      case 270:		/* Vector Pack Signed Halfword Unsigned Saturate */
> @@ -4338,6 +4506,8 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 268:		/* Vector Merge Low Byte */
>      case 332:		/* Vector Merge Low Halfword */
>      case 396:		/* Vector Merge Low Word */
> +    case 397:		/* Vector Clear Leftmost Bytes */
> +    case 461:		/* Vector Clear Rightmost Bytes */
>      case 526:		/* Vector Unpack High Signed Byte */
>      case 590:		/* Vector Unpack High Signed Halfword */
>      case 654:		/* Vector Unpack Low Signed Byte */
> @@ -4356,8 +4526,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 780:		/* Vector Splat Immediate Signed Byte */
>      case 844:		/* Vector Splat Immediate Signed Halfword */
>      case 908:		/* Vector Splat Immediate Signed Word */
> +    case 261:		/* Vector Shift Left Quadword */
>      case 452:		/* Vector Shift Left */
> +    case 517:		/* Vector Shift Right Quadword */
>      case 708:		/* Vector Shift Right */
> +    case 773:		/* Vector Shift Right Algebraic Quadword */
>      case 1036:		/* Vector Shift Left by Octet */
>      case 1100:		/* Vector Shift Right by Octet */
>      case 0:		/* Vector Add Unsigned Byte Modulo */
> @@ -4370,15 +4543,43 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 8:		/* Vector Multiply Odd Unsigned Byte */
>      case 72:		/* Vector Multiply Odd Unsigned Halfword */
>      case 136:		/* Vector Multiply Odd Unsigned Word */
> +    case 200:		/* Vector Multiply Odd Unsigned Doubleword */
>      case 264:		/* Vector Multiply Odd Signed Byte */
>      case 328:		/* Vector Multiply Odd Signed Halfword */
>      case 392:		/* Vector Multiply Odd Signed Word */
> +    case 456:		/* Vector Multiply Odd Signed Doubleword */
>      case 520:		/* Vector Multiply Even Unsigned Byte */
>      case 584:		/* Vector Multiply Even Unsigned Halfword */
>      case 648:		/* Vector Multiply Even Unsigned Word */
> +    case 712:		/* Vector Multiply Even Unsigned Doubleword */
>      case 776:		/* Vector Multiply Even Signed Byte */
>      case 840:		/* Vector Multiply Even Signed Halfword */
>      case 904:		/* Vector Multiply Even Signed Word */
> +    case 968:		/* Vector Multiply Even Signed Doubleword */
> +    case 457:		/* Vector Multiply Low Doubleword */
> +    case 649:		/* Vector Multiply High Unsigned Word */
> +    case 713:		/* Vector Multiply High Unsigned Doubleword */
> +    case 905:		/* Vector Multiply High Signed Word */
> +    case 969:		/* Vector Multiply High Signed Doubleword */
> +    case 11:		/* Vector Divide Unsigned Quadword */
> +    case 203:		/* Vector Divide Unsigned Doubleword */
> +    case 139:		/* Vector Divide Unsigned Word */
> +    case 267:		/* Vector Divide Signed Quadword */
> +    case 459:		/* Vector Divide Signed Doubleword */
> +    case 395:		/* Vector Divide Signed Word */
> +    case 523:		/* Vector Divide Extended Unsigned Quadword */
> +    case 715:		/* Vector Divide Extended Unsigned Doubleword */
> +    case 651:		/* Vector Divide Extended Unsigned Word */
> +    case 779:		/* Vector Divide Extended Signed Quadword */
> +    case 971:		/* Vector Divide Extended Signed Doubleword */
> +    case 907:		/* Vector Divide Extended Unsigned Word */
> +    case 1547:		/* Vector Modulo Unsigned Quadword */
> +    case 1675:		/* Vector Modulo Unsigned Word */
> +    case 1739:		/* Vector Modulo Unsigned Doubleword */
> +    case 1803:		/* Vector Modulo Signed Quadword */
> +    case 1931:		/* Vector Modulo Signed Word */
> +    case 1995:		/* Vector Modulo Signed Doubleword */
> +
>      case 137:		/* Vector Multiply Unsigned Word Modulo */
>      case 1024:		/* Vector Subtract Unsigned Byte Modulo */
>      case 1088:		/* Vector Subtract Unsigned Halfword Modulo */
> @@ -4462,7 +4663,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 1794:		/* Vector Count Leading Zeros Byte */
>      case 1858:		/* Vector Count Leading Zeros Halfword */
>      case 1922:		/* Vector Count Leading Zeros Word */
> +    case 1924:		/* Vector Count Leading Zeros Doubleword under
> +			   bit Mask*/
>      case 1986:		/* Vector Count Leading Zeros Doubleword */
> +    case 1988:		/* Vector Count Trailing Zeros Doubleword under bit
> +			   Mask */
>      case 1795:		/* Vector Population Count Byte */
>      case 1859:		/* Vector Population Count Halfword */
>      case 1923:		/* Vector Population Count Word */
> @@ -4488,14 +4693,50 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 589:		/* Vector Extract Unsigned Halfword */
>      case 653:		/* Vector Extract Unsigned Word */
>      case 717:		/* Vector Extract Doubleword */
> +    case 15:		/* Vector Insert Byte from VSR using GPR-specified
> +			   Left-Index */
> +    case 79:		/* Vector Insert Halfword from VSR using GPR-specified
> +			   Left-Index */
> +    case 143:		/* Vector Insert Word from VSR using GPR-specified
> +			   Left-Index */
> +    case 207:		/* Vector Insert Word from GPR using
> +			   immediate-specified index */
> +    case 463:		/* Vector Insert Doubleword from GPR using
> +			   immediate-specified index */
> +    case 271:		/* Vector Insert Byte from VSR using GPR-specified
> +			   Right-Index */
> +    case 335:		/* Vector Insert Halfword from VSR using GPR-specified
> +			   Right-Index */
> +    case 399:		/* Vector Insert Word from VSR using GPR-specified
> +			   Right-Index */
> +    case 527:		/* Vector Insert Byte from GPR using GPR-specified
> +			   Left-Index */
> +    case 591:		/* Vector Insert Halfword from GPR using GPR-specified
> +			   Left-Index */
> +    case 655:		/* Vector Insert Word from GPR using GPR-specified
> +			   Left-Index */
> +    case 719:		/* Vector Insert Doubleword from GPR using
> +			    GPR-specified Left-Index */
> +    case 783:		/* Vector Insert Byte from GPR using GPR-specified
> +			   Right-Index */
> +    case 847:		/* Vector Insert Halfword from GPR using GPR-specified
> +			   Left-Index */
> +    case 911:		/* Vector Insert Word from GPR using GPR-specified
> +			   Left-Index */
> +    case 975:		/* Vector Insert Doubleword from GPR using
> +			    GPR-specified Right-Index */
>      case 781:		/* Vector Insert Byte */
>      case 845:		/* Vector Insert Halfword */
>      case 909:		/* Vector Insert Word */
>      case 973:		/* Vector Insert Doubleword */
> +    case 1357:		/* Vector Centrifuge Doubleword */
> +    case 1421:		/* Vector Parallel Bits Extract Doubleword */
> +    case 1485:		/* Vector Parallel Bits Deposit Doubleword */
>        record_full_arch_list_add_reg (regcache,
>  				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
>        return 0;
>  
> +    case 1228:		/* Vector Gather every Nth Bit */
>      case 1549:		/* Vector Extract Unsigned Byte Left-Indexed */
>      case 1613:		/* Vector Extract Unsigned Halfword Left-Indexed */
>      case 1677:		/* Vector Extract Unsigned Word Left-Indexed */
> @@ -4525,6 +4766,34 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
>    return -1;
>  }
>  
> +/* Parse and record instructions of primary opcode 6 at ADDR.
> +   Return 0 if successful.  */
> +
> +static int
> +ppc_process_record_op6 (struct gdbarch *gdbarch, struct regcache *regcache,
> +			CORE_ADDR addr, uint32_t insn)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  int subtype = PPC_FIELD (insn, 28, 4);
> +  CORE_ADDR ea = 0;
> +
> +  switch (subtype)
> +    {
> +    case 0:    /* Load VSX Vector Paired */
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
> +      return 0;
> +    case 1:    /* Store VSX Vector Paired */
> +      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, 32);
> +      return 0;
> +    }
> +  return -1;
> +}
> +
>  /* Parse and record instructions of primary opcode-19 at ADDR.
>     Return 0 if successful.  */
>  
> @@ -4577,6 +4846,30 @@ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
>    return -1;
>  }
>  
> +/* Parse and record instructions of primary opcode-31 with the extended opcode
> +   177.  The argument is the word instruction (insn).  Return 0 if successful.
> +*/
> +
> +static int
> +ppc_process_record_op31_177 (struct gdbarch *gdbarch,
> +			     struct regcache *regcache,
> +			     uint32_t insn)
> +{
> +  int RA_opcode = PPC_RA(insn);
> +  int as = PPC_FIELD (insn, 6, 3);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  switch (RA_opcode)
> +    {
> +    case 0: 		/* VSX Move From Accumulator, xxmfacc */
> +    case 1: 		/* VSX Move To Accumulator, xxmtacc */
> +    case 3: 		/* VSX Set Accumulator to Zero, xxsetaccz */
> +      ppc_record_ACC_fpscr (regcache, tdep, as, DO_NOT_RECORD_FPSCR);
> +      return 0;
> +    }
> +  return -1;
> +}
> +
>  /* Parse and record instructions of primary opcode-31 at ADDR.
>     Return 0 if successful.  */
>  
> @@ -4586,7 +4879,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>  {
>    ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
>    int ext = PPC_EXTOP (insn);
> -  int tmp, nr, nb, i;
> +  int tmp, nr, nb = 0, i;
>    CORE_ADDR at_dcsz, ea = 0;
>    ULONGEST rb, ra, xer;
>    int size = 0;
> @@ -4677,6 +4970,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 371:		/* Move From Time Base [Phased-Out]  */
>      case 309:		/* Load Doubleword Monitored Indexed  */
>      case 128:		/* Set Boolean */
> +    case 384:		/* Set Boolean Condition */
> +    case 416:		/* Set Boolean Condition Reverse */
> +    case 448:		/* Set Negative Boolean Condition */
> +    case 480:		/* Set Negative Boolean Condition Reverse */
>      case 755:		/* Deliver A Random Number */
>        record_full_arch_list_add_reg (regcache,
>  				     tdep->ppc_gp0_regnum + PPC_RT (insn));
> @@ -4684,8 +4981,15 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>  
>      /* These only write to RA.  */
>      case 51:		/* Move From VSR Doubleword */
> +    case 59:		/* Count Leading Zeros Doubleword under bit Mask */
>      case 115:		/* Move From VSR Word and Zero */
>      case 122:		/* Population count bytes */
> +    case 155:		/* Byte-Reverse Word */
> +    case 156:		/* Parallel Bits Deposit Doubleword */
> +    case 187:		/* Byte-Reverse Doubleword */
> +    case 188:		/* Parallel Bits Extract Doubleword */
> +    case 219:		/* Byte-Reverse Halfword */
> +    case 220:		/* Centrifuge Doubleword */
>      case 378:		/* Population count words */
>      case 506:		/* Population count doublewords */
>      case 154:		/* Parity Word */
> @@ -4695,6 +4999,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 314:		/* Convert Binary Coded Decimal To Declets */
>      case 508:		/* Compare bytes */
>      case 307:		/* Move From VSR Lower Doubleword */
> +    case 571:		/* Count Trailing Zeros Doubleword under bit Mask */
>        record_full_arch_list_add_reg (regcache,
>  				     tdep->ppc_gp0_regnum + PPC_RA (insn));
>        return 0;
> @@ -4819,6 +5124,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>        record_full_arch_list_add_reg (regcache, tmp + 1);
>        return 0;
>  
> +    /* These write to destination register PPC_XT. */
>      case 179:		/* Move To VSR Doubleword */
>      case 211:		/* Move To VSR Word Algebraic */
>      case 243:		/* Move To VSR Word and Zero */
> @@ -4826,6 +5132,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>      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 13:		/* Load VSX Vector Rightmost Byte Indexed */
> +    case 45:		/* Load VSX Vector Rightmost Halfword Indexed */
> +    case 77:		/* Load VSX Vector Rightmost Word Indexed */
> +    case 109:		/* Load VSX Vector Rightmost Doubleword 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 */
> @@ -4842,6 +5152,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>        ppc_record_vsr (regcache, tdep, PPC_XT (insn));
>        return 0;
>  
> +    case 333:		/* Load VSX Vector Paired Indexed */
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
> +      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
> +      return 0;
> +
>      /* These write RA.  Update CR if RC is set.  */
>      case 24:		/* Shift Left Word */
>      case 26:		/* Count Leading Zeros Word */
> @@ -5006,6 +5321,31 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>        record_full_arch_list_add_mem (ea, size);
>        return 0;
>  
> +    case 141:		/* Store VSX Vector Rightmost Byte Indexed */
> +    case 173:		/* Store VSX Vector Rightmost Halfword Indexed */
> +    case 205:		/* Store VSX Vector Rightmost Word Indexed */
> +    case 237:		/* Store VSX Vector Rightmost Doubleword Indexed */
> +      switch(ext)
> +	{
> +	  case 141: nb = 1;
> +	  break;
> +	  case 173: nb = 2;
> +	  break;
> +	  case 205: nb = 4;
> +	  break;
> +	  case 237: nb = 8;
> +	  break;
> +	}
> +      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;
> +      record_full_arch_list_add_mem (ea, nb);
> +      return 0;
> +
>      case 397:		/* Store VSX Vector with Length */
>      case 429:		/* Store VSX Vector Left-justified with Length */
>        ra = 0;
> @@ -5021,6 +5361,19 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>  	record_full_arch_list_add_mem (ea, nb);
>        return 0;
>  
> +    case 461:		/* Store VSX Vector Paired Indexed */
> +      {
> +	if (PPC_RA (insn) != 0)
> +	  regcache_raw_read_unsigned (regcache,
> +				      tdep->ppc_gp0_regnum
> +				      + PPC_RA (insn), &ea);
> +	regcache_raw_read_unsigned (regcache,
> +				    tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
> +	ea += rb;
> +	record_full_arch_list_add_mem (ea, 32);
> +	return 0;
> +      }
> +
>      case 710:		/* Store Word Atomic */
>      case 742:		/* Store Doubleword Atomic */
>        ra = 0;
> @@ -5166,6 +5519,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>        ea = (ra + rb) & ~((ULONGEST) (at_dcsz - 1));
>        record_full_arch_list_add_mem (ea, at_dcsz);
>        return 0;
> +
> +    case 177:
> +      if (ppc_process_record_op31_177 (gdbarch, regcache, insn) == 0)
> +	return 0;
>      }
>  
>  UNKNOWN_OP:
> @@ -5179,10 +5536,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
>  
>  static int
>  ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
> -			   CORE_ADDR addr, uint32_t insn)
> +			 CORE_ADDR addr, uint32_t insn)
>  {
>    ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
>    int ext = PPC_EXTOP (insn);
> +  int at = PPC_FIELD (insn, 6, 3);
>  
>    switch (ext & 0x1f)
>      {
> @@ -5206,6 +5564,75 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
>        return 0;
>      }
>  
> +  /* MMA instructions, keep looking.  */
> +  switch (ext >> 2)    /* Additional opcode field is upper 8-bits of ext */
> +    {
> +    case 3:	/* VSX Vector 8-bit Signed/Unsigned Integer GER, xvi8ger4 */
> +    case 2:	/* VSX Vector 8-bit Signed/Unsigned Integer GER Positive
> +		   multiply, Positive accumulate, xvi8ger4pp */
> +
> +    case 99:	/* VSX Vector 8-bit Signed/Unsigned Integer GER with
> +		   Saturate Positive multiply, Positive accumulate,
> +		   xvi8ger4spp */
> +
> +    case 35:	/* VSX Vector 4-bit Signed Integer GER, xvi4ger8 */
> +    case 34:	/* VSX Vector 4-bit Signed Integer GER Positive multiply,
> +		   Positive accumulate, xvi4ger8pp */
> +
> +    case 75:	/* VSX Vector 16-bit Signed Integer GER, xvi16ger2 */
> +    case 107:	/* VSX Vector 16-bit Signed Integer GER  Positive multiply,
> +		   Positive accumulate, xvi16ger2pp */
> +
> +    case 43:	/* VSX Vector 16-bit Signed Integer GER with Saturation,
> +		   xvi16ger2s */
> +    case 42:	/* VSX Vector 16-bit Signed Integer GER with Saturation
> +		   Positive multiply, Positive accumulate, xvi16ger2spp */
> +      ppc_record_ACC_fpscr (regcache, tdep, at, DO_NOT_RECORD_FPSCR);
> +      return 0;
> +
> +    case 19:	/* VSX Vector 16-bit Floating-Point GER, xvf16ger2 */
> +    case 18:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
> +		   Positive accumulate, xvf16ger2pp */
> +    case 146:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
> +		   Negative accumulate, xvf16ger2pn */
> +    case 82:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
> +		   Positive accumulate, xvf16ger2np */
> +    case 210:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
> +		   Negative accumulate, xvf16ger2nn */
> +
> +    case 27:	/* VSX Vector 32-bit Floating-Point GER, xvf32ger */
> +    case 26:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
> +		   Positive accumulate, xvf32gerpp */
> +    case 154:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
> +		   Negative accumulate, xvf32gerpn */
> +    case 90:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
> +		   Positive accumulate, xvf32gernp */
> +    case 218:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
> +		   Negative accumulate, xvf32gernn */
> +
> +    case 59:	/* VSX Vector 64-bit Floating-Point GER, pmxvf64ger */
> +    case 58:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
> +		   Positive accumulate, xvf64gerpp */
> +    case 186:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
> +		   Negative accumulate, xvf64gerpn */
> +    case 122:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
> +		   Positive accumulate, xvf64gernp */
> +    case 250:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
> +		   Negative accumulate, pmxvf64gernn */
> +
> +    case 51:	/* VSX Vector bfloat16 GER, xvbf16ger2 */
> +    case 50:	/* VSX Vector bfloat16 GER Positive multiply,
> +		   Positive accumulate, xvbf16ger2pp */
> +    case 178:	/* VSX Vector bfloat16 GER Positive multiply,
> +		   Negative accumulate, xvbf16ger2pn */
> +    case 114:	/* VSX Vector bfloat16 GER Negative multiply,
> +		   Positive accumulate, xvbf16ger2np */
> +    case 242:	/* VSX Vector bfloat16 GER Negative multiply,
> +		   Negative accumulate, xvbf16ger2nn */
> +      ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
> +      return 0;
> +    }
> +
>    switch (ext)
>      {
>      case 2:		/* DFP Add */
> @@ -5268,6 +5695,48 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
>    return -1;
>  }
>  
> +/* Parse and record an XX2-Form instruction with opcode 60 at ADDR.  The
> +   word instruction is an argument insn.  Return 0 if successful.  */
> +
> +static int
> +ppc_process_record_op60_XX2 (struct gdbarch *gdbarch,
> +			     struct regcache *regcache,
> +			     CORE_ADDR addr, uint32_t insn)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  int RA_opcode = PPC_RA(insn);
> +
> +  switch (RA_opcode)
> +    {
> +    case 2:	/* VSX Vector Test Least-Significant Bit by Byte */
> +    case 25:	/* VSX Vector round and Convert Single-Precision format
> +		   to Half-Precision format.  Only changes the CR
> +		   field.  */
> +      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
> +      return 0;
> +    case 17:	/* VSX Vector Convert with round Single-Precision
> +		   to bfloat16 format */
> +    case 24:	/* VSX Vector Convert Half-Precision format to
> +		   Single-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 16:	/* VSX Vector Convert bfloat16 to Single-Precision
> +		   format Non-signaling */
> +    case 23:	/* VSX Vector Byte-Reverse Doubleword */
> +    case 31:	/* VSX Vector Byte-Reverse Quadword */
> +      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
> +      return 0;
> +    }
> +
> +  return -1;
> +}
> +
>  /* Parse and record instructions of primary opcode-60 at ADDR.
>     Return 0 if successful.  */
>  
> @@ -5583,37 +6052,30 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
>        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;
> +      if (ppc_process_record_op60_XX2 (gdbarch, regcache, addr, insn) != 0)
> +	return -1;
> +      return 0;
>      }
>  
>    switch (ext)
>      {
> -    case 360:		/* VSX Vector Splat Immediate Byte */
> -      if (PPC_FIELD (insn, 11, 2) == 0)
> +    case 360:
> +      if (PPC_FIELD (insn, 11, 2) == 0)  /* VSX Vector Splat Immediate Byte */
> +	{
> +	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
> +	  return 0;
> +	}
> +      if (PPC_FIELD (insn, 11, 5) == 31)  /* Load VSX Vector Special Value
> +					     Quadword */
>  	{
>  	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
>  	  return 0;
>  	}
>        break;
> +    case 916:		/* VSX Vector Generate PCV from Byte Mask */
> +    case 917:		/* VSX Vector Generate PCV from Halfword Mask */
> +    case 948:		/* VSX Vector Generate PCV from Word Mask */
> +    case 949:		/* VSX Vector Generate PCV from Doubleword Mask */
>      case 918:		/* VSX Scalar Insert Exponent Double-Precision */
>        ppc_record_vsr (regcache, tdep, PPC_XT (insn));
>        return 0;
> @@ -5894,6 +6356,35 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
>  			   Quad-Precision */
>      case 516:		/* VSX Scalar Subtract Quad-Precision */
>      case 548:		/* VSX Scalar Divide Quad-Precision */
> +    case 994:
> +      {
> +      switch (PPC_FIELD (insn, 11, 5))
> +	{
> +	case 0:	/* DFP Convert From Fixed Quadword Quad */
> +	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
> +
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_fp0_regnum
> +					 + PPC_FRT (insn));
> +	  record_full_arch_list_add_reg (regcache,
> +					 tdep->ppc_fp0_regnum
> +					 + PPC_FRT (insn) + 1);
> +	  return 0;
> +	case 1:	/* DFP Convert To Fixed Quadword Quad */
> +	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
> +	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
> +	  return 0;
> +	}
> +      }
> +
> +      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
> +      /* FALL-THROUGH */
> +    case 68:		/* VSX Scalar Compare Equal Quad-Precision */
> +    case 196:		/* VSX Scalar Compare Greater Than or Equal
> +			   Quad-Precision */
> +    case 228:		/* VSX Scalar Compare Greater Than Quad-Precision */
> +    case 676:		/* VSX Scalar Maximum Type-C Quad-Precision */
> +    case 740:		/* VSX Scalar Minimum Type-C Quad-Precision */
>        record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
>        /* FALL-THROUGH */
>      case 100:		/* VSX Scalar Copy Sign Quad-Precision */
> @@ -5920,14 +6411,22 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
>      case 836:
>        switch (PPC_FIELD (insn, 11, 5))
>  	{
> +	case 0:		/* VSX Scalar Convert with round to zero
> +			   Quad-Precision to Unsigned Quadword  */
>  	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 3:		/* VSX Scalar Convert with round
> +			   Unsigned Quadword to Quad-Precision  */
> +	case 8:		/* VSX Scalar Convert with round to zero
> +			   Quad-Precision to Signed Quadword  */
>  	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 11:	/* VSX Scalar Convert with round
> +			   Signed Quadword to Quad-Precision */
>  	case 17:	/* VSX Scalar truncate & Convert Quad-Precision format
>  			   to Unsigned Doubleword format */
>  	case 20:	/* VSX Scalar round & Convert Quad-Precision format to
> @@ -5947,17 +6446,651 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
>    return -1;
>  }
>  
> +/* Record the prefixed instructions with primary opcode 32.  The arguments are
> +   the first 32-bits of the instruction (insn_prefix), and the second 32-bits
> +   of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_op42 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +
> +  if (ST1 != 0)
> +    return -1;
> +
> +  switch (type)
> +    {
> +    case 0:  /* Prefixed Load VSX Scalar Doubleword, plxsd */
> +      ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
> +      break;
> +    case 2:  /* Prefixed Load Halfword Algebraic, plha */
> +      record_full_arch_list_add_reg (regcache,
> +				     tdep->ppc_gp0_regnum
> +				     + PPC_RT (insn_suffix));
> +      break;
> +    default:
> +      return -1;
> +    }
> +  return 0;
> +}
> +
> +/* Record the prefixed XX3-Form instructions with primary opcode 59.  The
> +   arguments are the first 32-bits of the instruction (insn_prefix), and the
> +   second 32-bits of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_op59_XX3 (struct gdbarch *gdbarch,
> +				    struct regcache *regcache,
> +				    uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  int opcode = PPC_FIELD (insn_suffix, 21, 8);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  int at = PPC_FIELD (insn_suffix, 6, 3);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  if (type == 3)
> +    {
> +      if (ST4 == 9)
> +	switch (opcode)
> +	  {
> +	  case 35:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
> +			   MMIRR, pmxvi4ger8 */
> +	  case 34:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
> +			   MMIRR, pmxvi4ger8pp */
> +
> +	  case 99:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
> +			   Integer GER with Saturate Positive multiply,
> +			   Positive accumulate, xvi8ger4spp */
> +
> +	  case 3:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
> +			   Integer GER MMIRR, pmxvi8ger4 */
> +	  case 2:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
> +			   Integer GER Positive multiply, Positive accumulate
> +			   MMIRR, pmxvi8ger4pp */
> +
> +	  case 75:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
> +			   GER MMIRR, pmxvi16ger2 */
> +	  case 107:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
> +			   GER  Positive multiply, Positive accumulate,
> +			   pmxvi16ger2pp */
> +
> +	  case 43:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
> +			   GER with Saturation MMIRR, pmxvi16ger2s */
> +	  case 42:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
> +			   GER with Saturation Positive multiply, Positive
> +			   accumulate MMIRR, pmxvi16ger2spp */
> +	    ppc_record_ACC_fpscr (regcache, tdep, at, DO_NOT_RECORD_FPSCR);
> +	    return 0;
> +
> +	  case 19:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER MMIRR, pmxvf16ger2 */
> +	  case 18:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER Positive multiply, Positive accumulate MMIRR,
> +			   pmxvf16ger2pp */
> +	  case 146:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER Positive multiply, Negative accumulate MMIRR,
> +			   pmxvf16ger2pn */
> +	  case 82:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER Negative multiply, Positive accumulate MMIRR,
> +			   pmxvf16ger2np */
> +	  case 210:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
> +			   GER Negative multiply, Negative accumulate MMIRR,
> +			   pmxvf16ger2nn */
> +
> +	  case 27:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER MMIRR, pmxvf32ger */
> +	  case 26:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER Positive multiply, Positive accumulate MMIRR,
> +			   pmxvf32gerpp */
> +	  case 154:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER Positive multiply, Negative accumulate MMIRR,
> +			   pmxvf32gerpn */
> +	  case 90:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER Negative multiply, Positive accumulate MMIRR,
> +			   pmxvf32gernp */
> +	  case 218:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
> +			   GER Negative multiply, Negative accumulate MMIRR,
> +			   pmxvf32gernn */
> +
> +	  case 59:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
> +			   GER MMIRR, pmxvf64ger */
> +	  case 58:	/* Floating-Point GER Positive multiply, Positive
> +			   accumulate MMIRR, pmxvf64gerpp */
> +	  case 186:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
> +			   GER Positive multiply, Negative accumulate MMIRR,
> +			   pmxvf64gerpn */
> +	  case 122:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
> +			   GER Negative multiply, Positive accumulate MMIRR,
> +			   pmxvf64gernp */
> +	  case 250:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
> +			   GER Negative multiply, Negative accumulate MMIRR,
> +			   pmxvf64gernn */
> +
> +	  case 51:	/* Prefixed Masked VSX Vector bfloat16 GER MMIRR,
> +			   pmxvbf16ger2 */
> +	  case 50:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
> +			   multiply, Positive accumulate MMIRR,
> +			   pmxvbf16ger2pp */
> +	  case 178:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
> +			   multiply, Negative accumulate MMIRR,
> +			   pmxvbf16ger2pn */
> +	  case 114:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
> +			   multiply, Positive accumulate MMIRR,
> +			   pmxvbf16ger2np */
> +	  case 242:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
> +			   multiply, Negative accumulate MMIRR,
> +			   pmxvbf16ger2nn */
> +	    ppc_record_ACC_fpscr (regcache, tdep, at, RECORD_FPSCR);
> +	    return 0;
> +	  }
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed store instructions.  The arguments are the instruction
> +   address, the first 32-bits of the instruction(insn_prefix) and the following
> +   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_store (struct gdbarch *gdbarch,
> +				 struct regcache *regcache,
> +				 CORE_ADDR addr, uint32_t insn_prefix,
> +				 uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  ULONGEST iaddr = 0;
> +  int size;
> +  int R = PPC_BIT (insn_prefix, 11);
> +  int op6 = PPC_OP6 (insn_suffix);
> +
> +  if (R == 0)
> +    {
> +      if (PPC_RA (insn_suffix) != 0)
> +	regcache_raw_read_unsigned (regcache, tdep->ppc_gp0_regnum
> +				    + PPC_RA (insn_suffix), &iaddr);
> +    }
> +  else
> +    {
> +      iaddr = addr;     /* PC relative */
> +    }
> +
> +  switch (op6)
> +    {
> +    case 38:
> +      size =  1;    /* store byte, pstb */
> +      break;
> +    case 44:
> +      size =  2;    /* store halfword, psth */
> +      break;
> +    case 36:
> +    case 52:
> +      size =  4;    /* store word, pstw, pstfs */
> +      break;
> +    case 54:
> +    case 61:
> +      size =  8;    /* store double word, pstd, pstfd */
> +      break;
> +    case 60:
> +      size = 16;    /* store quadword, pstq */
> +      break;
> +    default: return -1;
> +    }
> +
> +  iaddr += P_PPC_D (insn_prefix, insn_suffix);
> +  record_full_arch_list_add_mem (iaddr, size);
> +  return 0;
> +}
> +
> +/* Record the prefixed instructions with primary op code 32.  The arguments
> +   are the first 32-bits of the instruction (insn_prefix) and the following
> +   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_op32 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  if (type == 1)
> +    {
> +      if (ST4 == 0)
> +	{
> +	  switch (PPC_FIELD (insn_suffix, 11, 3))
> +	    {
> +	    case 0:  	/* VSX Vector Splat Immediate Word 8RR, xxsplti32dx */
> +	      ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
> +	      return 0;
> +	    }
> +
> +	  switch (PPC_FIELD (insn_suffix, 11, 4))
> +	    {
> +	    case 2:  	/* VSX Vector Splat Immediate Double-Precision
> +			   8RR, xxspltidp */
> +	    case 3:  	/* VSX Vector Splat Immediate Word 8RR, xxspltiw */
> +	      ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
> +	      return 0;
> +	    default:
> +	      return -1;
> +	    }
> +	}
> +      else
> +	return -1;
> +
> +    }
> +  else if (type == 2)
> +    {
> +      if (ST1 == 0)  		/* Prefixed Load Word and Zero, plwz */
> +	record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	return -1;
> +
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed instructions with primary op code 33.  The arguments
> +   are the first 32-bits of the instruction(insn_prefix) and the following
> +   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_op33 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  if (type == 1)
> +    {
> +      if (ST4 == 0)
> +	switch (PPC_FIELD (insn_suffix, 26, 2))
> +	  {
> +	  case 0:  	/* VSX Vector Blend Variable Byte 8RR, xxblendvb */
> +	  case 1:  	/* VSX Vector Blend Variable Halfword, xxblendvh */
> +	  case 2:  	/* VSX Vector Blend Variable Word, xxblendvw */
> +	  case 3:  	/* VSX Vector Blend Variable Doubleword, xxblendvd */
> +	    ppc_record_vsr (regcache, tdep, PPC_XT (insn_suffix));
> +	  break;
> +	  default:
> +	    return -1;
> +	  }
> +      else
> +	return -1;
> +
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed instructions with primary op code 34.  The arguments
> +   are the first 32-bits of the instruction(insn_prefix) and the following
> +   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_op34 (struct gdbarch *gdbarch,
> +				struct regcache *regcache,
> +				uint32_t insn_prefix, uint32_t insn_suffix)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +
> +  if (type == 1)
> +    {
> +      if (ST4 == 0)
> +	switch (PPC_FIELD (insn_suffix, 26, 2))
> +	  {
> +	  case 0:  	/* VSX Vector Permute Extended 8RR, xxpermx */
> +	  case 1:  	/* VSX Vector Evaluate 8RR, xxeval */
> +	    ppc_record_vsr (regcache, tdep, P_PPC_XT (insn_suffix));
> +	    break;
> +	  default:
> +	    return -1;
> +	  }
> +      else
> +	return -1;
> +
> +    }
> +  else if (type == 2)
> +    {
> +      if (ST1 == 0)  		/* Prefixed Load Word and Zero, plbz */
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	return -1;
> +
> +    }
> +  else
> +    return -1;
> +
> +  return 0;
> +}
> +
> +/* Record the prefixed VSX store, form DS, instructions.  The arguments are the
> +   instruction address (addr), the first 32-bits of the instruction
> +   (insn_prefix) followed by the 32-bit instruction suffix (insn_suffix).
> +   Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_store_vsx_ds_form (struct gdbarch *gdbarch,
> +					     struct regcache *regcache,
> +					     CORE_ADDR addr,
> +					     uint32_t insn_prefix,
> +					     uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  ULONGEST ea = 0;
> +  int size;
> +  int R = PPC_BIT (insn_prefix, 11);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +
> +  if ((type == 0) && (ST1 == 0))
> +    {
> +      if (R == 0)
> +	{
> +	  if (PPC_RA (insn_suffix) != 0)
> +	    regcache_raw_read_unsigned (regcache,
> +					tdep->ppc_gp0_regnum
> +					+ PPC_RA (insn_suffix),
> +					&ea);
> +	}
> +      else
> +	{
> +	  ea = addr;     /* PC relative */
> +	}
> +
> +      ea += P_PPC_D (insn_prefix, insn_suffix);
> +      switch (PPC_FIELD (insn_suffix, 0, 6))
> +	{
> +	case 46:    /* Prefixed Store VSX Scalar Doubleword, pstxsd */
> +	  size = 8;
> +	  break;
> +	case 47:    /* Prefixed,Store VSX Scalar Single-Precision, pstxssp */
> +	  size = 4;
> +	  break;
> +	default:
> +	  return -1;
> +	}
> +      record_full_arch_list_add_mem (ea, size);
> +      return 0;
> +  }
> +  else
> +    return -1;
> +}
> +
> +/* Record the prefixed VSX, form D, instructions.  The arguments are the
> +   instruction address for PC-relative addresss (addr), the first 32-bits of
> +   the instruction (insn_prefix) and the following 32-bits of the instruction
> +   (insn_suffix).  Return 0 on success.  */
> +
> +static int
> +ppc_process_record_prefix_vsx_d_form (struct gdbarch *gdbarch,
> +				      struct regcache *regcache,
> +				      CORE_ADDR addr,
> +				      uint32_t insn_prefix,
> +				      uint32_t insn_suffix)
> +{
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  ULONGEST ea = 0;
> +  int size;
> +  int R = PPC_BIT (insn_prefix, 11);
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +
> +  if ((type == 0) && (ST1 == 0))
> +    {
> +      switch (PPC_FIELD (insn_suffix, 0, 5))
> +	{
> +	case 25:	/* Prefixed Load VSX Vector, plxv */
> +	  ppc_record_vsr (regcache, tdep, P_PPC_XT5 (insn_prefix));
> +	  return 0;
> +	case 27:	/* Prefixed Store VSX Vector 8LS, pstxv */
> +	  {
> +	    size = 16;
> +	    if (R == 0)
> +	      {
> +		if (PPC_RA (insn_suffix) != 0)
> +		  regcache_raw_read_unsigned (regcache,
> +					      tdep->ppc_gp0_regnum
> +					      + PPC_RA (insn_suffix),
> +					      &ea);
> +	      }
> +	    else
> +	      {
> +		ea = addr;     /* PC relative */
> +	      }
> +
> +	    ea += P_PPC_D (insn_prefix, insn_suffix);
> +	    record_full_arch_list_add_mem (ea, size);
> +	    return 0;
> +	  }
> +	}
> +      return -1;
> +    }
> +  else
> +    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.  */
>  
> +/* This handles the recording of the various prefix instructions.  It takes
> +   the instruction address, the first 32-bits of the instruction (insn_prefix)
> +   and the following 32-bits of the instruction (insn_suffix).  Return 0 on
> +   success.  */
> +
> +static int
> +ppc_process_prefix_instruction (int insn_prefix, int insn_suffix,
> +				CORE_ADDR addr,	struct gdbarch *gdbarch,
> +				struct regcache *regcache)
> +{
> +  int type = PPC_FIELD (insn_prefix, 6, 2);
> +  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
> +  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
> +  int op6;
> +
> +  /* D-form has uses a 5-bit opcode in the instruction suffix */
> +  if (ppc_process_record_prefix_vsx_d_form ( gdbarch, regcache, addr,
> +					     insn_prefix, insn_suffix) == 0)
> +    goto SUCCESS;
> +
> +  op6 = PPC_OP6 (insn_suffix);  /* 6-bit opcode in the instruction suffix */
> +
> +  switch (op6)
> +    {
> +    case 14:		/* Prefixed Add Immediate, paddi */
> +      if ((type == 2) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 32:
> +      if (ppc_process_record_prefix_op32 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 33:
> +      if (ppc_process_record_prefix_op33 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 34:		/* Prefixed Load Byte and Zero, plbz */
> +      if (ppc_process_record_prefix_op34 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +    case 40:		/* Prefixed Load Halfword and Zero, plhz */
> +      if ((type == 2) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +      break;
> +
> +    case 36:		/* Prefixed Store Word, pstw */
> +    case 38:		/* Prefixed Store Byte, pstb */
> +    case 44:		/* Prefixed Store Halfword, psth */
> +    case 52:		/* Prefixed Store Floating-Point Single, pstfs */
> +    case 54:		/* Prefixed Store Floating-Point Double, pstfd */
> +    case 60:		/* Prefixed Store Quadword, pstq */
> +    case 61:		/* Prefixed Store Doubleword, pstd */
> +      if (ppc_process_record_prefix_store (gdbarch, regcache, addr,
> +					   insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 42:
> +      if (ppc_process_record_prefix_op42 (gdbarch, regcache,
> +					  insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 43:          /* Prefixed Load VSX Scalar Single-Precision, plxssp */
> +      if ((type == 0) && (ST1 == 0))
> +	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
> +      else
> +	  goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 46:
> +    case 47:
> +      if (ppc_process_record_prefix_store_vsx_ds_form (gdbarch, regcache, addr,
> +					       insn_prefix, insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 56:		/* Prefixed Load Quadword, plq */
> +      {
> +	if ((type == 0) && (ST1 == 0))
> +	  {
> +	    int tmp;
> +	    tmp = tdep->ppc_gp0_regnum + (PPC_RT (insn_suffix) & ~1);
> +	    record_full_arch_list_add_reg (regcache, tmp);
> +	    record_full_arch_list_add_reg (regcache, tmp + 1);
> +	  }
> +	else
> +	  goto UNKNOWN_PREFIX_OP;
> +	break;
> +      }
> +
> +    case 41:		/* Prefixed Load Word Algebraic, plwa */
> +    case 57:  		/* Prefixed Load Doubleword, pld */
> +      if ((type == 0) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_gp0_regnum
> +				       + PPC_RT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 48:		/* Prefixed Load Floating-Point Single, plfs */
> +    case 50:		/* Prefixed Load Floating-Point Double, plfd */
> +      if ((type == 2) && (ST1 == 0))
> +	record_full_arch_list_add_reg (regcache,
> +				       tdep->ppc_fp0_regnum
> +				       + PPC_FRT (insn_suffix));
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 58:		/* Prefixed Load VSX Vector Paired, plxvp */
> +      if ((type == 0) && (ST1 == 0))
> +	{
> +	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix));
> +	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix) + 1);
> +	}
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 59:
> +      if (ppc_process_record_prefix_op59_XX3 (gdbarch, regcache, insn_prefix,
> +					      insn_suffix) != 0)
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    case 62:	    /* Prefixed Store VSX Vector Paired 8LS, pstxvp */
> +      if ((type == 0) && (ST1 == 0))
> +	{
> +	  int R = PPC_BIT (insn_prefix, 11);
> +	  CORE_ADDR ea = 0;
> +
> +	  if (R == 0)
> +	    {
> +	      if (PPC_RA (insn_suffix) != 0)
> +		regcache_raw_read_unsigned (regcache,
> +					    tdep->ppc_gp0_regnum
> +					    + PPC_RA (insn_suffix), &ea);
> +	    }
> +	  else
> +	    {
> +	      ea = addr;     /* PC relative */
> +	    }
> +
> +	  ea += P_PPC_D (insn_prefix, insn_suffix) << 4;
> +	  record_full_arch_list_add_mem (ea, 32);
> +	}
> +      else
> +	goto UNKNOWN_PREFIX_OP;
> +      break;
> +
> +    default:
> +UNKNOWN_PREFIX_OP:
> +      gdb_printf (gdb_stdlog,
> +		  "Warning: Don't know how to record prefix instruction "
> +		  "%08x %08x at %s, %d.\n",
> +		  insn_prefix, insn_suffix, paddress (gdbarch, addr),
> +		  op6);
> +      return -1;
> +    }
> +
> + SUCCESS:
> +  if (record_full_arch_list_add_reg (regcache, PPC_PC_REGNUM))
> +    return -1;
> +
> +  if (record_full_arch_list_add_end ())
> +    return -1;
> +  return 0;
> +}
> +
>  int
>  ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
>  		      CORE_ADDR addr)
>  {
>    ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
>    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
> -  uint32_t insn;
> +  uint32_t insn, insn_suffix;
>    int op6, tmp, i;
>  
>    insn = read_memory_unsigned_integer (addr, 4, byte_order);
> @@ -5965,16 +7098,28 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
>  
>    switch (op6)
>      {
> +    case 1:		/* prefixed instruction */
> +      {
> +	/* Get the lower 32-bits of the prefixed instruction. */
> +	insn_suffix = read_memory_unsigned_integer (addr+4, 4, byte_order);
> +	return ppc_process_prefix_instruction (insn, insn_suffix, addr,
> +					       gdbarch, regcache);
> +      }
>      case 2:		/* Trap Doubleword Immediate */
>      case 3:		/* Trap Word Immediate */
>        /* Do nothing.  */
>        break;
>  
> -    case 4:
> +    case 4:             /* Vector Integer, Compare, Logical, Shift, etc.  */
>        if (ppc_process_record_op4 (gdbarch, regcache, addr, insn) != 0)
>  	return -1;
>        break;
>  
> +    case 6:             /* Vector Load and Store */
> +      if (ppc_process_record_op6 (gdbarch, regcache, addr, insn) != 0)
> +	return -1;
> +      break;
> +
>      case 17:		/* System call */
>        if (PPC_LEV (insn) != 0)
>  	goto UNKNOWN_OP;
> -- 
> 2.31.1
> 
> 

-- 
Joel

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/2 Version 5] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-18 19:21                   ` [PATCH 2/2 Version 5] " Carl Love
  2022-04-22 19:47                     ` [PATCH 2/2 Version 5 PING] " Carl Love
@ 2022-04-24 16:56                     ` Joel Brobecker
  1 sibling, 0 replies; 25+ messages in thread
From: Joel Brobecker @ 2022-04-24 16:56 UTC (permalink / raw)
  To: Carl Love
  Cc: Joel Brobecker, Pedro Alves, will schmidt, gdb-patches,
	Ulrich Weigand, Tulio Magno, Rogerio Alves

> GDB PowerPC record test cases for ISA 2.06 and ISA 3.1
> 
> This patch adds PowerPC specific tests to verify recording of various
> instructions.  The first test case checks the ISA 2.06 lxvd2x instruction.
> The second test case tests several of the ISA 3.01 instructions.  Specifically,
> it checks the word and prefixed instructions and some of the Matrix
> Multiply Assist (MMA) instructions.
> 
> The patch has been run on both Power 10 and Power 9 to verify the ISA
> 2.06 test case runs on both platforms without errors.  The ISA 3.1 test
> runs without errors on Power 10 and is skipped as expected on Power 9.

Looks good to me, so OK to push to master.

> ---
>  .../gdb.reverse/ppc_record_test_isa_2_06.c    |  39 ++
>  .../gdb.reverse/ppc_record_test_isa_2_06.exp  | 105 ++++++
>  .../gdb.reverse/ppc_record_test_isa_3_1.c     |  95 +++++
>  .../gdb.reverse/ppc_record_test_isa_3_1.exp   | 341 ++++++++++++++++++
>  4 files changed, 580 insertions(+)
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
>  create mode 100644 gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> 
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
> new file mode 100644
> index 00000000000..45e58413da2
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.c
> @@ -0,0 +1,39 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2012-2022 Free Software Foundation, Inc.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +/* globals used for vector tests */
> +static vector unsigned long vec_xb;
> +static unsigned long ra, rb, rs;
> +
> +int
> +main ()
> +{
> +  ra = 0xABCDEF012;
> +  rb = 0;
> +  rs = 0x012345678;
> +
> +  /* 9.0, 16.0, 25.0, 36.0 */
> +  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
> +
> +  /* Test ISA 2.06 instructions.  Load source into vs1, result of sqrt
> +     put into vs0.  */
> +  ra = (unsigned long) & vec_xb;        /* stop 1 */
> +  __asm__ __volatile__ ("lxvd2x 1, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("xvsqrtsp 0, 1");
> +  ra = 0;                               /* stop 2 */
> +}
> +
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
> new file mode 100644
> index 00000000000..d68dd7b9049
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_2_06.exp
> @@ -0,0 +1,105 @@
> +# Copyright 2008-2022 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +#
> +# Test instruction record for PowerPC, ISA 2.06.
> +#
> +
> +# The basic flow of the record tests are:
> +#    1) Stop before executing the instructions of interest.  Record
> +#       the initial value of the registers that the instruction will
> +#       change, i.e. the destination register.
> +#    2) Execute the instructions.  Record the new value of the
> +#       registers that changed.
> +#    3) Reverse the direction of the execution and execute back to
> +#       just before the instructions of interest.  Record the final
> +#       value of the registers of interest.
> +#    4) Check that the initial and new values of the registers are
> +#       different, i.e. the instruction changed the registers as expected.
> +#    5) Check that the initial and final values of the registers are
> +#       the same, i.e. gdb record restored the registers to their
> +#       original values.
> +
> +standard_testfile
> +
> +set gen_src record_test_isa_2_06.c
> +set executable record_test_isa_2_06
> +set options [list debug]
> +
> +if {![istarget "powerpc*"]} then {
> +    verbose "Skipping PowerPC ISA 2.06 instruction record_test_2_06."
> +    return
> +}
> +
> +if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
> +    return -1
> +}
> +
> +clean_restart $executable
> +
> +if ![runto_main] then {
> +    untested "could not run to main"
> +    continue
> +}
> +
> +gdb_test_no_output "record"
> +
> +###### Test: Test an ISA 2.06 load (lxvd2x) and square root instruction
> +###### (xvsqrtsp).  The load instruction will load vs1.  The sqrt instruction
> +###### will put its result into vs0.
> +
> +set stop1 [gdb_get_line_number "stop 1"]
> +set stop2 [gdb_get_line_number "stop 2"]
> +
> +gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 1"
> +
> +# Record the initial values in vs0, vs1.
> +set vs0_initial [capture_command_output "info register vs0" ""]
> +set vs1_initial [capture_command_output "info register vs1" ""]
> +
> +gdb_test "break $stop2" ".*Breakpoint .*" "executed lxvd2x, xvsqrtsp"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 2"
> +
> +# Record the new values of vs0 and vs1.
> +set vs0_new [capture_command_output "info register vs0" ""]
> +set vs1_new [capture_command_output "info register vs1" ""]
> +
> +# Reverse the execution direction.
> +gdb_test_no_output "set exec-direction reverse"
> +gdb_test "break $stop1" ".*Breakpoint .*" "un executed lxvd2x, xvsqrtsp"
> +
> +# Execute in reverse to before the lxvd2x instruction.
> +gdb_test "continue"  ".*Breakpoint.*" "at stop 1 in reverse"
> +
> +# Record the final values of vs0, vs1.
> +set vs0_final [capture_command_output "info register vs0" ""]
> +set vs1_final [capture_command_output "info register vs1" ""]
> +
> +# Check initial and new of vs0 are different.
> +gdb_assert [string compare $vs0_initial $vs1_new] \
> +    "check vs0 initial versus vs0 new"
> +
> +# Check initial and new of vs1 are different.
> +gdb_assert [string compare $vs1_initial $vs1_new] \
> +    "check vs0 initial versus vs1 new"
> +
> +# Check initial and final are the same.
> +gdb_assert ![string compare $vs0_initial $vs0_final] \
> +    "check vs0 initial versus vs0 final"
> +
> +# Check initial and final are the same.
> +gdb_assert ![string compare $vs1_initial $vs1_final] \
> +    "check vs1 initial versus vs1 final"
> +
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
> new file mode 100644
> index 00000000000..c0d65d944af
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.c
> @@ -0,0 +1,95 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2012-2022 Free Software Foundation, Inc.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +/* Globals used for vector tests.  */
> +static vector unsigned long vec_xa, vec_xb, vec_xt;
> +static unsigned long ra, rb, rs;
> +
> +int
> +main ()
> +{
> +  ra = 0xABCDEF012;
> +  rb = 0;
> +  rs = 0x012345678;
> +
> +  /* 9.0, 16.0, 25.0, 36.0 */
> +  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
> +
> +  vec_xt = (vector unsigned long){0xFF00FF00FF00FF00, 0xAA00AA00AA00AA00};
> +
> +  /* Test 1, ISA 3.1 word instructions. Load source into r1, result of brh
> +     put in r0.  */
> +  ra = 0xABCDEF012;                     /* stop 1 */
> +  __asm__ __volatile__ ("pld 1, %0" :: "r" (ra ));
> +  __asm__ __volatile__ ("brh 0, 1" );
> +  ra = 0;                               /* stop 2 */
> +
> +  /* Test 2, ISA 3.1 MMA instructions with results in various ACC entries
> +     xxsetaccz    - ACC[3]
> +     xvi4ger8     - ACC[4]
> +     xvf16ger2pn  - ACC[5]
> +     pmxvi8ger4   - ACC[6]
> +     pmxvf32gerpp - ACC[7] and fpscr */
> +  /* Need to initialize the vs registers to a non zero value.  */
> +  ra = (unsigned long) & vec_xb;
> +  __asm__ __volatile__ ("lxvd2x 12, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 13, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 14, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 15, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xa = (vector unsigned long){0x333134343987601, 0x9994bbbc9983307};
> +  vec_xb = (vector unsigned long){0x411234041898760, 0x41c833042103400};
> +  __asm__ __volatile__ ("lxvd2x 16, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x123456789987650, 0x235676546989807};
> +  __asm__ __volatile__ ("lxvd2x 17, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x878363439823470, 0x413434c99839870};
> +  __asm__ __volatile__ ("lxvd2x 18, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x043765434398760, 0x419876555558850};
> +  __asm__ __volatile__ ("lxvd2x 19, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x33313434398760, 0x9994bbbc99899330};
> +  __asm__ __volatile__ ("lxvd2x 20, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 21, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 22, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 23, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 24, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 25, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 26, %0, %1" :: "r" (ra ), "r" (rb));
> +  __asm__ __volatile__ ("lxvd2x 27, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xa = (vector unsigned long){0x33313434398760, 0x9994bbbc998330};
> +  vec_xb = (vector unsigned long){0x4110000041800000, 0x41c8000042100000};
> +  __asm__ __volatile__ ("lxvd2x 28, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x4567000046800000, 0x4458000048700000};
> +  __asm__ __volatile__ ("lxvd2x 29, %0, %1" :: "r" (ra ), "r" (rb));
> +  vec_xb = (vector unsigned long){0x41dd000041e00000, 0x41c8000046544400};
> +  __asm__ __volatile__ ("lxvd2x 30, %0, %1" :: "r" (ra ), "r" (rb));
> +
> +  /* SNAN */
> +  vec_xb = (vector unsigned long){0x7F8F00007F8F0000, 0x7F8F00007F8F0000};
> +
> +  __asm__ __volatile__ ("lxvd2x 31, %0, %1" :: "r" (ra ), "r" (rb));
> +
> +  ra = 0xAB;                            /* stop 3 */
> +  __asm__ __volatile__ ("xxsetaccz 3");
> +  __asm__ __volatile__ ("xvi4ger8 4, %x0, %x1" :: "wa" (vec_xa), \
> +			"wa" (vec_xb) );
> +  __asm__ __volatile__ ("xvf16ger2pn 5, %x0, %x1" :: "wa" (vec_xa),\
> +			"wa" (vec_xb) );
> +  __asm__ __volatile__ ("pmxvi8ger4spp  6, %x0, %x1, 11, 13, 5"
> +                                :: "wa" (vec_xa), "wa" (vec_xb) );
> +  __asm__ __volatile__ ("pmxvf32gerpp  7, %x0, %x1, 11, 13"
> +                                :: "wa" (vec_xa), "wa" (vec_xb) );
> +  ra = 0;                               /* stop 4 */
> +}
> diff --git a/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> new file mode 100644
> index 00000000000..9ea8931e9cf
> --- /dev/null
> +++ b/gdb/testsuite/gdb.reverse/ppc_record_test_isa_3_1.exp
> @@ -0,0 +1,341 @@
> +# Copyright 2008-2022 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +#
> +# Test instruction record for PowerPC, ISA 3.1.
> +#
> +
> +# The basic flow of the record tests are:
> +#    1) Stop before executing the instructions of interest.  Record
> +#       the initial value of the registers that the instruction will
> +#       change, i.e. the destination register.
> +#    2) Execute the instructions.  Record the new value of the
> +#       registers that changed.
> +#    3) Reverse the direction of the execution and execute back to
> +#       just before the instructions of interest.  Record the final
> +#       value of the registers of interest.
> +#    4) Check that the initial and new values of the registers are
> +#       different, i.e. the instruction changed the registers as expected.
> +#    5) Check that the initial and final values of the registers are
> +#       the same, i.e. gdb record restored the registers to their
> +#       original values.
> +
> +
> +standard_testfile
> +
> +set gen_src record_test_isa_3_1.c
> +set executable record_test_isa_3_1
> +
> +if {![istarget "powerpc*"] || [skip_power_isa_3_1_tests] } then  {
> +    verbose "Skipping PowerPC ISA 3.1 instruction record_test."
> +    return
> +}
> +
> +set options [list additional_flags=-mcpu=power10 debug]
> +if {[build_executable "failed to prepare" $executable $srcfile $options] == -1} then {
> +    return -1
> +}
> +
> +clean_restart $executable
> +
> +if ![runto_main] then {
> +    untested "could not run to main"
> +    continue
> +}
> +
> +gdb_test_no_output "record"
> +
> +######  Test 1:  Test an ISA 3.1 byte reverse word instruction (brd) and a
> +######  prefixed load double (pld) instruction.
> +set stop1 [gdb_get_line_number "stop 1"]
> +set stop2 [gdb_get_line_number "stop 2"]
> +
> +gdb_test "break $stop1" ".*Breakpoint .*" "about to execute test 1"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 1"
> +
> +# Record the initial values in r0, r1
> +# Load the argument into r1, result of byte reverse is put into r0.
> +set r0_initial [capture_command_output "info register r0" ""]
> +set r1_initial [capture_command_output "info register r1" ""]
> +
> +gdb_test "break $stop2" ".*Breakpoint .*" "executed test 1"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 2"
> +
> +# Record the new values of r0 and r1
> +set r0_new [capture_command_output "info register r0" ""]
> +set r1_new [capture_command_output "info register r1" ""]
> +
> +# Execute in reverse to before test 1
> +gdb_test_no_output "set exec-direction reverse"
> +
> +gdb_test "break $stop1" ".*Breakpoint .*" "reverse stop at test 1 start"
> +gdb_test "continue"  ".*Breakpoint.*" "at stop 1 in reverse"
> +
> +# Record the final values of r0, r1
> +set r0_final [capture_command_output "info register r0" ""]
> +set r1_final [capture_command_output "info register r1" ""]
> +
> +# Check initial and new of r0 are different.
> +gdb_assert [string compare $r0_initial $r0_new] \
> +    "check r0 initial versus r0 new"
> +
> +# Check initial and new of r1 are different.
> +gdb_assert [string compare $r1_initial $r1_new] \
> +    "check r0 initial versus r1 new"
> +
> +# Check initial and final are the same.
> +gdb_assert ![string compare $r0_initial $r0_final] \
> +    "check r0 initial versus r0 final"
> +
> +# Check initial and final are the same.
> +gdb_assert ![string compare $r1_initial $r1_final] \
> +    "check r1 initial versus r1 final"
> +
> +
> +# Change execution direction to forward for next test.
> +gdb_test_no_output "set exec-direction forward" "start forward test3"
> +gdb_test "record stop" ".*Process record is stopped.*" "stopped recording 2"
> +set test_del_bkpts "delete breakpoints, answer prompt 2"
> +
> +# Delete all breakpoints and catchpoints.
> +delete_breakpoints
> +
> +gdb_test_no_output "record" "start recording test2"
> +
> +
> +######  Test 2:  Test the ISA 3.1 MMA instructions xxsetaccz, xvi4ger8,
> +######  xvf16ger2pn, pmxvi8ger4, and pmxvf32gerpp.  Goal here is to hit all
> +######  the places where ppc_record_ACC_fpscr() gets called.
> +##
> +##       xxsetaccz    - ACC[3], vs[12] to vs[15]
> +##       xvi4ger8     - ACC[4], vs[16] to vs[19]
> +##       xvf16ger2pn  - ACC[5], vs[20] to vs[23]
> +##       pmxvi8ger4   - ACC[6], vs[21] to vs[27]
> +##       pmxvf32gerpp - ACC[7], vs[28] to vs[31] and fpscr
> +
> +set stop3 [gdb_get_line_number "stop 3"]
> +set stop4 [gdb_get_line_number "stop 4"]
> +
> +gdb_test "break $stop3" ".*Breakpoint .*" "about to execute test 2"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 3"
> +
> +# Record the initial values of vs's that correspond to the ACC entries,
> +# and fpscr.
> +set acc_3_0_initial [capture_command_output "info register vs12" ""]
> +set acc_3_1_initial [capture_command_output "info register vs13" ""]
> +set acc_3_2_initial [capture_command_output "info register vs14" ""]
> +set acc_3_3_initial [capture_command_output "info register vs15" ""]
> +set acc_4_0_initial [capture_command_output "info register vs16" ""]
> +set acc_4_1_initial [capture_command_output "info register vs17" ""]
> +set acc_4_2_initial [capture_command_output "info register vs18" ""]
> +set acc_4_3_initial [capture_command_output "info register vs19" ""]
> +set acc_5_0_initial [capture_command_output "info register vs20" ""]
> +set acc_5_1_initial [capture_command_output "info register vs21" ""]
> +set acc_5_2_initial [capture_command_output "info register vs22" ""]
> +set acc_5_3_initial [capture_command_output "info register vs23" ""]
> +set acc_6_0_initial [capture_command_output "info register vs24" ""]
> +set acc_6_1_initial [capture_command_output "info register vs25" ""]
> +set acc_6_2_initial [capture_command_output "info register vs26" ""]
> +set acc_6_3_initial [capture_command_output "info register vs27" ""]
> +set acc_7_0_initial [capture_command_output "info register vs28" ""]
> +set acc_7_1_initial [capture_command_output "info register vs29" ""]
> +set acc_7_2_initial [capture_command_output "info register vs30" ""]
> +set acc_7_3_initial [capture_command_output "info register vs31" ""]
> +set fpscr_initial [capture_command_output "info register fpscr" ""]
> +
> +gdb_test "break $stop4" ".*Breakpoint .*" "executed test 2"
> +gdb_test "continue"  ".*Breakpoint .*" "at stop 4"
> +
> +# Record the new values of the ACC entries and fpscr.
> +set acc_3_0_new [capture_command_output "info register vs12" ""]
> +set acc_3_1_new [capture_command_output "info register vs13" ""]
> +set acc_3_2_new [capture_command_output "info register vs14" ""]
> +set acc_3_3_new [capture_command_output "info register vs15" ""]
> +set acc_4_0_new [capture_command_output "info register vs16" ""]
> +set acc_4_1_new [capture_command_output "info register vs17" ""]
> +set acc_4_2_new [capture_command_output "info register vs18" ""]
> +set acc_4_3_new [capture_command_output "info register vs19" ""]
> +set acc_5_0_new [capture_command_output "info register vs20" ""]
> +set acc_5_1_new [capture_command_output "info register vs21" ""]
> +set acc_5_2_new [capture_command_output "info register vs22" ""]
> +set acc_5_3_new [capture_command_output "info register vs23" ""]
> +set acc_6_0_new [capture_command_output "info register vs24" ""]
> +set acc_6_1_new [capture_command_output "info register vs25" ""]
> +set acc_6_2_new [capture_command_output "info register vs26" ""]
> +set acc_6_3_new [capture_command_output "info register vs27" ""]
> +set acc_7_0_new [capture_command_output "info register vs28" ""]
> +set acc_7_1_new [capture_command_output "info register vs29" ""]
> +set acc_7_2_new [capture_command_output "info register vs30" ""]
> +set acc_7_3_new [capture_command_output "info register vs31" ""]
> +set fpscr_new [capture_command_output "info register fpscr" ""]
> +
> +# Execute in reverse to before test 2.
> +gdb_test_no_output "set exec-direction reverse" "reverse to start of test 2"
> +
> +gdb_test "break $stop3" ".*Breakpoint .*" "reverse stop at test 2 start"
> +gdb_test "continue"  ".*Breakpoint.*" "at stop 3 in reverse"
> +
> +# Record the final values of the ACC entries and fpscr.
> +set acc_3_0_final [capture_command_output "info register vs12" ""]
> +set acc_3_1_final [capture_command_output "info register vs13" ""]
> +set acc_3_2_final [capture_command_output "info register vs14" ""]
> +set acc_3_3_final [capture_command_output "info register vs15" ""]
> +set acc_4_0_final [capture_command_output "info register vs16" ""]
> +set acc_4_1_final [capture_command_output "info register vs17" ""]
> +set acc_4_2_final [capture_command_output "info register vs18" ""]
> +set acc_4_3_final [capture_command_output "info register vs19" ""]
> +set acc_5_0_final [capture_command_output "info register vs20" ""]
> +set acc_5_1_final [capture_command_output "info register vs21" ""]
> +set acc_5_2_final [capture_command_output "info register vs22" ""]
> +set acc_5_3_final [capture_command_output "info register vs23" ""]
> +set acc_6_0_final [capture_command_output "info register vs24" ""]
> +set acc_6_1_final [capture_command_output "info register vs25" ""]
> +set acc_6_2_final [capture_command_output "info register vs26" ""]
> +set acc_6_3_final [capture_command_output "info register vs27" ""]
> +set acc_7_0_final [capture_command_output "info register vs28" ""]
> +set acc_7_1_final [capture_command_output "info register vs29" ""]
> +set acc_7_2_final [capture_command_output "info register vs30" ""]
> +set acc_7_3_final [capture_command_output "info register vs31" ""]
> +set fpscr_final [capture_command_output "info register fpscr" ""]
> +
> +# check initial and new ACC entries are different.
> +gdb_assert [string compare $acc_3_0_initial $acc_3_0_new] \
> +    "check vs12 initial versus new"
> +
> +gdb_assert [string compare $acc_3_1_initial $acc_3_1_new] \
> +    "check vs13 initial versus new"
> +
> +gdb_assert [string compare $acc_3_2_initial $acc_3_2_new] \
> +    "check vs14 initial versus new"
> +
> +gdb_assert [string compare $acc_3_3_initial $acc_3_3_new] \
> +    "check vs15 initial versus new"
> +
> +gdb_assert [string compare $acc_4_0_initial $acc_4_0_new] \
> +    "check vs16 initial versus new"
> +
> +gdb_assert [string compare $acc_4_1_initial $acc_4_1_new] \
> +    "check vs17 initial versus new"
> +
> +gdb_assert [string compare $acc_4_2_initial $acc_4_2_new] \
> +    "check vs18 initial versus new"
> +
> +gdb_assert [string compare $acc_4_3_initial $acc_4_3_new] \
> +    "check vs19 initial versus new"
> +
> +gdb_assert [string compare $acc_5_0_initial $acc_5_0_new] \
> +    "check vs20 initial versus new"
> +
> +gdb_assert [string compare $acc_5_1_initial $acc_5_1_new] \
> +    "check vs21 initial versus new"
> +
> +gdb_assert [string compare $acc_5_2_initial $acc_5_2_new] \
> +    "check vs22 initial versus new"
> +
> +gdb_assert [string compare $acc_5_3_initial $acc_5_3_new] \
> +    "check vs23 initial versus new"
> +
> +gdb_assert [string compare $acc_6_0_initial $acc_6_0_new] \
> +    "check vs24 initial versus new"
> +
> +gdb_assert [string compare $acc_6_1_initial $acc_6_1_new] \
> +    "check vs25 initial versus new"
> +
> +gdb_assert [string compare $acc_6_2_initial $acc_6_2_new] \
> +    "check vs26 initial versus new"
> +
> +gdb_assert [string compare $acc_6_3_initial $acc_6_3_new] \
> +    "check vs27 initial versus new"
> +
> +gdb_assert [string compare $acc_7_0_initial $acc_7_0_new] \
> +    "check vs28 initial versus new"
> +
> +gdb_assert [string compare $acc_7_1_initial $acc_7_1_new] \
> +    "check vs29 initial versus new"
> +
> +gdb_assert [string compare $acc_7_2_initial $acc_7_2_new] \
> +    "check vs30 initial versus new"
> +
> +gdb_assert [string compare $acc_7_3_initial $acc_7_3_new] \
> +    "check vs31 initial versus new"
> +
> +gdb_assert [string compare $fpscr_initial $fpscr_new] \
> +    "check fpscr initial versus new"
> +
> +
> +# Check initial and final ACC entries are the same.
> +gdb_assert ![string compare $acc_3_0_initial $acc_3_0_final] \
> +    "check vs12 initial versus final"
> +
> +gdb_assert ![string compare $acc_3_1_initial $acc_3_1_final] \
> +    "check vs13 initial versus final"
> +
> +gdb_assert ![string compare $acc_3_2_initial $acc_3_2_final] \
> +    "check vs14 initial versus final"
> +
> +gdb_assert ![string compare $acc_3_3_initial $acc_3_3_final] \
> +    "check vs15 initial versus final"
> +
> +gdb_assert ![string compare $acc_4_0_initial $acc_4_0_final] \
> +    "check vs16 initial versus final"
> +
> +gdb_assert ![string compare $acc_4_1_initial $acc_4_1_final] \
> +    "check vs17 initial versus final"
> +
> +gdb_assert ![string compare $acc_4_2_initial $acc_4_2_final] \
> +    "check vs18 initial versus final"
> +
> +gdb_assert ![string compare $acc_4_3_initial $acc_4_3_final] \
> +    "check vs19 initial versus final"
> +
> +gdb_assert ![string compare $acc_5_0_initial $acc_5_0_final] \
> +    "check vs20 initial versus final"
> +
> +gdb_assert ![string compare $acc_5_1_initial $acc_5_1_final] \
> +    "check vs21 initial versus final"
> +
> +gdb_assert ![string compare $acc_5_2_initial $acc_5_2_final] \
> +    "check vs22 initial versus final"
> +
> +gdb_assert ![string compare $acc_5_3_initial $acc_5_3_final] \
> +    "check vs23 initial versus final"
> +
> +gdb_assert ![string compare $acc_6_0_initial $acc_6_0_final] \
> +    "check vs24 initial versus final"
> +
> +gdb_assert ![string compare $acc_6_1_initial $acc_6_1_final] \
> +    "check vs25 initial versus final"
> +
> +gdb_assert ![string compare $acc_6_2_initial $acc_6_2_final] \
> +    "check vs26 initial versus final"
> +
> +gdb_assert ![string compare $acc_6_3_initial $acc_6_3_final] \
> +    "check vs27 initial versus final"
> +
> +gdb_assert ![string compare $acc_7_0_initial $acc_7_0_final] \
> +    "check vs28 initial versus final"
> +
> +gdb_assert ![string compare $acc_7_1_initial $acc_7_1_final] \
> +    "check vs29 initial versus final"
> +
> +gdb_assert ![string compare $acc_7_2_initial $acc_7_2_final] \
> +    "check !vs30 initial versus final"
> +
> +gdb_assert ![string compare $acc_7_3_initial $acc_7_3_final] \
> +    "check !vs31 initial versus final"
> +
> +gdb_assert ![string compare $fpscr_initial $fpscr_final] \
> +    "check fpscr initial versus final"
> +
> +
> -- 
> 2.31.1
> 
> 

-- 
Joel

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH 1/2 Version 6] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-24 16:50               ` [PATCH 1/2 Version 5] " Joel Brobecker
@ 2022-04-25 15:58                 ` Carl Love
  2022-04-26 18:05                   ` Joel Brobecker
  0 siblings, 1 reply; 25+ messages in thread
From: Carl Love @ 2022-04-25 15:58 UTC (permalink / raw)
  To: Joel Brobecker, cel
  Cc: will schmidt, gdb-patches, Ulrich Weigand, Tulio Magno, Rogerio Alves

Joel:

On Sun, 2022-04-24 at 09:50 -0700, Joel Brobecker wrote:
> One thing I wanted to mention is that the GNU Coding Style has a
> convention whereby the all-caps spelling of an entity means the
> value of that entity. E.g. "FOO" means "the value of foo". We use
> that extensitively in GDB. So, you could say, for instance:
> 
>     AT provides which of the 8 AT entries to record.
>     SAVE_FPSCR should be set to true if the FPSCR also needs to be
>     recorded, false otherwise.
> 
> And FWIW, I have a comment which is a bit on the nit-picking side,
> but
> said in the spirit of trying to raise awareness rather than a change
> request, so I'll let you decide what to do with it:
> 
>     For me, "which of the 8 AT entries to record" is slightly
>     confusing, because it leaves me wondering what kind of value
>     this should be given. I mean, could multiple AT entries be
>     recorded, and not just one, in which case I suppose AT would
>     be some kind of mask. Or does the function only ever record
>     one AT entry, in which case AT is the corresponding number?
> 
> If you do decide to act on it, I invite you to do so as a separate
> commit, just so we don't delay this commit further for something
> so minor, especially after the patch having gone through several
> iterations already.

Thanks for the additional comments.  Given that we are not under any
timeline to get this patch done and the changes are very minor I think
it is better to just get it right the first time rather than have to
come back ad fix it up later.  The changes are all localized as well.

I have made the changes to the header comment for the function
ppc_record_ACC_fpscr() to clairfy what the function does as well as to
use the capitalization to indicate the value.  The parameter "at" was
also changed to "entry" to make it clearer we are selecting one of the
possible AT entries to be recorded.  Finally, argument save_fpscr was
changed to a boolean thus eliminating the #defines for RECORD_FPSCR and
DO_NOT_RECORD_FPSCR.  Fortunately, the changes are all at the beginning
of the patch making it easy to find.

As always, the patch was retested to make sure I didn't break anything.
Please let me know if the additional changes are acceptable.  Thanks.

                      Carl 

--------------------------------------------------------------------

Add recording support for the ISA 3.1 PowerPC instructions.

This patch adds support for the PowerPC ISA 3.1 instructions to the PowerPC
gdb instruction recording routines.  Case statement entries are added to a
number of the existing routines for recording the 32-bit word instructions.
A few new functions were added to handle the new word instructions.  The 64-bit
prefix instructions are all handled by a set of new routines.  The function
ppc_process_prefix_instruction() is the primary function to handle the
prefixed instructions. It calls additional functions to handle specific
sets of prefixed instructions.  These new functions are:
  ppc_process_record_prefix_vsx_d_form(),
  ppc_process_record_prefix_store_vsx_ds_form(),
  ppc_process_record_prefix_op34(),
  ppc_process_record_prefix_op33(),
  ppc_process_record_prefix_op32(),
  ppc_process_record_prefix_store(),
  ppc_process_record_prefix_op59_XX3(),
  ppc_process_record_prefix_op42().
---
 gdb/rs6000-tdep.c | 1195 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 1169 insertions(+), 26 deletions(-)

diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 44828bcff6d..6815dfaa820 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -4123,8 +4123,25 @@ bfd_uses_spe_extensions (bfd *abfd)
 #define PPC_LEV(insn)	PPC_FIELD (insn, 20, 7)
 
 #define PPC_XT(insn)	((PPC_TX (insn) << 5) | PPC_T (insn))
+#define PPC_XTp(insn)	((PPC_BIT (insn, 10) << 5)	\
+			 | PPC_FIELD (insn, 6, 4) << 1)
+#define PPC_XSp(insn)	((PPC_BIT (insn, 10) << 5)	\
+			 | PPC_FIELD (insn, 6, 4) << 1)
 #define PPC_XER_NB(xer)	(xer & 0x7f)
 
+/* The following macros are for the prefixed instructions.  */
+#define P_PPC_D(insn_prefix, insn_suffix) \
+  PPC_SEXT (PPC_FIELD (insn_prefix, 14, 18) << 16 \
+	    | PPC_FIELD (insn_suffix, 16, 16), 34)
+#define P_PPC_TX5(insn_sufix)	PPC_BIT (insn_suffix, 5)
+#define P_PPC_TX15(insn_suffix) PPC_BIT (insn_suffix, 15)
+#define P_PPC_XT(insn_suffix)	((PPC_TX (insn_suffix) << 5) \
+				 | PPC_T (insn_suffix))
+#define P_PPC_XT5(insn_suffix) ((P_PPC_TX5 (insn_suffix) << 5) \
+				| PPC_T (insn_suffix))
+#define P_PPC_XT15(insn_suffix) \
+  ((P_PPC_TX15 (insn_suffix) << 5) | PPC_T (insn_suffix))
+
 /* Record Vector-Scalar Registers.
    For VSR less than 32, it's represented by an FPR and an VSR-upper register.
    Otherwise, it's just a VR register.  Record them accordingly.  */
@@ -4152,6 +4169,59 @@ ppc_record_vsr (struct regcache *regcache, ppc_gdbarch_tdep *tdep, int vsr)
   return 0;
 }
 
+/* The ppc_record_ACC_fpscr() records the changes to the VSR registers
+   modified by a floating point instruction.  The ENTRY argument selects which
+   of the eight AT entries needs to be recorded.  The boolean SAVE_FPSCR
+   argument is set to TRUE to indicate the FPSCR also needs to be recorded.
+   The function returns 0 on success.  */
+
+static int
+ppc_record_ACC_fpscr (struct regcache *regcache, ppc_gdbarch_tdep *tdep,
+		      int entry, bool save_fpscr)
+{
+  int i;
+  if (entry < 0 || entry >= 8)
+    return -1;
+
+  /* The ACC register file consists of 8 register entries, each register
+     entry consist of four 128-bit rows.
+
+     The ACC rows map to specific VSR registers.
+         ACC[0][0] -> VSR[0]
+         ACC[0][1] -> VSR[1]
+         ACC[0][2] -> VSR[2]
+         ACC[0][3] -> VSR[3]
+              ...
+         ACC[7][0] -> VSR[28]
+         ACC[7][1] -> VSR[29]
+         ACC[7][2] -> VSR[30]
+         ACC[7][3] -> VSR[31]
+
+     NOTE:
+     In ISA 3.1 the ACC is mapped on top of VSR[0] thru VSR[31].
+
+     In the future, the ACC may be implemented as an independent register file
+     rather than mapping on top of the VSRs.  This will then require the ACC to
+     be assigned its own register number and the ptrace interface to be able
+     access the ACC.  Note the ptrace interface for the ACC will also need to
+     be implemented.  */
+
+  /* ACC maps over the same VSR space as the fp registers.  */
+  for (i = 0; i < 4; i++)
+    {
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fp0_regnum
+				     + entry * 4 + i);
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_vsr0_upper_regnum
+				     + entry * 4 + i);
+    }
+
+  if (save_fpscr)
+    record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+
+  return 0;
+}
+
 /* Parse and record instructions primary opcode-4 at ADDR.
    Return 0 if successful.  */
 
@@ -4171,9 +4241,34 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 41:		/* Vector Multiply-Sum Signed Halfword Saturate */
       record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
       /* FALL-THROUGH */
+    case 20:		/* Move To VSR Byte Mask Immediate opcode, b2 = 0,
+			   ignore bit 31 */
+    case 21:		/* Move To VSR Byte Mask Immediate opcode, b2 = 1,
+			   ignore bit 31 */
+    case 23:		/* Vector Multiply-Sum & write Carry-out Unsigned
+			   Doubleword */
+    case 24:		/* Vector Extract Double Unsigned Byte to VSR
+			   using GPR-specified Left-Index */
+    case 25:		/* Vector Extract Double Unsigned Byte to VSR
+			   using GPR-specified Right-Index */
+    case 26:		/* Vector Extract Double Unsigned Halfword to VSR
+			   using GPR-specified Left-Index */
+    case 27:		/* Vector Extract Double Unsigned Halfword to VSR
+			   using GPR-specified Right-Index */
+    case 28:		/* Vector Extract Double Unsigned Word to VSR
+			   using GPR-specified Left-Index */
+    case 29:		/* Vector Extract Double Unsigned Word to VSR
+			   using GPR-specified Right-Index */
+    case 30:		/* Vector Extract Double Unsigned Doubleword to VSR
+			   using GPR-specified Left-Index */
+    case 31:		/* Vector Extract Double Unsigned Doubleword to VSR
+			   using GPR-specified Right-Index */
     case 42:		/* Vector Select */
     case 43:		/* Vector Permute */
     case 59:		/* Vector Permute Right-indexed */
+    case 22: 		/* Vector Shift
+			      Left  Double by Bit Immediate if insn[21] = 0
+			      Right Double by Bit Immediate if insn[21] = 1 */
     case 44:		/* Vector Shift Left Double by Octet Immediate */
     case 45:		/* Vector Permute and Exclusive-OR */
     case 60:		/* Vector Add Extended Unsigned Quadword Modulo */
@@ -4236,6 +4331,9 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
   /* Bit-21 is used for RC */
   switch (ext & 0x3ff)
     {
+    case 5:		/* Vector Rotate Left Quadword */
+    case 69:		/* Vector Rotate Left Quadword then Mask Insert */
+    case 325:		/* Vector Rotate Left Quadword then AND with Mask */
     case 6:		/* Vector Compare Equal To Unsigned Byte */
     case 70:		/* Vector Compare Equal To Unsigned Halfword */
     case 134:		/* Vector Compare Equal To Unsigned Word */
@@ -4244,13 +4342,16 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     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 903:		/* Vector Compare Greater Than Signed Quadword */
     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 647:		/* Vector Compare Greater Than Unsigned Quadword */
     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 455:		/* Vector Compare Equal Quadword */
     case 710:		/* Vector Compare Greater Than Single-Precision */
     case 7:		/* Vector Compare Not Equal Byte */
     case 71:		/* Vector Compare Not Equal Halfword */
@@ -4263,6 +4364,21 @@ 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 13:
+      switch (vra)    /* Bit-21 is used for RC */
+	{
+	case 0:       /* Vector String Isolate Byte Left-justified */
+	case 1:       /* Vector String Isolate Byte Right-justified */
+	case 2:       /* Vector String Isolate Halfword Left-justified */
+	case 3:       /* Vector String Isolate Halfword Right-justified */
+	  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;
+	}
     }
 
   if (ext  == 1538)
@@ -4287,6 +4403,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
 	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 27:	/* Vector Extend Sign Doubleword To Quadword */
 	case 28:	/* Vector Count Trailing Zeros Byte */
 	case 29:	/* Vector Count Trailing Zeros Halfword */
 	case 30:	/* Vector Count Trailing Zeros Word */
@@ -4297,8 +4414,57 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
 	}
     }
 
+  if (ext == 1602)
+    {
+      switch (vra)
+	{
+	case 0: 	/* Vector Expand Byte Mask */
+	case 1: 	/* Vector Expand Halfword Mask */
+	case 2: 	/* Vector Expand Word Mask */
+	case 3: 	/* Vector Expand Doubleword Mask */
+	case 4: 	/* Vector Expand Quadword Mask */
+	case 16:	/* Move to VSR Byte Mask */
+	case 17:	/* Move to VSR Halfword Mask */
+	case 18:	/* Move to VSR Word Mask */
+	case 19:	/* Move to VSR Doubleword Mask */
+	case 20:	/* Move to VSR Quadword Mask */
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+	  return 0;
+
+	case 8: 	/* Vector Extract Byte Mask */
+	case 9: 	/* Vector Extract Halfword Mask */
+	case 10: 	/* Vector Extract Word Mask */
+	case 11: 	/* Vector Extract Doubleword Mask */
+	case 12: 	/* Vector Extract Quadword Mask */
+
+	/* Ignore the MP bit in the LSB position of the vra value. */
+	case 24:	/* Vector Count Mask Bits Byte, MP = 0 */
+	case 25:	/* Vector Count Mask Bits Byte, MP = 1 */
+	case 26:	/* Vector Count Mask Bits Halfword, MP = 0 */
+	case 27:	/* Vector Count Mask Bits Halfword, MP = 1 */
+	case 28:	/* Vector Count Mask Bits Word, MP = 0 */
+	case 29:	/* Vector Count Mask Bits Word, MP = 1 */
+	case 30:	/* Vector Count Mask Bits Doubleword, MP = 0 */
+	case 31:	/* Vector Count Mask Bits Doubleword, MP = 1 */
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_gp0_regnum + PPC_RT (insn));
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_gp0_regnum + PPC_RT (insn));
+	  return 0;
+	}
+    }
+
   switch (ext)
     {
+
+    case 257:		/* Vector Compare Unsigned Quadword */
+    case 321:		/* Vector Compare Signed Quadword */
+      /* Comparison tests that always set CR field BF */
+      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;
+
     case 142:		/* Vector Pack Unsigned Halfword Unsigned Saturate */
     case 206:		/* Vector Pack Unsigned Word Unsigned Saturate */
     case 270:		/* Vector Pack Signed Halfword Unsigned Saturate */
@@ -4338,6 +4504,8 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 268:		/* Vector Merge Low Byte */
     case 332:		/* Vector Merge Low Halfword */
     case 396:		/* Vector Merge Low Word */
+    case 397:		/* Vector Clear Leftmost Bytes */
+    case 461:		/* Vector Clear Rightmost Bytes */
     case 526:		/* Vector Unpack High Signed Byte */
     case 590:		/* Vector Unpack High Signed Halfword */
     case 654:		/* Vector Unpack Low Signed Byte */
@@ -4356,8 +4524,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 780:		/* Vector Splat Immediate Signed Byte */
     case 844:		/* Vector Splat Immediate Signed Halfword */
     case 908:		/* Vector Splat Immediate Signed Word */
+    case 261:		/* Vector Shift Left Quadword */
     case 452:		/* Vector Shift Left */
+    case 517:		/* Vector Shift Right Quadword */
     case 708:		/* Vector Shift Right */
+    case 773:		/* Vector Shift Right Algebraic Quadword */
     case 1036:		/* Vector Shift Left by Octet */
     case 1100:		/* Vector Shift Right by Octet */
     case 0:		/* Vector Add Unsigned Byte Modulo */
@@ -4370,15 +4541,43 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 8:		/* Vector Multiply Odd Unsigned Byte */
     case 72:		/* Vector Multiply Odd Unsigned Halfword */
     case 136:		/* Vector Multiply Odd Unsigned Word */
+    case 200:		/* Vector Multiply Odd Unsigned Doubleword */
     case 264:		/* Vector Multiply Odd Signed Byte */
     case 328:		/* Vector Multiply Odd Signed Halfword */
     case 392:		/* Vector Multiply Odd Signed Word */
+    case 456:		/* Vector Multiply Odd Signed Doubleword */
     case 520:		/* Vector Multiply Even Unsigned Byte */
     case 584:		/* Vector Multiply Even Unsigned Halfword */
     case 648:		/* Vector Multiply Even Unsigned Word */
+    case 712:		/* Vector Multiply Even Unsigned Doubleword */
     case 776:		/* Vector Multiply Even Signed Byte */
     case 840:		/* Vector Multiply Even Signed Halfword */
     case 904:		/* Vector Multiply Even Signed Word */
+    case 968:		/* Vector Multiply Even Signed Doubleword */
+    case 457:		/* Vector Multiply Low Doubleword */
+    case 649:		/* Vector Multiply High Unsigned Word */
+    case 713:		/* Vector Multiply High Unsigned Doubleword */
+    case 905:		/* Vector Multiply High Signed Word */
+    case 969:		/* Vector Multiply High Signed Doubleword */
+    case 11:		/* Vector Divide Unsigned Quadword */
+    case 203:		/* Vector Divide Unsigned Doubleword */
+    case 139:		/* Vector Divide Unsigned Word */
+    case 267:		/* Vector Divide Signed Quadword */
+    case 459:		/* Vector Divide Signed Doubleword */
+    case 395:		/* Vector Divide Signed Word */
+    case 523:		/* Vector Divide Extended Unsigned Quadword */
+    case 715:		/* Vector Divide Extended Unsigned Doubleword */
+    case 651:		/* Vector Divide Extended Unsigned Word */
+    case 779:		/* Vector Divide Extended Signed Quadword */
+    case 971:		/* Vector Divide Extended Signed Doubleword */
+    case 907:		/* Vector Divide Extended Unsigned Word */
+    case 1547:		/* Vector Modulo Unsigned Quadword */
+    case 1675:		/* Vector Modulo Unsigned Word */
+    case 1739:		/* Vector Modulo Unsigned Doubleword */
+    case 1803:		/* Vector Modulo Signed Quadword */
+    case 1931:		/* Vector Modulo Signed Word */
+    case 1995:		/* Vector Modulo Signed Doubleword */
+
     case 137:		/* Vector Multiply Unsigned Word Modulo */
     case 1024:		/* Vector Subtract Unsigned Byte Modulo */
     case 1088:		/* Vector Subtract Unsigned Halfword Modulo */
@@ -4462,7 +4661,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 1794:		/* Vector Count Leading Zeros Byte */
     case 1858:		/* Vector Count Leading Zeros Halfword */
     case 1922:		/* Vector Count Leading Zeros Word */
+    case 1924:		/* Vector Count Leading Zeros Doubleword under
+			   bit Mask*/
     case 1986:		/* Vector Count Leading Zeros Doubleword */
+    case 1988:		/* Vector Count Trailing Zeros Doubleword under bit
+			   Mask */
     case 1795:		/* Vector Population Count Byte */
     case 1859:		/* Vector Population Count Halfword */
     case 1923:		/* Vector Population Count Word */
@@ -4488,14 +4691,50 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 589:		/* Vector Extract Unsigned Halfword */
     case 653:		/* Vector Extract Unsigned Word */
     case 717:		/* Vector Extract Doubleword */
+    case 15:		/* Vector Insert Byte from VSR using GPR-specified
+			   Left-Index */
+    case 79:		/* Vector Insert Halfword from VSR using GPR-specified
+			   Left-Index */
+    case 143:		/* Vector Insert Word from VSR using GPR-specified
+			   Left-Index */
+    case 207:		/* Vector Insert Word from GPR using
+			   immediate-specified index */
+    case 463:		/* Vector Insert Doubleword from GPR using
+			   immediate-specified index */
+    case 271:		/* Vector Insert Byte from VSR using GPR-specified
+			   Right-Index */
+    case 335:		/* Vector Insert Halfword from VSR using GPR-specified
+			   Right-Index */
+    case 399:		/* Vector Insert Word from VSR using GPR-specified
+			   Right-Index */
+    case 527:		/* Vector Insert Byte from GPR using GPR-specified
+			   Left-Index */
+    case 591:		/* Vector Insert Halfword from GPR using GPR-specified
+			   Left-Index */
+    case 655:		/* Vector Insert Word from GPR using GPR-specified
+			   Left-Index */
+    case 719:		/* Vector Insert Doubleword from GPR using
+			    GPR-specified Left-Index */
+    case 783:		/* Vector Insert Byte from GPR using GPR-specified
+			   Right-Index */
+    case 847:		/* Vector Insert Halfword from GPR using GPR-specified
+			   Left-Index */
+    case 911:		/* Vector Insert Word from GPR using GPR-specified
+			   Left-Index */
+    case 975:		/* Vector Insert Doubleword from GPR using
+			    GPR-specified Right-Index */
     case 781:		/* Vector Insert Byte */
     case 845:		/* Vector Insert Halfword */
     case 909:		/* Vector Insert Word */
     case 973:		/* Vector Insert Doubleword */
+    case 1357:		/* Vector Centrifuge Doubleword */
+    case 1421:		/* Vector Parallel Bits Extract Doubleword */
+    case 1485:		/* Vector Parallel Bits Deposit Doubleword */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
       return 0;
 
+    case 1228:		/* Vector Gather every Nth Bit */
     case 1549:		/* Vector Extract Unsigned Byte Left-Indexed */
     case 1613:		/* Vector Extract Unsigned Halfword Left-Indexed */
     case 1677:		/* Vector Extract Unsigned Word Left-Indexed */
@@ -4525,6 +4764,34 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record instructions of primary opcode 6 at ADDR.
+   Return 0 if successful.  */
+
+static int
+ppc_process_record_op6 (struct gdbarch *gdbarch, struct regcache *regcache,
+			CORE_ADDR addr, uint32_t insn)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int subtype = PPC_FIELD (insn, 28, 4);
+  CORE_ADDR ea = 0;
+
+  switch (subtype)
+    {
+    case 0:    /* Load VSX Vector Paired */
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
+      return 0;
+    case 1:    /* Store VSX Vector Paired */
+      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, 32);
+      return 0;
+    }
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-19 at ADDR.
    Return 0 if successful.  */
 
@@ -4577,6 +4844,30 @@ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record instructions of primary opcode-31 with the extended opcode
+   177.  The argument is the word instruction (insn).  Return 0 if successful.
+*/
+
+static int
+ppc_process_record_op31_177 (struct gdbarch *gdbarch,
+			     struct regcache *regcache,
+			     uint32_t insn)
+{
+  int RA_opcode = PPC_RA(insn);
+  int as = PPC_FIELD (insn, 6, 3);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  switch (RA_opcode)
+    {
+    case 0: 		/* VSX Move From Accumulator, xxmfacc */
+    case 1: 		/* VSX Move To Accumulator, xxmtacc */
+    case 3: 		/* VSX Set Accumulator to Zero, xxsetaccz */
+      ppc_record_ACC_fpscr (regcache, tdep, as, false);
+      return 0;
+    }
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-31 at ADDR.
    Return 0 if successful.  */
 
@@ -4586,7 +4877,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
-  int tmp, nr, nb, i;
+  int tmp, nr, nb = 0, i;
   CORE_ADDR at_dcsz, ea = 0;
   ULONGEST rb, ra, xer;
   int size = 0;
@@ -4677,6 +4968,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 371:		/* Move From Time Base [Phased-Out]  */
     case 309:		/* Load Doubleword Monitored Indexed  */
     case 128:		/* Set Boolean */
+    case 384:		/* Set Boolean Condition */
+    case 416:		/* Set Boolean Condition Reverse */
+    case 448:		/* Set Negative Boolean Condition */
+    case 480:		/* Set Negative Boolean Condition Reverse */
     case 755:		/* Deliver A Random Number */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_gp0_regnum + PPC_RT (insn));
@@ -4684,8 +4979,15 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 
     /* These only write to RA.  */
     case 51:		/* Move From VSR Doubleword */
+    case 59:		/* Count Leading Zeros Doubleword under bit Mask */
     case 115:		/* Move From VSR Word and Zero */
     case 122:		/* Population count bytes */
+    case 155:		/* Byte-Reverse Word */
+    case 156:		/* Parallel Bits Deposit Doubleword */
+    case 187:		/* Byte-Reverse Doubleword */
+    case 188:		/* Parallel Bits Extract Doubleword */
+    case 219:		/* Byte-Reverse Halfword */
+    case 220:		/* Centrifuge Doubleword */
     case 378:		/* Population count words */
     case 506:		/* Population count doublewords */
     case 154:		/* Parity Word */
@@ -4695,6 +4997,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 314:		/* Convert Binary Coded Decimal To Declets */
     case 508:		/* Compare bytes */
     case 307:		/* Move From VSR Lower Doubleword */
+    case 571:		/* Count Trailing Zeros Doubleword under bit Mask */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_gp0_regnum + PPC_RA (insn));
       return 0;
@@ -4819,6 +5122,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache, tmp + 1);
       return 0;
 
+    /* These write to destination register PPC_XT. */
     case 179:		/* Move To VSR Doubleword */
     case 211:		/* Move To VSR Word Algebraic */
     case 243:		/* Move To VSR Word and Zero */
@@ -4826,6 +5130,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     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 13:		/* Load VSX Vector Rightmost Byte Indexed */
+    case 45:		/* Load VSX Vector Rightmost Halfword Indexed */
+    case 77:		/* Load VSX Vector Rightmost Word Indexed */
+    case 109:		/* Load VSX Vector Rightmost Doubleword 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 */
@@ -4842,6 +5150,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
 
+    case 333:		/* Load VSX Vector Paired Indexed */
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn));
+      ppc_record_vsr (regcache, tdep, PPC_XTp (insn) + 1);
+      return 0;
+
     /* These write RA.  Update CR if RC is set.  */
     case 24:		/* Shift Left Word */
     case 26:		/* Count Leading Zeros Word */
@@ -5006,6 +5319,31 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_mem (ea, size);
       return 0;
 
+    case 141:		/* Store VSX Vector Rightmost Byte Indexed */
+    case 173:		/* Store VSX Vector Rightmost Halfword Indexed */
+    case 205:		/* Store VSX Vector Rightmost Word Indexed */
+    case 237:		/* Store VSX Vector Rightmost Doubleword Indexed */
+      switch(ext)
+	{
+	  case 141: nb = 1;
+	  break;
+	  case 173: nb = 2;
+	  break;
+	  case 205: nb = 4;
+	  break;
+	  case 237: nb = 8;
+	  break;
+	}
+      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;
+      record_full_arch_list_add_mem (ea, nb);
+      return 0;
+
     case 397:		/* Store VSX Vector with Length */
     case 429:		/* Store VSX Vector Left-justified with Length */
       ra = 0;
@@ -5021,6 +5359,19 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 	record_full_arch_list_add_mem (ea, nb);
       return 0;
 
+    case 461:		/* Store VSX Vector Paired Indexed */
+      {
+	if (PPC_RA (insn) != 0)
+	  regcache_raw_read_unsigned (regcache,
+				      tdep->ppc_gp0_regnum
+				      + PPC_RA (insn), &ea);
+	regcache_raw_read_unsigned (regcache,
+				    tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
+	ea += rb;
+	record_full_arch_list_add_mem (ea, 32);
+	return 0;
+      }
+
     case 710:		/* Store Word Atomic */
     case 742:		/* Store Doubleword Atomic */
       ra = 0;
@@ -5166,6 +5517,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       ea = (ra + rb) & ~((ULONGEST) (at_dcsz - 1));
       record_full_arch_list_add_mem (ea, at_dcsz);
       return 0;
+
+    case 177:
+      if (ppc_process_record_op31_177 (gdbarch, regcache, insn) == 0)
+	return 0;
     }
 
 UNKNOWN_OP:
@@ -5179,10 +5534,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 
 static int
 ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
-			   CORE_ADDR addr, uint32_t insn)
+			 CORE_ADDR addr, uint32_t insn)
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
+  int at = PPC_FIELD (insn, 6, 3);
 
   switch (ext & 0x1f)
     {
@@ -5206,6 +5562,75 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
+  /* MMA instructions, keep looking.  */
+  switch (ext >> 2)    /* Additional opcode field is upper 8-bits of ext */
+    {
+    case 3:	/* VSX Vector 8-bit Signed/Unsigned Integer GER, xvi8ger4 */
+    case 2:	/* VSX Vector 8-bit Signed/Unsigned Integer GER Positive
+		   multiply, Positive accumulate, xvi8ger4pp */
+
+    case 99:	/* VSX Vector 8-bit Signed/Unsigned Integer GER with
+		   Saturate Positive multiply, Positive accumulate,
+		   xvi8ger4spp */
+
+    case 35:	/* VSX Vector 4-bit Signed Integer GER, xvi4ger8 */
+    case 34:	/* VSX Vector 4-bit Signed Integer GER Positive multiply,
+		   Positive accumulate, xvi4ger8pp */
+
+    case 75:	/* VSX Vector 16-bit Signed Integer GER, xvi16ger2 */
+    case 107:	/* VSX Vector 16-bit Signed Integer GER  Positive multiply,
+		   Positive accumulate, xvi16ger2pp */
+
+    case 43:	/* VSX Vector 16-bit Signed Integer GER with Saturation,
+		   xvi16ger2s */
+    case 42:	/* VSX Vector 16-bit Signed Integer GER with Saturation
+		   Positive multiply, Positive accumulate, xvi16ger2spp */
+      ppc_record_ACC_fpscr (regcache, tdep, at, false);
+      return 0;
+
+    case 19:	/* VSX Vector 16-bit Floating-Point GER, xvf16ger2 */
+    case 18:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf16ger2pp */
+    case 146:	/* VSX Vector 16-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf16ger2pn */
+    case 82:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf16ger2np */
+    case 210:	/* VSX Vector 16-bit Floating-Point GER Negative multiply,
+		   Negative accumulate, xvf16ger2nn */
+
+    case 27:	/* VSX Vector 32-bit Floating-Point GER, xvf32ger */
+    case 26:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf32gerpp */
+    case 154:	/* VSX Vector 32-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf32gerpn */
+    case 90:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf32gernp */
+    case 218:	/* VSX Vector 32-bit Floating-Point GER Negative multiply,
+		   Negative accumulate, xvf32gernn */
+
+    case 59:	/* VSX Vector 64-bit Floating-Point GER, pmxvf64ger */
+    case 58:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
+		   Positive accumulate, xvf64gerpp */
+    case 186:	/* VSX Vector 64-bit Floating-Point GER Positive multiply,
+		   Negative accumulate, xvf64gerpn */
+    case 122:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
+		   Positive accumulate, xvf64gernp */
+    case 250:	/* VSX Vector 64-bit Floating-Point GER Negative multiply,
+		   Negative accumulate, pmxvf64gernn */
+
+    case 51:	/* VSX Vector bfloat16 GER, xvbf16ger2 */
+    case 50:	/* VSX Vector bfloat16 GER Positive multiply,
+		   Positive accumulate, xvbf16ger2pp */
+    case 178:	/* VSX Vector bfloat16 GER Positive multiply,
+		   Negative accumulate, xvbf16ger2pn */
+    case 114:	/* VSX Vector bfloat16 GER Negative multiply,
+		   Positive accumulate, xvbf16ger2np */
+    case 242:	/* VSX Vector bfloat16 GER Negative multiply,
+		   Negative accumulate, xvbf16ger2nn */
+      ppc_record_ACC_fpscr (regcache, tdep, at, true);
+      return 0;
+    }
+
   switch (ext)
     {
     case 2:		/* DFP Add */
@@ -5268,6 +5693,48 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record an XX2-Form instruction with opcode 60 at ADDR.  The
+   word instruction is an argument insn.  Return 0 if successful.  */
+
+static int
+ppc_process_record_op60_XX2 (struct gdbarch *gdbarch,
+			     struct regcache *regcache,
+			     CORE_ADDR addr, uint32_t insn)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int RA_opcode = PPC_RA(insn);
+
+  switch (RA_opcode)
+    {
+    case 2:	/* VSX Vector Test Least-Significant Bit by Byte */
+    case 25:	/* VSX Vector round and Convert Single-Precision format
+		   to Half-Precision format.  Only changes the CR
+		   field.  */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+    case 17:	/* VSX Vector Convert with round Single-Precision
+		   to bfloat16 format */
+    case 24:	/* VSX Vector Convert Half-Precision format to
+		   Single-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 16:	/* VSX Vector Convert bfloat16 to Single-Precision
+		   format Non-signaling */
+    case 23:	/* VSX Vector Byte-Reverse Doubleword */
+    case 31:	/* VSX Vector Byte-Reverse Quadword */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
+    }
+
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-60 at ADDR.
    Return 0 if successful.  */
 
@@ -5583,37 +6050,30 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
       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;
+      if (ppc_process_record_op60_XX2 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      return 0;
     }
 
   switch (ext)
     {
-    case 360:		/* VSX Vector Splat Immediate Byte */
-      if (PPC_FIELD (insn, 11, 2) == 0)
+    case 360:
+      if (PPC_FIELD (insn, 11, 2) == 0)  /* VSX Vector Splat Immediate Byte */
+	{
+	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+	  return 0;
+	}
+      if (PPC_FIELD (insn, 11, 5) == 31)  /* Load VSX Vector Special Value
+					     Quadword */
 	{
 	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
 	  return 0;
 	}
       break;
+    case 916:		/* VSX Vector Generate PCV from Byte Mask */
+    case 917:		/* VSX Vector Generate PCV from Halfword Mask */
+    case 948:		/* VSX Vector Generate PCV from Word Mask */
+    case 949:		/* VSX Vector Generate PCV from Doubleword Mask */
     case 918:		/* VSX Scalar Insert Exponent Double-Precision */
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
@@ -5894,6 +6354,35 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
 			   Quad-Precision */
     case 516:		/* VSX Scalar Subtract Quad-Precision */
     case 548:		/* VSX Scalar Divide Quad-Precision */
+    case 994:
+      {
+      switch (PPC_FIELD (insn, 11, 5))
+	{
+	case 0:	/* DFP Convert From Fixed Quadword Quad */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_fp0_regnum
+					 + PPC_FRT (insn));
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_fp0_regnum
+					 + PPC_FRT (insn) + 1);
+	  return 0;
+	case 1:	/* DFP Convert To Fixed Quadword Quad */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+	  return 0;
+	}
+      }
+
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
+    case 68:		/* VSX Scalar Compare Equal Quad-Precision */
+    case 196:		/* VSX Scalar Compare Greater Than or Equal
+			   Quad-Precision */
+    case 228:		/* VSX Scalar Compare Greater Than Quad-Precision */
+    case 676:		/* VSX Scalar Maximum Type-C Quad-Precision */
+    case 740:		/* VSX Scalar Minimum Type-C Quad-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       /* FALL-THROUGH */
     case 100:		/* VSX Scalar Copy Sign Quad-Precision */
@@ -5920,14 +6409,22 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 836:
       switch (PPC_FIELD (insn, 11, 5))
 	{
+	case 0:		/* VSX Scalar Convert with round to zero
+			   Quad-Precision to Unsigned Quadword  */
 	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 3:		/* VSX Scalar Convert with round
+			   Unsigned Quadword to Quad-Precision  */
+	case 8:		/* VSX Scalar Convert with round to zero
+			   Quad-Precision to Signed Quadword  */
 	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 11:	/* VSX Scalar Convert with round
+			   Signed Quadword to Quad-Precision */
 	case 17:	/* VSX Scalar truncate & Convert Quad-Precision format
 			   to Unsigned Doubleword format */
 	case 20:	/* VSX Scalar round & Convert Quad-Precision format to
@@ -5947,17 +6444,651 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Record the prefixed instructions with primary opcode 32.  The arguments are
+   the first 32-bits of the instruction (insn_prefix), and the second 32-bits
+   of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op42 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if (ST1 != 0)
+    return -1;
+
+  switch (type)
+    {
+    case 0:  /* Prefixed Load VSX Scalar Doubleword, plxsd */
+      ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
+      break;
+    case 2:  /* Prefixed Load Halfword Algebraic, plha */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum
+				     + PPC_RT (insn_suffix));
+      break;
+    default:
+      return -1;
+    }
+  return 0;
+}
+
+/* Record the prefixed XX3-Form instructions with primary opcode 59.  The
+   arguments are the first 32-bits of the instruction (insn_prefix), and the
+   second 32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op59_XX3 (struct gdbarch *gdbarch,
+				    struct regcache *regcache,
+				    uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int opcode = PPC_FIELD (insn_suffix, 21, 8);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  int at = PPC_FIELD (insn_suffix, 6, 3);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 3)
+    {
+      if (ST4 == 9)
+	switch (opcode)
+	  {
+	  case 35:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
+			   MMIRR, pmxvi4ger8 */
+	  case 34:	/* Prefixed Masked VSX Vector 4-bit Signed Integer GER
+			   MMIRR, pmxvi4ger8pp */
+
+	  case 99:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER with Saturate Positive multiply,
+			   Positive accumulate, xvi8ger4spp */
+
+	  case 3:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER MMIRR, pmxvi8ger4 */
+	  case 2:	/* Prefixed Masked VSX Vector 8-bit Signed/Unsigned
+			   Integer GER Positive multiply, Positive accumulate
+			   MMIRR, pmxvi8ger4pp */
+
+	  case 75:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER MMIRR, pmxvi16ger2 */
+	  case 107:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER  Positive multiply, Positive accumulate,
+			   pmxvi16ger2pp */
+
+	  case 43:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER with Saturation MMIRR, pmxvi16ger2s */
+	  case 42:	/* Prefixed Masked VSX Vector 16-bit Signed Integer
+			   GER with Saturation Positive multiply, Positive
+			   accumulate MMIRR, pmxvi16ger2spp */
+	    ppc_record_ACC_fpscr (regcache, tdep, at, false);
+	    return 0;
+
+	  case 19:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER MMIRR, pmxvf16ger2 */
+	  case 18:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Positive multiply, Positive accumulate MMIRR,
+			   pmxvf16ger2pp */
+	  case 146:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf16ger2pn */
+	  case 82:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf16ger2np */
+	  case 210:	/* Prefixed Masked VSX Vector 16-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf16ger2nn */
+
+	  case 27:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER MMIRR, pmxvf32ger */
+	  case 26:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Positive multiply, Positive accumulate MMIRR,
+			   pmxvf32gerpp */
+	  case 154:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf32gerpn */
+	  case 90:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf32gernp */
+	  case 218:	/* Prefixed Masked VSX Vector 32-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf32gernn */
+
+	  case 59:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER MMIRR, pmxvf64ger */
+	  case 58:	/* Floating-Point GER Positive multiply, Positive
+			   accumulate MMIRR, pmxvf64gerpp */
+	  case 186:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Positive multiply, Negative accumulate MMIRR,
+			   pmxvf64gerpn */
+	  case 122:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Negative multiply, Positive accumulate MMIRR,
+			   pmxvf64gernp */
+	  case 250:	/* Prefixed Masked VSX Vector 64-bit Floating-Point
+			   GER Negative multiply, Negative accumulate MMIRR,
+			   pmxvf64gernn */
+
+	  case 51:	/* Prefixed Masked VSX Vector bfloat16 GER MMIRR,
+			   pmxvbf16ger2 */
+	  case 50:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
+			   multiply, Positive accumulate MMIRR,
+			   pmxvbf16ger2pp */
+	  case 178:	/* Prefixed Masked VSX Vector bfloat16 GER Positive
+			   multiply, Negative accumulate MMIRR,
+			   pmxvbf16ger2pn */
+	  case 114:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
+			   multiply, Positive accumulate MMIRR,
+			   pmxvbf16ger2np */
+	  case 242:	/* Prefixed Masked VSX Vector bfloat16 GER Negative
+			   multiply, Negative accumulate MMIRR,
+			   pmxvbf16ger2nn */
+	    ppc_record_ACC_fpscr (regcache, tdep, at, true);
+	    return 0;
+	  }
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed store instructions.  The arguments are the instruction
+   address, the first 32-bits of the instruction(insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_store (struct gdbarch *gdbarch,
+				 struct regcache *regcache,
+				 CORE_ADDR addr, uint32_t insn_prefix,
+				 uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST iaddr = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int op6 = PPC_OP6 (insn_suffix);
+
+  if (R == 0)
+    {
+      if (PPC_RA (insn_suffix) != 0)
+	regcache_raw_read_unsigned (regcache, tdep->ppc_gp0_regnum
+				    + PPC_RA (insn_suffix), &iaddr);
+    }
+  else
+    {
+      iaddr = addr;     /* PC relative */
+    }
+
+  switch (op6)
+    {
+    case 38:
+      size =  1;    /* store byte, pstb */
+      break;
+    case 44:
+      size =  2;    /* store halfword, psth */
+      break;
+    case 36:
+    case 52:
+      size =  4;    /* store word, pstw, pstfs */
+      break;
+    case 54:
+    case 61:
+      size =  8;    /* store double word, pstd, pstfd */
+      break;
+    case 60:
+      size = 16;    /* store quadword, pstq */
+      break;
+    default: return -1;
+    }
+
+  iaddr += P_PPC_D (insn_prefix, insn_suffix);
+  record_full_arch_list_add_mem (iaddr, size);
+  return 0;
+}
+
+/* Record the prefixed instructions with primary op code 32.  The arguments
+   are the first 32-bits of the instruction (insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op32 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1)
+    {
+      if (ST4 == 0)
+	{
+	  switch (PPC_FIELD (insn_suffix, 11, 3))
+	    {
+	    case 0:  	/* VSX Vector Splat Immediate Word 8RR, xxsplti32dx */
+	      ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
+	      return 0;
+	    }
+
+	  switch (PPC_FIELD (insn_suffix, 11, 4))
+	    {
+	    case 2:  	/* VSX Vector Splat Immediate Double-Precision
+			   8RR, xxspltidp */
+	    case 3:  	/* VSX Vector Splat Immediate Word 8RR, xxspltiw */
+	      ppc_record_vsr (regcache, tdep, P_PPC_XT15 (insn_suffix));
+	      return 0;
+	    default:
+	      return -1;
+	    }
+	}
+      else
+	return -1;
+
+    }
+  else if (type == 2)
+    {
+      if (ST1 == 0)  		/* Prefixed Load Word and Zero, plwz */
+	record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	return -1;
+
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed instructions with primary op code 33.  The arguments
+   are the first 32-bits of the instruction(insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op33 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1)
+    {
+      if (ST4 == 0)
+	switch (PPC_FIELD (insn_suffix, 26, 2))
+	  {
+	  case 0:  	/* VSX Vector Blend Variable Byte 8RR, xxblendvb */
+	  case 1:  	/* VSX Vector Blend Variable Halfword, xxblendvh */
+	  case 2:  	/* VSX Vector Blend Variable Word, xxblendvw */
+	  case 3:  	/* VSX Vector Blend Variable Doubleword, xxblendvd */
+	    ppc_record_vsr (regcache, tdep, PPC_XT (insn_suffix));
+	  break;
+	  default:
+	    return -1;
+	  }
+      else
+	return -1;
+
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed instructions with primary op code 34.  The arguments
+   are the first 32-bits of the instruction(insn_prefix) and the following
+   32-bits of the instruction (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_op34 (struct gdbarch *gdbarch,
+				struct regcache *regcache,
+				uint32_t insn_prefix, uint32_t insn_suffix)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  int ST4 = PPC_FIELD (insn_prefix, 8, 4);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+  if (type == 1)
+    {
+      if (ST4 == 0)
+	switch (PPC_FIELD (insn_suffix, 26, 2))
+	  {
+	  case 0:  	/* VSX Vector Permute Extended 8RR, xxpermx */
+	  case 1:  	/* VSX Vector Evaluate 8RR, xxeval */
+	    ppc_record_vsr (regcache, tdep, P_PPC_XT (insn_suffix));
+	    break;
+	  default:
+	    return -1;
+	  }
+      else
+	return -1;
+
+    }
+  else if (type == 2)
+    {
+      if (ST1 == 0)  		/* Prefixed Load Word and Zero, plbz */
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	return -1;
+
+    }
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Record the prefixed VSX store, form DS, instructions.  The arguments are the
+   instruction address (addr), the first 32-bits of the instruction
+   (insn_prefix) followed by the 32-bit instruction suffix (insn_suffix).
+   Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_store_vsx_ds_form (struct gdbarch *gdbarch,
+					     struct regcache *regcache,
+					     CORE_ADDR addr,
+					     uint32_t insn_prefix,
+					     uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST ea = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if ((type == 0) && (ST1 == 0))
+    {
+      if (R == 0)
+	{
+	  if (PPC_RA (insn_suffix) != 0)
+	    regcache_raw_read_unsigned (regcache,
+					tdep->ppc_gp0_regnum
+					+ PPC_RA (insn_suffix),
+					&ea);
+	}
+      else
+	{
+	  ea = addr;     /* PC relative */
+	}
+
+      ea += P_PPC_D (insn_prefix, insn_suffix);
+      switch (PPC_FIELD (insn_suffix, 0, 6))
+	{
+	case 46:    /* Prefixed Store VSX Scalar Doubleword, pstxsd */
+	  size = 8;
+	  break;
+	case 47:    /* Prefixed,Store VSX Scalar Single-Precision, pstxssp */
+	  size = 4;
+	  break;
+	default:
+	  return -1;
+	}
+      record_full_arch_list_add_mem (ea, size);
+      return 0;
+  }
+  else
+    return -1;
+}
+
+/* Record the prefixed VSX, form D, instructions.  The arguments are the
+   instruction address for PC-relative addresss (addr), the first 32-bits of
+   the instruction (insn_prefix) and the following 32-bits of the instruction
+   (insn_suffix).  Return 0 on success.  */
+
+static int
+ppc_process_record_prefix_vsx_d_form (struct gdbarch *gdbarch,
+				      struct regcache *regcache,
+				      CORE_ADDR addr,
+				      uint32_t insn_prefix,
+				      uint32_t insn_suffix)
+{
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  ULONGEST ea = 0;
+  int size;
+  int R = PPC_BIT (insn_prefix, 11);
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+
+  if ((type == 0) && (ST1 == 0))
+    {
+      switch (PPC_FIELD (insn_suffix, 0, 5))
+	{
+	case 25:	/* Prefixed Load VSX Vector, plxv */
+	  ppc_record_vsr (regcache, tdep, P_PPC_XT5 (insn_prefix));
+	  return 0;
+	case 27:	/* Prefixed Store VSX Vector 8LS, pstxv */
+	  {
+	    size = 16;
+	    if (R == 0)
+	      {
+		if (PPC_RA (insn_suffix) != 0)
+		  regcache_raw_read_unsigned (regcache,
+					      tdep->ppc_gp0_regnum
+					      + PPC_RA (insn_suffix),
+					      &ea);
+	      }
+	    else
+	      {
+		ea = addr;     /* PC relative */
+	      }
+
+	    ea += P_PPC_D (insn_prefix, insn_suffix);
+	    record_full_arch_list_add_mem (ea, size);
+	    return 0;
+	  }
+	}
+      return -1;
+    }
+  else
+    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.  */
 
+/* This handles the recording of the various prefix instructions.  It takes
+   the instruction address, the first 32-bits of the instruction (insn_prefix)
+   and the following 32-bits of the instruction (insn_suffix).  Return 0 on
+   success.  */
+
+static int
+ppc_process_prefix_instruction (int insn_prefix, int insn_suffix,
+				CORE_ADDR addr,	struct gdbarch *gdbarch,
+				struct regcache *regcache)
+{
+  int type = PPC_FIELD (insn_prefix, 6, 2);
+  int ST1 = PPC_FIELD (insn_prefix, 8, 1);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int op6;
+
+  /* D-form has uses a 5-bit opcode in the instruction suffix */
+  if (ppc_process_record_prefix_vsx_d_form ( gdbarch, regcache, addr,
+					     insn_prefix, insn_suffix) == 0)
+    goto SUCCESS;
+
+  op6 = PPC_OP6 (insn_suffix);  /* 6-bit opcode in the instruction suffix */
+
+  switch (op6)
+    {
+    case 14:		/* Prefixed Add Immediate, paddi */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 32:
+      if (ppc_process_record_prefix_op32 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 33:
+      if (ppc_process_record_prefix_op33 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 34:		/* Prefixed Load Byte and Zero, plbz */
+      if (ppc_process_record_prefix_op34 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+    case 40:		/* Prefixed Load Halfword and Zero, plhz */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+      break;
+
+    case 36:		/* Prefixed Store Word, pstw */
+    case 38:		/* Prefixed Store Byte, pstb */
+    case 44:		/* Prefixed Store Halfword, psth */
+    case 52:		/* Prefixed Store Floating-Point Single, pstfs */
+    case 54:		/* Prefixed Store Floating-Point Double, pstfd */
+    case 60:		/* Prefixed Store Quadword, pstq */
+    case 61:		/* Prefixed Store Doubleword, pstd */
+      if (ppc_process_record_prefix_store (gdbarch, regcache, addr,
+					   insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 42:
+      if (ppc_process_record_prefix_op42 (gdbarch, regcache,
+					  insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 43:          /* Prefixed Load VSX Scalar Single-Precision, plxssp */
+      if ((type == 0) && (ST1 == 0))
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn_suffix) + 32);
+      else
+	  goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 46:
+    case 47:
+      if (ppc_process_record_prefix_store_vsx_ds_form (gdbarch, regcache, addr,
+					       insn_prefix, insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 56:		/* Prefixed Load Quadword, plq */
+      {
+	if ((type == 0) && (ST1 == 0))
+	  {
+	    int tmp;
+	    tmp = tdep->ppc_gp0_regnum + (PPC_RT (insn_suffix) & ~1);
+	    record_full_arch_list_add_reg (regcache, tmp);
+	    record_full_arch_list_add_reg (regcache, tmp + 1);
+	  }
+	else
+	  goto UNKNOWN_PREFIX_OP;
+	break;
+      }
+
+    case 41:		/* Prefixed Load Word Algebraic, plwa */
+    case 57:  		/* Prefixed Load Doubleword, pld */
+      if ((type == 0) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_gp0_regnum
+				       + PPC_RT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 48:		/* Prefixed Load Floating-Point Single, plfs */
+    case 50:		/* Prefixed Load Floating-Point Double, plfd */
+      if ((type == 2) && (ST1 == 0))
+	record_full_arch_list_add_reg (regcache,
+				       tdep->ppc_fp0_regnum
+				       + PPC_FRT (insn_suffix));
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 58:		/* Prefixed Load VSX Vector Paired, plxvp */
+      if ((type == 0) && (ST1 == 0))
+	{
+	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix));
+	  ppc_record_vsr (regcache, tdep, PPC_XTp (insn_suffix) + 1);
+	}
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 59:
+      if (ppc_process_record_prefix_op59_XX3 (gdbarch, regcache, insn_prefix,
+					      insn_suffix) != 0)
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    case 62:	    /* Prefixed Store VSX Vector Paired 8LS, pstxvp */
+      if ((type == 0) && (ST1 == 0))
+	{
+	  int R = PPC_BIT (insn_prefix, 11);
+	  CORE_ADDR ea = 0;
+
+	  if (R == 0)
+	    {
+	      if (PPC_RA (insn_suffix) != 0)
+		regcache_raw_read_unsigned (regcache,
+					    tdep->ppc_gp0_regnum
+					    + PPC_RA (insn_suffix), &ea);
+	    }
+	  else
+	    {
+	      ea = addr;     /* PC relative */
+	    }
+
+	  ea += P_PPC_D (insn_prefix, insn_suffix) << 4;
+	  record_full_arch_list_add_mem (ea, 32);
+	}
+      else
+	goto UNKNOWN_PREFIX_OP;
+      break;
+
+    default:
+UNKNOWN_PREFIX_OP:
+      gdb_printf (gdb_stdlog,
+		  "Warning: Don't know how to record prefix instruction "
+		  "%08x %08x at %s, %d.\n",
+		  insn_prefix, insn_suffix, paddress (gdbarch, addr),
+		  op6);
+      return -1;
+    }
+
+ SUCCESS:
+  if (record_full_arch_list_add_reg (regcache, PPC_PC_REGNUM))
+    return -1;
+
+  if (record_full_arch_list_add_end ())
+    return -1;
+  return 0;
+}
+
 int
 ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 		      CORE_ADDR addr)
 {
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  uint32_t insn;
+  uint32_t insn, insn_suffix;
   int op6, tmp, i;
 
   insn = read_memory_unsigned_integer (addr, 4, byte_order);
@@ -5965,16 +7096,28 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 
   switch (op6)
     {
+    case 1:		/* prefixed instruction */
+      {
+	/* Get the lower 32-bits of the prefixed instruction. */
+	insn_suffix = read_memory_unsigned_integer (addr+4, 4, byte_order);
+	return ppc_process_prefix_instruction (insn, insn_suffix, addr,
+					       gdbarch, regcache);
+      }
     case 2:		/* Trap Doubleword Immediate */
     case 3:		/* Trap Word Immediate */
       /* Do nothing.  */
       break;
 
-    case 4:
+    case 4:             /* Vector Integer, Compare, Logical, Shift, etc.  */
       if (ppc_process_record_op4 (gdbarch, regcache, addr, insn) != 0)
 	return -1;
       break;
 
+    case 6:             /* Vector Load and Store */
+      if (ppc_process_record_op6 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      break;
+
     case 17:		/* System call */
       if (PPC_LEV (insn) != 0)
 	goto UNKNOWN_OP;
-- 
2.31.1





^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/2  Version 6] Add recording support for the ISA 3.1 Powerpc instructions
  2022-04-25 15:58                 ` [PATCH 1/2 Version 6] " Carl Love
@ 2022-04-26 18:05                   ` Joel Brobecker
  0 siblings, 0 replies; 25+ messages in thread
From: Joel Brobecker @ 2022-04-26 18:05 UTC (permalink / raw)
  To: Carl Love
  Cc: Joel Brobecker, will schmidt, gdb-patches, Ulrich Weigand,
	Tulio Magno, Rogerio Alves

> Thanks for the additional comments.  Given that we are not under any
> timeline to get this patch done and the changes are very minor I think
> it is better to just get it right the first time rather than have to
> come back ad fix it up later.  The changes are all localized as well.

That's a great attitude to have.

For large patches, it can have a bit of a perverse effect, though,
which is related to how code review is done for GDB (email-based).
So, to review a new iteration of a patch I already reviewed before,
when the patch is large, I tend to go fish in the archives the
previous iteration, and do a diff between previous and new. Easy
enough, but it requires a bit of time to do so. If I trust a person
enough to follow up, or when things are very minor, I tend to let
the patch through, and ask that the corrections be done as a followup
patch. It's true that this means two patches instead of one, so this
could be seen as a real downside -- but the upside is that the minor
updates are sent for review on their own, and very often, reviewing
just that update patch will be trivial, and therefore the chances
of it being reviewed are much higher in my experience.

I was able to take a bit of time today to review the new version,
though, and this version looks good to me. So you can go ahead
and push to master.

Thanks again.

> I have made the changes to the header comment for the function
> ppc_record_ACC_fpscr() to clairfy what the function does as well as to
> use the capitalization to indicate the value.  The parameter "at" was
> also changed to "entry" to make it clearer we are selecting one of the
> possible AT entries to be recorded.  Finally, argument save_fpscr was
> changed to a boolean thus eliminating the #defines for RECORD_FPSCR and
> DO_NOT_RECORD_FPSCR.  Fortunately, the changes are all at the beginning
> of the patch making it easy to find.
> 
> As always, the patch was retested to make sure I didn't break anything.
> Please let me know if the additional changes are acceptable.  Thanks.
-- 
Joel

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2022-04-26 18:05 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-04 19:46 [PATCH 0/2] Add recording support for the ISA 3.1 Powerpc instructions Carl Love
2022-03-04 19:52 ` [PATCH 1/2] " Carl Love
2022-03-06 11:53   ` Joel Brobecker
2022-04-12 17:09     ` [PATCH 1/2 Version 2] " Carl Love
2022-04-12 21:50       ` will schmidt
2022-04-13 17:26         ` [PATCH 1/2 Version 3] " Carl Love
2022-04-17 16:23           ` Joel Brobecker
2022-04-18 19:21             ` [PATCH 1/2 Version 5] " Carl Love
2022-04-22 19:49               ` [PATCH 1/2 Version 5 Ping] " Carl Love
2022-04-24 16:50               ` [PATCH 1/2 Version 5] " Joel Brobecker
2022-04-25 15:58                 ` [PATCH 1/2 Version 6] " Carl Love
2022-04-26 18:05                   ` Joel Brobecker
2022-03-04 19:53 ` [PATCH 2/2] " Carl Love
2022-03-06 12:42   ` Joel Brobecker
2022-04-12 17:09     ` [PATCH 2/2 Version 2] " Carl Love
2022-04-13 14:12       ` will schmidt
2022-04-13 21:38         ` [PATCH 2/2 Version 3] " Carl Love
2022-04-14 13:05           ` Pedro Alves
2022-04-14 20:20             ` [PATCH 2/2 Version 4] " Carl Love
2022-04-14 20:43               ` Carl Love
2022-04-17 16:48                 ` Joel Brobecker
2022-04-18 19:21                   ` [PATCH 2/2 Version 5] " Carl Love
2022-04-22 19:47                     ` [PATCH 2/2 Version 5 PING] " Carl Love
2022-04-24 16:56                     ` [PATCH 2/2 Version 5] " Joel Brobecker
2022-04-12 17:09 ` [PATCH 0/2 Version 2] " Carl Love

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).