This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] ppc: Add Power ISA 3.0/POWER9 instructions record support


Hi Uli,

first, thanks for the review. I've talked to the kernel developers and
reworked the patch.

On 09/20/2016 12:06 PM, Ulrich Weigand wrote:
> Edjunior Barbosa Machado wrote:
> 
>> +  switch(ext & 0x01f)
> Space before '('.
Done.

>> +    {
>> +    case 2:		/* Add PC Immediate Shifted */
> 
>> +    case 82:		/* Return From System Call Vectored */
>> +      record_full_arch_list_add_reg (regcache, tdep->ppc_ps_regnum);
>> +      return 0;
> This is a privileged instruction, which we don't need to track here.
> 
Removed.

>> +    case 370:		/* Stop */
>>       /* Do nothing.  */
> Likewise.
> 
Removed.

>> +    case 890:		/* Extend-Sign Word and Shift Left Immediate (445) */
>> +    case 890 | 1:	/* Extend-Sign Word and Shift Left Immediate (445) */
>> +      if (PPC_RC (insn))
>> +	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
>> +      /* FALL-THROUGH */
>>     /* These only write to RA.  */
> Move the above down the block starting with
>       /* These write RA.  Update CR if RC is set.  */
> 
Moved.

>> +    case 902:		/* Paste */
> This one is a bit interesting, since according to the ISA, the update of
> the memory block happens asyncroneously.   But I guess by the time the
> debugger gets involved, this will probably have happened ...
> 

According to the kernel devs, copy/paste should indeed fail (cp_abort)
due to context switching with gdb. paste instruction should also fail
and, as we discussed previously, the memory location might not even be
accessible by gdb, so we'll just save the CR register.

>> +    case 397:		/* Store VSX Vector with Length */
>> +    case 429:		/* Store VSX Vector Left-justified with Length */
>> +      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);
>> +      nb = rb & 0xff;
>> +      if (nb != 0)
>> +	record_full_arch_list_add_mem (ea, nb);
> If I'm reading the ISA correctly, there are never more than 16 bytes stored.
> 
Fixed.

>> +    case 774:		/* Copy */
>> +    case 838:		/* CP_Abort */
> These are also interesting.  They manipulate the state of the internal 128-byte
> copy/paste buffer, so in order to reverse past those instructions, we'd
> really have to restore that state.  But I don't think this is even possible
> with current kernel support (or even hardware support)?  You should verify
> with kernel people what to do about this.  (In fact, maybe even single-
> stepping across a copy will not work correctly since the single-step
> intercept kernel entry point may call cp_abort ...)
> 
Mentioned above.

>> +    case 27:      /* VSX Scalar Compare Not Equal Double-Precision */
> This was removed from the final ISA 3.0B.
> 
Removed.

>> +    case 91:      /* VSX Vector Compare Not Equal Single-Precision */
>> +    case 123:      /* VSX Vector Compare Not Equal Double-Precision */
> Those were removed from the final ISA 3.0B as well.
> 
Removed.

>> +    case 347:
>> +      switch (PPC_FIELD(insn, 11, 5))
> Space before '('.
> 
Fixed.

>> +    case 475:
>> +      switch (PPC_FIELD(insn, 11, 5))
> Space before '('.
> 
Fixed.

>> +    case 804:
>> +      switch (PPC_FIELD(insn, 11, 5))
> Space before '('.
> 
Fixed.

>> +	{
>> +	case 0:		/* VSX Scalar Absolute Quad-Precision */
>> +	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
> This actually uses PPC_VRT (insn) + 32, just like the others.
> 
Fixed.

>> +    case 836:
>> +      switch (PPC_FIELD(insn, 11, 5))
> Space before '('.
> 
Fixed.

>>     case 17:		/* System call */
>> -      if (PPC_LEV (insn) != 0)
>> +			/* System Call Vectored */
>> +      if ((PPC_LEV (insn) != 0) && ((insn & 0x2) != 2)  && ((insn & 0x3) != 1))
>> 	goto UNKNOWN_OP;
>>
>>       if (tdep->ppc_syscall_record != NULL)
> I think Linux doesn't support using scv in user space -- you should check
> with the kernel folks.  If it doesn't, process record shouldn't accept it.
> But if it actually *does* support scv, then you'll have to update the
> syscall_record callback to describe how it is used.  For one, with scv
> the restriction that PPC_LEV (insn) must be 0 no longer applies ...
> 
According to kernel devs, in fact scv is currently not supported in
userspace. Removed.

>> 	  printf_unfiltered (_("no syscall record support\n"));
>> 	  return -1;
>> 	}
>> +
>> +      record_full_arch_list_add_reg (regcache, tdep->ppc_ps_regnum);
>> +      if ((insn & 0x3) != 1)
>> +	{
>> +	  record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
>> +	  record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
>> +	}
> Why is that here?  That should be done by the syscall_record callback
> if appropriate, since it is platform-specific.
> 
Removed.

>> -    case 57:		/* Load Floating-Point Double Pair */
>> -      if (PPC_FIELD (insn, 30, 2) != 0)
>> -	goto UNKNOWN_OP;
>> -      tmp = tdep->ppc_fp0_regnum + (PPC_RT (insn) & ~1);
>> -      record_full_arch_list_add_reg (regcache, tmp);
>> -      record_full_arch_list_add_reg (regcache, tmp + 1);
>> +    case 57:
>> +      /* Load Floating-Point Double Pair */
>> +      if ((insn & 0x3) == 0)
> Note you still need to go to UNKNOWN_OP if (insn & 0x3) == 1.
> Maybe a switch on (insn & 0x3) would be nicer?
Fixed.

>> +        {
>> +	  tmp = tdep->ppc_fp0_regnum + (PPC_RT (insn) & ~1);
>> +	  record_full_arch_list_add_reg (regcache, tmp);
>> +	  record_full_arch_list_add_reg (regcache, tmp + 1);
>> +	  return 0;
> You shouldn't do a "return 0" here, but rather fall through to the end
> of the function, so that the PC gets recorded.
Fixed.

>> +	}
>> +
>> +      /* Load VSX Scalar Doubleword */
>> +      /* Load VSX Scalar Single */
>> +      if (((insn & 0x3) == 2)
>> +	  || ((insn & 0x3) == 3))
>> +	{
>> +	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
>> +	  return 0;
> Likewise.
Fixed.

> 
> 
> The following late additions to ISA 3.0B are still missing (from opcodes):
> 
> {"addex",       ZRC(31,170,0),  Z2_MASK,     POWER9,    0,              {RT, RA, RB, CY}},
> {"vmsumudm",    VXA(4,  35),    VXA_MASK,    PPCVEC3,   0,              {VD, VA, VB, VC}},
> 
> {"mffsce",      XMMF(63,583,0,1), XMMF_MASK|RB_MASK, POWER9, PPCVLE,    {FRT}},
> {"mffscdrn",    XMMF(63,583,2,4), XMMF_MASK,         POWER9, PPCVLE,    {FRT, FRB}},
> {"mffscdrni",   XMMF(63,583,2,5), XMMF_MASK|(3<<14), POWER9, PPCVLE,    {FRT, DRM}},
> {"mffscrn",     XMMF(63,583,2,6), XMMF_MASK,         POWER9, PPCVLE,    {FRT, FRB}},
> {"mffscrni",    XMMF(63,583,2,7), XMMF_MASK|(7<<13), POWER9, PPCVLE,    {FRT, RM}},
> {"mffsl",       XMMF(63,583,3,0), XMMF_MASK|RB_MASK, POWER9, PPCVLE,    {FRT}},
> 
Added.

The new version of the patch is below. Please let me know if there are
any more issues.

Thanks,
--
Edjunior

gdb/ChangeLog:
2016-09-21  Edjunior Barbosa Machado  <emachado@linux.vnet.ibm.com>

	* rs6000-tdep.c (PPC_DQ): New macro.
	(ppc_process_record_op4): Add Power ISA 3.0 instructions.
	(ppc_process_record_op19): Likewise.
	(ppc_process_record_op31): Likewise.
	(ppc_process_record_op59): Likewise.
	(ppc_process_record_op60): Likewise.
	(ppc_process_record_op63): Likewise.
	(ppc_process_record): Likewise.
	(ppc_process_record_op61): New function.

---
 gdb/rs6000-tdep.c | 459 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 448 insertions(+), 11 deletions(-)

diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 263dda0..d7cf38f 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -3817,6 +3817,7 @@ bfd_uses_spe_extensions (bfd *abfd)
 #define PPC_T(insn)	PPC_FIELD (insn, 6, 5)
 #define PPC_D(insn)	PPC_SEXT (PPC_FIELD (insn, 16, 16), 16)
 #define PPC_DS(insn)	PPC_SEXT (PPC_FIELD (insn, 16, 14), 14)
+#define PPC_DQ(insn)	PPC_SEXT (PPC_FIELD (insn, 16, 12), 12)
 #define PPC_BIT(insn,n)	((insn & (1 << (31 - (n)))) ? 1 : 0)
 #define PPC_OE(insn)	PPC_BIT (insn, 21)
 #define PPC_RC(insn)	PPC_BIT (insn, 31)
@@ -3864,6 +3865,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int ext = PPC_FIELD (insn, 21, 11);
+  int vra = PPC_FIELD (insn, 11, 5);
 
   switch (ext & 0x3f)
     {
@@ -3875,6 +3877,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
       /* FALL-THROUGH */
     case 42:		/* Vector Select */
     case 43:		/* Vector Permute */
+    case 59:		/* Vector Permute Right-indexed */
     case 44:		/* Vector Shift Left Double by Octet Immediate */
     case 45:		/* Vector Permute and Exclusive-OR */
     case 60:		/* Vector Add Extended Unsigned Quadword Modulo */
@@ -3882,6 +3885,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 62:		/* Vector Subtract Extended Unsigned Quadword Modulo */
     case 63:		/* Vector Subtract Extended & write Carry Unsigned Quadword */
     case 34:		/* Vector Multiply-Low-Add Unsigned Halfword Modulo */
+    case 35:		/* Vector Multiply-Sum Unsigned Doubleword Modulo */
     case 36:		/* Vector Multiply-Sum Unsigned Byte Modulo */
     case 37:		/* Vector Multiply-Sum Mixed Byte Modulo */
     case 38:		/* Vector Multiply-Sum Unsigned Halfword Modulo */
@@ -3891,14 +3895,37 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
       return 0;
+
+    case 48:		/* Multiply-Add High Doubleword */
+    case 49:		/* Multiply-Add High Doubleword Unsigned */
+    case 51:		/* Multiply-Add Low Doubleword */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
     }
 
   switch ((ext & 0x1ff))
     {
+    case 385:
+      if (vra != 0	/* Decimal Convert To Signed Quadword */
+	  && vra != 2	/* Decimal Convert From Signed Quadword */
+	  && vra != 4	/* Decimal Convert To Zoned */
+	  && vra != 5	/* Decimal Convert To National */
+	  && vra != 6	/* Decimal Convert From Zoned */
+	  && vra != 7	/* Decimal Convert From National */
+	  && vra != 31)	/* Decimal Set Sign */
+	break;
 			/* 5.16 Decimal Integer Arithmetic Instructions */
     case 1:		/* Decimal Add Modulo */
     case 65:		/* Decimal Subtract Modulo */
 
+    case 193:		/* Decimal Shift */
+    case 129:		/* Decimal Unsigned Shift */
+    case 449:		/* Decimal Shift and Round */
+
+    case 257:		/* Decimal Truncate */
+    case 321:		/* Decimal Unsigned Truncate */
+
       /* Bit-21 should be set.  */
       if (!PPC_BIT (insn, 21))
 	break;
@@ -3928,6 +3955,12 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 198:		/* Vector Compare Equal To Single-Precision */
     case 454:		/* Vector Compare Greater Than or Equal To Single-Precision */
     case 710:		/* Vector Compare Greater Than Single-Precision */
+    case 7:		/* Vector Compare Not Equal Byte */
+    case 71:		/* Vector Compare Not Equal Halfword */
+    case 135:		/* Vector Compare Not Equal Word */
+    case 263:		/* Vector Compare Not Equal or Zero Byte */
+    case 327:		/* Vector Compare Not Equal or Zero Halfword */
+    case 391:		/* Vector Compare Not Equal or Zero Word */
       if (PPC_Rc (insn))
 	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache,
@@ -3935,6 +3968,38 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
+  if (ext  == 1538)
+    {
+      switch (vra)
+	{
+	case 0:		/* Vector Count Leading Zero Least-Significant Bits
+			   Byte */
+	case 1:		/* Vector Count Trailing Zero Least-Significant Bits
+			   Byte */
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_gp0_regnum + PPC_RT (insn));
+	  return 0;
+
+	case 6:		/* Vector Negate Word */
+	case 7:		/* Vector Negate Doubleword */
+	case 8:		/* Vector Parity Byte Word */
+	case 9:		/* Vector Parity Byte Doubleword */
+	case 10:	/* Vector Parity Byte Quadword */
+	case 16:	/* Vector Extend Sign Byte To Word */
+	case 17:	/* Vector Extend Sign Halfword To Word */
+	case 24:	/* Vector Extend Sign Byte To Doubleword */
+	case 25:	/* Vector Extend Sign Halfword To Doubleword */
+	case 26:	/* Vector Extend Sign Word To Doubleword */
+	case 28:	/* Vector Count Trailing Zeros Byte */
+	case 29:	/* Vector Count Trailing Zeros Halfword */
+	case 30:	/* Vector Count Trailing Zeros Word */
+	case 31:	/* Vector Count Trailing Zeros Doubleword */
+	  record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_vr0_regnum + PPC_VRT (insn));
+	  return 0;
+	}
+    }
+
   switch (ext)
     {
     case 142:		/* Vector Pack Unsigned Halfword Unsigned Saturate */
@@ -4106,10 +4171,44 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 1923:		/* Vector Population Count Word */
     case 1987:		/* Vector Population Count Doubleword */
     case 1356:		/* Vector Bit Permute Quadword */
+    case 1484:		/* Vector Bit Permute Doubleword */
+    case 513:		/* Vector Multiply-by-10 Unsigned Quadword */
+    case 1:		/* Vector Multiply-by-10 & write Carry Unsigned
+			   Quadword */
+    case 577:		/* Vector Multiply-by-10 Extended Unsigned Quadword */
+    case 65:		/* Vector Multiply-by-10 Extended & write Carry
+			   Unsigned Quadword */
+    case 1027:		/* Vector Absolute Difference Unsigned Byte */
+    case 1091:		/* Vector Absolute Difference Unsigned Halfword */
+    case 1155:		/* Vector Absolute Difference Unsigned Word */
+    case 1796:		/* Vector Shift Right Variable */
+    case 1860:		/* Vector Shift Left Variable */
+    case 133:		/* Vector Rotate Left Word then Mask Insert */
+    case 197:		/* Vector Rotate Left Doubleword then Mask Insert */
+    case 389:		/* Vector Rotate Left Word then AND with Mask */
+    case 453:		/* Vector Rotate Left Doubleword then AND with Mask */
+    case 525:		/* Vector Extract Unsigned Byte */
+    case 589:		/* Vector Extract Unsigned Halfword */
+    case 653:		/* Vector Extract Unsigned Word */
+    case 717:		/* Vector Extract Doubleword */
+    case 781:		/* Vector Insert Byte */
+    case 845:		/* Vector Insert Halfword */
+    case 909:		/* Vector Insert Word */
+    case 973:		/* Vector Insert Doubleword */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
       return 0;
 
+    case 1549:		/* Vector Extract Unsigned Byte Left-Indexed */
+    case 1613:		/* Vector Extract Unsigned Halfword Left-Indexed */
+    case 1677:		/* Vector Extract Unsigned Word Left-Indexed */
+    case 1805:		/* Vector Extract Unsigned Byte Right-Indexed */
+    case 1869:		/* Vector Extract Unsigned Halfword Right-Indexed */
+    case 1933:		/* Vector Extract Unsigned Word Right-Indexed */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+
     case 1604:		/* Move To Vector Status and Control Register */
       record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
       return 0;
@@ -4117,6 +4216,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
       return 0;
+    case 833:		/* Decimal Copy Sign */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
     }
 
   fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
@@ -4134,6 +4238,14 @@ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
 
+  switch (ext & 0x01f)
+    {
+    case 2:		/* Add PC Immediate Shifted */
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+    }
+
   switch (ext)
     {
     case 0:		/* Move Condition Register Field */
@@ -4239,6 +4351,15 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
+  if ((ext & 0xff) == 170)
+    {
+      /* Add Extended using alternate carry bits */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      record_full_arch_list_add_reg (regcache,
+				     tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+    }
+
   switch (ext)
     {
     case 78:		/* Determine Leftmost Zero Byte */
@@ -4257,6 +4378,9 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 302:		/* Move From Branch History Rolling Buffer */
     case 339:		/* Move From Special Purpose Register */
     case 371:		/* Move From Time Base [Phased-Out]  */
+    case 309:		/* Load Doubleword Monitored Indexed  */
+    case 128:		/* Set Boolean */
+    case 755:		/* Deliver A Random Number */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_gp0_regnum + PPC_RT (insn));
       return 0;
@@ -4273,6 +4397,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 282:		/* Convert Declets To Binary Coded Decimal */
     case 314:		/* Convert Binary Coded Decimal To Declets */
     case 508:		/* Compare bytes */
+    case 307:		/* Move From VSR Lower Doubleword */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_gp0_regnum + PPC_RA (insn));
       return 0;
@@ -4291,6 +4416,12 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 32:		/* Compare logical */
     case 144:		/* Move To Condition Register Fields */
 			/* Move To One Condition Register Field */
+    case 192:		/* Compare Ranged Byte */
+    case 224:		/* Compare Equal Byte */
+    case 576:		/* Move XER to CR Extended */
+    case 902:		/* Paste (should always fail due to single-stepping and
+			   the memory location might not be accessible, so
+			   record only CR) */
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       return 0;
 
@@ -4317,6 +4448,12 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 790:		/* Load Halfword Byte-Reverse Indexed */
     case 534:		/* Load Word Byte-Reverse Indexed */
     case 532:		/* Load Doubleword Byte-Reverse Indexed */
+    case 582:		/* Load Word Atomic */
+    case 614:		/* Load Doubleword Atomic */
+    case 265:		/* Modulo Unsigned Doubleword */
+    case 777:		/* Modulo Signed Doubleword */
+    case 267:		/* Modulo Unsigned Word */
+    case 779:		/* Modulo Signed Word */
       record_full_arch_list_add_reg (regcache,
 				     tdep->ppc_gp0_regnum + PPC_RT (insn));
       return 0;
@@ -4395,6 +4532,16 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 844:		/* Load VSX Vector Doubleword*2 Indexed */
     case 332:		/* Load VSX Vector Doubleword & Splat Indexed */
     case 780:		/* Load VSX Vector Word*4 Indexed */
+    case 268:		/* Load VSX Vector Indexed */
+    case 364:		/* Load VSX Vector Word & Splat Indexed */
+    case 812:		/* Load VSX Vector Halfword*8 Indexed */
+    case 876:		/* Load VSX Vector Byte*16 Indexed */
+    case 269:		/* Load VSX Vector with Length */
+    case 301:		/* Load VSX Vector Left-justified with Length */
+    case 781:		/* Load VSX Scalar as Integer Byte & Zero Indexed */
+    case 813:		/* Load VSX Scalar as Integer Halfword & Zero Indexed */
+    case 403:		/* Move To VSR Word & Splat */
+    case 435:		/* Move To VSR Double Doubleword */
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
 
@@ -4416,6 +4563,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 922:		/* Extend Sign Halfword */
     case 954:		/* Extend Sign Byte */
     case 986:		/* Extend Sign Word */
+    case 538:		/* Count Trailing Zeros Word */
+    case 570:		/* Count Trailing Zeros Doubleword */
+    case 890:		/* Extend-Sign Word and Shift Left Immediate (445) */
+    case 890 | 1:	/* Extend-Sign Word and Shift Left Immediate (445) */
       if (PPC_RC (insn))
 	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache,
@@ -4458,6 +4609,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 727:		/* Store Floating-Point Double Indexed */
     case 919:		/* Store Floating-Point Double Pair Indexed */
     case 983:		/* Store Floating-Point as Integer Word Indexed */
+    case 396:		/* Store VSX Vector Indexed */
+    case 940:		/* Store VSX Vector Halfword*8 Indexed */
+    case 1004:		/* Store VSX Vector Byte*16 Indexed */
+    case 909:		/* Store VSX Scalar as Integer Byte Indexed */
+    case 941:		/* Store VSX Scalar as Integer Halfword Indexed */
       if (ext == 694 || ext == 726 || ext == 150 || ext == 214 || ext == 182)
 	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
 
@@ -4487,6 +4643,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 	case 135:	/* Store Vector Element Byte Indexed */
 	case 215:	/* Store Byte Indexed */
 	case 694:	/* Store Byte Conditional Indexed */
+	case 909:	/* Store VSX Scalar as Integer Byte Indexed */
 	  size = 1;
 	  break;
 	case 439:	/* Store Halfword with Update Indexed */
@@ -4494,6 +4651,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 	case 407:	/* Store Halfword Indexed */
 	case 726:	/* Store Halfword Conditional Indexed */
 	case 918:	/* Store Halfword Byte-Reverse Indexed */
+	case 941:	/* Store VSX Scalar as Integer Halfword Indexed */
 	  size = 2;
 	  break;
 	case 181:	/* Store Doubleword with Update Indexed */
@@ -4511,6 +4669,9 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 	case 231:	/* Store Vector Indexed */
 	case 487:	/* Store Vector Indexed LRU */
 	case 919:	/* Store Floating-Point Double Pair Indexed */
+	case 396:	/* Store VSX Vector Indexed */
+	case 940:	/* Store VSX Vector Halfword*8 Indexed */
+	case 1004:	/* Store VSX Vector Byte*16 Indexed */
 	  size = 16;
 	  break;
 	default:
@@ -4537,6 +4698,38 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_mem (addr, size);
       return 0;
 
+    case 397:		/* Store VSX Vector with Length */
+    case 429:		/* Store VSX Vector Left-justified with Length */
+      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);
+      /* Store up to 16 bytes.  */
+      nb = (rb & 0xff) > 16 ? 16 : (rb & 0xff);
+      if (nb > 0)
+	record_full_arch_list_add_mem (ea, nb);
+      return 0;
+
+    case 710:		/* Store Word Atomic */
+    case 742:		/* Store Doubleword Atomic */
+      if (PPC_RA (insn) != 0)
+	regcache_raw_read_unsigned (regcache,
+				    tdep->ppc_gp0_regnum + PPC_RA (insn), &ea);
+      switch (ext)
+	{
+	case 710:	/* Store Word Atomic */
+	  size = 8;
+	  break;
+	case 742:	/* Store Doubleword Atomic */
+	  size = 16;
+	  break;
+	default:
+	  gdb_assert (0);
+	}
+      record_full_arch_list_add_mem (ea, size);
+      return 0;
+
     case 725:		/* Store String Word Immediate */
       ra = 0;
       if (PPC_RA (insn) != 0)
@@ -4606,6 +4799,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 430:		/* Clear BHRB */
     case 598:		/* Synchronize */
     case 62:		/* Wait for Interrupt */
+    case 30:		/* Wait */
     case 22:		/* Instruction Cache Block Touch */
     case 854:		/* Enforce In-order Execution of I/O */
     case 246:		/* Data Cache Block Touch for Store */
@@ -4614,6 +4808,8 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 278:		/* Data Cache Block Touch */
     case 758:		/* Data Cache Block Allocate */
     case 982:		/* Instruction Cache Block Invalidate */
+    case 774:		/* Copy */
+    case 838:		/* CP_Abort */
       return 0;
 
     case 654:		/* Transaction Begin */
@@ -4713,6 +4909,7 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 226:		/* DFP Test Data Group */
     case 642:		/* DFP Compare Unordered */
     case 674:		/* DFP Test Significance */
+    case 675:		/* DFP Test Significance Immediate */
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       return 0;
@@ -4812,7 +5009,16 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 217:		/* ditto */
     case 104:		/* VSX Vector Subtract Double-Precision */
     case 72:		/* VSX Vector Subtract Single-Precision */
+    case 128:		/* VSX Scalar Maximum Type-C Double-Precision */
+    case 136:		/* VSX Scalar Minimum Type-C Double-Precision */
+    case 144:		/* VSX Scalar Maximum Type-J Double-Precision */
+    case 152:		/* VSX Scalar Minimum Type-J Double-Precision */
+    case 3:		/* VSX Scalar Compare Equal Double-Precision */
+    case 11:		/* VSX Scalar Compare Greater Than Double-Precision */
+    case 19:		/* VSX Scalar Compare Greater Than or Equal
+			   Double-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
     case 240:		/* VSX Vector Copy Sign Double-Precision */
     case 208:		/* VSX Vector Copy Sign Single-Precision */
     case 130:		/* VSX Logical AND */
@@ -4833,6 +5039,14 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 2 | 0x20:	/* VSX Shift Left Double by Word Immediate (SHW=1) */
     case 2 | 0x40:	/* VSX Shift Left Double by Word Immediate (SHW=2) */
     case 2 | 0x60:	/* VSX Shift Left Double by Word Immediate (SHW=3) */
+    case 216:		/* VSX Vector Insert Exponent Single-Precision */
+    case 248:		/* VSX Vector Insert Exponent Double-Precision */
+    case 26:		/* VSX Vector Permute */
+    case 58:		/* VSX Vector Permute Right-indexed */
+    case 213:		/* VSX Vector Test Data Class Single-Precision (DC=0) */
+    case 213 | 0x8:	/* VSX Vector Test Data Class Single-Precision (DC=1) */
+    case 245:		/* VSX Vector Test Data Class Double-Precision (DC=0) */
+    case 245 | 0x8:	/* VSX Vector Test Data Class Double-Precision (DC=1) */
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
 
@@ -4844,6 +5058,7 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
 
     case 35:		/* VSX Scalar Compare Unordered Double-Precision */
     case 43:		/* VSX Scalar Compare Ordered Double-Precision */
+    case 59:		/* VSX Scalar Compare Exponents Double-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       return 0;
@@ -4990,6 +5205,7 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 203:		/* VSX Vector Square Root Double-Precision */
     case 139:		/* VSX Vector Square Root Single-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
     case 345:		/* VSX Scalar Absolute Value Double-Precision */
     case 267:		/* VSX Scalar Convert Scalar Single-Precision to
 			   Vector Single-Precision format Non-signalling */
@@ -5004,9 +5220,15 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 505:		/* VSX Vector Negate Double-Precision */
     case 441:		/* VSX Vector Negate Single-Precision */
     case 164:		/* VSX Splat Word */
+    case 165:		/* VSX Vector Extract Unsigned Word */
+    case 181:		/* VSX Vector Insert Word */
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
 
+    case 298:		/* VSX Scalar Test Data Class Single-Precision */
+    case 362:		/* VSX Scalar Test Data Class Double-Precision */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
     case 106:		/* VSX Scalar Test for software Square Root
 			   Double-Precision */
     case 234:		/* VSX Vector Test for software Square Root
@@ -5015,6 +5237,60 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
 			   Single-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       return 0;
+
+    case 347:
+      switch (PPC_FIELD (insn, 11, 5))
+	{
+	case 0:		/* VSX Scalar Extract Exponent Double-Precision */
+	case 1:		/* VSX Scalar Extract Significand Double-Precision */
+          record_full_arch_list_add_reg (regcache,
+					 tdep->ppc_gp0_regnum + PPC_RT (insn));
+	  return 0;
+	case 16:	/* VSX Scalar Convert Half-Precision format to
+			   Double-Precision format */
+	case 17:	/* VSX Scalar round & Convert Double-Precision format
+			   to Half-Precision format */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+	  return 0;
+	}
+      break;
+
+    case 475:
+      switch (PPC_FIELD (insn, 11, 5))
+	{
+	case 24:	/* VSX Vector Convert Half-Precision format to
+			   Single-Precision format */
+	case 25:	/* VSX Vector round and Convert Single-Precision format
+			   to Half-Precision format */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+	  /* FALL-THROUGH */
+	case 0:		/* VSX Vector Extract Exponent Double-Precision */
+	case 1:		/* VSX Vector Extract Significand Double-Precision */
+	case 7:		/* VSX Vector Byte-Reverse Halfword */
+	case 8:		/* VSX Vector Extract Exponent Single-Precision */
+	case 9:		/* VSX Vector Extract Significand Single-Precision */
+	case 15:	/* VSX Vector Byte-Reverse Word */
+	case 23:	/* VSX Vector Byte-Reverse Doubleword */
+	case 31:	/* VSX Vector Byte-Reverse Quadword */
+	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+	  return 0;
+	}
+      break;
+    }
+
+  switch (ext)
+    {
+    case 360:		/* VSX Vector Splat Immediate Byte */
+      if (PPC_FIELD (insn, 11, 2) == 0)
+	{
+	  ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+	  return 0;
+	}
+      break;
+    case 918:		/* VSX Scalar Insert Exponent Double-Precision */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
     }
 
   if (((ext >> 3) & 0x3) == 3)	/* VSX Select */
@@ -5028,6 +5304,65 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record instructions of primary opcode-61 at ADDR.
+   Return 0 if successful.  */
+
+static int
+ppc_process_record_op61 (struct gdbarch *gdbarch, struct regcache *regcache,
+			   CORE_ADDR addr, uint32_t insn)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ULONGEST ea = 0;
+  int size;
+
+  switch (insn & 0x3)
+    {
+    case 0:		/* Store Floating-Point Double Pair */
+    case 2:		/* Store VSX Scalar Doubleword */
+    case 3:		/* Store VSX Scalar Single */
+      if (PPC_RA (insn) != 0)
+	regcache_raw_read_unsigned (regcache,
+				    tdep->ppc_gp0_regnum + PPC_RA (insn),
+				    &ea);
+      ea += PPC_DS (insn) << 2;
+      switch (insn & 0x3)
+	{
+	case 0:		/* Store Floating-Point Double Pair */
+	  size = 16;
+	  break;
+	case 2:		/* Store VSX Scalar Doubleword */
+	  size = 8;
+	  break;
+	case 3:		/* Store VSX Scalar Single */
+	  size = 4;
+	  break;
+	default:
+	  gdb_assert (0);
+	}
+      record_full_arch_list_add_mem (ea, size);
+      return 0;
+    }
+
+  switch (insn & 0x7)
+    {
+    case 1:		/* Load VSX Vector */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
+    case 5:		/* Store VSX Vector */
+      if (PPC_RA (insn) != 0)
+	regcache_raw_read_unsigned (regcache,
+				    tdep->ppc_gp0_regnum + PPC_RA (insn),
+				    &ea);
+      ea += PPC_DQ (insn) << 4;
+      record_full_arch_list_add_mem (ea, 16);
+      return 0;
+    }
+
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+		      "at %s.\n", insn, paddress (gdbarch, addr));
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-63 at ADDR.
    Return 0 if successful.  */
 
@@ -5066,6 +5401,16 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
 	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
     }
 
+  switch (ext & 0xff)
+    {
+    case 5:		/* VSX Scalar Round to Quad-Precision Integer */
+    case 37:		/* VSX Scalar Round Quad-Precision to Double-Extended
+			   Precision */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+      return 0;
+    }
+
   switch (ext)
     {
     case 2:		/* DFP Add Quad */
@@ -5095,6 +5440,7 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 226:		/* DFP Test Data Group Quad */
     case 642:		/* DFP Compare Unordered Quad */
     case 674:		/* DFP Test Significance Quad */
+    case 675:		/* DFP Test Significance Immediate Quad */
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       return 0;
@@ -5151,7 +5497,26 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       return 0;
 
-    case 583:		/* Move From FPSCR */
+    case 583:
+      switch (PPC_FIELD (insn, 11, 5))
+        {
+	  case 1:	/* Move From FPSCR & Clear Enables */
+	  case 20:	/* Move From FPSCR Control & set DRN */
+	  case 21:	/* Move From FPSCR Control & set DRN Immediate */
+	  case 22:	/* Move From FPSCR Control & set RN */
+	  case 23:	/* Move From FPSCR Control & set RN Immediate */
+	    record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+	  case 0:	/* Move From FPSCR */
+	  case 24:	/* Move From FPSCR Lightweight */
+	    if (PPC_FIELD (insn, 11, 5) == 0 && PPC_RC (insn))
+	      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+	    record_full_arch_list_add_reg (regcache,
+					   tdep->ppc_fp0_regnum
+					   + PPC_FRT (insn));
+	    return 0;
+        }
+      break;
+
     case 8:		/* Floating Copy Sign */
     case 40:		/* Floating Negate */
     case 72:		/* Floating Move Register */
@@ -5181,6 +5546,10 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 0:		/* Floating Compare Unordered */
     case 32:		/* Floating Compare Ordered */
     case 64:		/* Move to Condition Register from FPSCR */
+    case 132:		/* VSX Scalar Compare Ordered Quad-Precision */
+    case 164:		/* VSX Scalar Compare Exponents Quad-Precision */
+    case 644:		/* VSX Scalar Compare Unordered Quad-Precision */
+    case 708:		/* VSX Scalar Test Data Class Quad-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       /* FALL-THROUGH */
     case 128:		/* Floating Test for software Divide */
@@ -5188,10 +5557,65 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       return 0;
 
+    case 4:		/* VSX Scalar Add Quad-Precision */
+    case 36:		/* VSX Scalar Multiply Quad-Precision */
+    case 388:		/* VSX Scalar Multiply-Add Quad-Precision */
+    case 420:		/* VSX Scalar Multiply-Subtract Quad-Precision */
+    case 452:		/* VSX Scalar Negative Multiply-Add Quad-Precision */
+    case 484:		/* VSX Scalar Negative Multiply-Subtract
+			   Quad-Precision */
+    case 516:		/* VSX Scalar Subtract Quad-Precision */
+    case 548:		/* VSX Scalar Divide Quad-Precision */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
+    case 100:		/* VSX Scalar Copy Sign Quad-Precision */
+    case 868:		/* VSX Scalar Insert Exponent Quad-Precision */
+      ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+      return 0;
+
+    case 804:
+      switch (PPC_FIELD (insn, 11, 5))
+	{
+	case 27:	/* VSX Scalar Square Root Quad-Precision */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+	  /* FALL-THROUGH */
+	case 0:		/* VSX Scalar Absolute Quad-Precision */
+	case 2:		/* VSX Scalar Extract Exponent Quad-Precision */
+	case 8:		/* VSX Scalar Negative Absolute Quad-Precision */
+	case 16:	/* VSX Scalar Negate Quad-Precision */
+	case 18:	/* VSX Scalar Extract Significand Quad-Precision */
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+	  return 0;
+	}
+      break;
+
+    case 836:
+      switch (PPC_FIELD (insn, 11, 5))
+	{
+	case 1:		/* VSX Scalar truncate & Convert Quad-Precision format
+			   to Unsigned Word format */
+	case 2:		/* VSX Scalar Convert Unsigned Doubleword format to
+			   Quad-Precision format */
+	case 9:		/* VSX Scalar truncate & Convert Quad-Precision format
+			   to Signed Word format */
+	case 10:	/* VSX Scalar Convert Signed Doubleword format to
+			   Quad-Precision format */
+	case 17:	/* VSX Scalar truncate & Convert Quad-Precision format
+			   to Unsigned Doubleword format */
+	case 20:	/* VSX Scalar round & Convert Quad-Precision format to
+			   Double-Precision format */
+	case 22:	/* VSX Scalar Convert Double-Precision format to
+			   Quad-Precision format */
+	case 25:	/* VSX Scalar truncate & Convert Quad-Precision format
+			   to Signed Doubleword format */
+	  record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+	  return 0;
+	}
     }
 
   fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
-		      "at %s, 59-%d.\n", insn, paddress (gdbarch, addr), ext);
+		      "at %s, 63-%d.\n", insn, paddress (gdbarch, addr), ext);
   return -1;
 }
 
@@ -5402,12 +5826,21 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 	}
       break;
 
-    case 57:		/* Load Floating-Point Double Pair */
-      if (PPC_FIELD (insn, 30, 2) != 0)
-	goto UNKNOWN_OP;
-      tmp = tdep->ppc_fp0_regnum + (PPC_RT (insn) & ~1);
-      record_full_arch_list_add_reg (regcache, tmp);
-      record_full_arch_list_add_reg (regcache, tmp + 1);
+    case 57:
+      switch (insn & 0x3)
+        {
+	case 0:		/* Load Floating-Point Double Pair */
+	  tmp = tdep->ppc_fp0_regnum + (PPC_RT (insn) & ~1);
+	  record_full_arch_list_add_reg (regcache, tmp);
+	  record_full_arch_list_add_reg (regcache, tmp + 1);
+	  break;
+	case 2:		/* Load VSX Scalar Doubleword */
+	case 3:		/* Load VSX Scalar Single */
+	  ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+	  break;
+	default:
+	  goto UNKNOWN_OP;
+	}
       break;
 
     case 58:		/* Load Doubleword */
@@ -5433,7 +5866,11 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 	return -1;
       break;
 
-    case 61:		/* Store Floating-Point Double Pair */
+    case 61:
+      if (ppc_process_record_op61 (gdbarch, regcache, addr, insn) != 0)
+	return -1;
+      break;
+
     case 62:		/* Store Doubleword */
 			/* Store Doubleword with Update */
 			/* Store Quadword with Update */
@@ -5442,7 +5879,7 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 	  int size;
 	  int sub2 = PPC_FIELD (insn, 30, 2);
 
-	  if ((op6 == 61 && sub2 != 0) || (op6 == 62 && sub2 > 2))
+	  if (sub2 > 2)
 	    goto UNKNOWN_OP;
 
 	  if (PPC_RA (insn) != 0)
@@ -5450,7 +5887,7 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 					tdep->ppc_gp0_regnum + PPC_RA (insn),
 					&addr);
 
-	  size = ((op6 == 61) || sub2 == 2) ? 16 : 8;
+	  size = (sub2 == 2) ? 16 : 8;
 
 	  addr += PPC_DS (insn) << 2;
 	  record_full_arch_list_add_mem (addr, size);
-- 
2.5.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]