public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] PPC: reject more instructions with invalid operand  combinations
@ 2011-09-28 12:26 Jan Beulich
  2011-10-06  1:14 ` Alan Modra
  2011-10-27  2:11 ` Peter Bergner
  0 siblings, 2 replies; 6+ messages in thread
From: Jan Beulich @ 2011-09-28 12:26 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 23635 bytes --]

While updating test cases for another disassembler I noticed a number of
cases where supposedly (as per the documentation) invalid instructions are
being happily accepted by the assembler. These were
- bcctr with a condition accessing the count register,
- lswi and lswx loading into their address register,
- lfdp{,x}, stfdp{,x}, and the DFP quad instructions accessing odd numbered
  register pairs.

Additionally I found that while lfdp{,x} get rejected as invalid for POWER7
as specified, stfdp{,x} were accepted.

There is one more case that this patch doesn't address (due it being unclear
to me how to actually do so): Instructions invalid in little endian mode (in
the server environment).

Finally I noticed that even in the documentation there is a pseudo opcode
apparently missing: While xvmov{d,s}p are aliases of xvcpsgn{d,s}p, there's
no xsmovdp alias of xscpsgndp.

gas/testsuite/
2011-09-28  Jan Beulich  <jbeulich@suse.com>

	* gas/ppc/476.s: Fix lswi first operand.
	* gas/ppc/476.d: Adjust expected output.
	* gas/ppc/a2.s: Fix lswi first operand.
	* gas/ppc/a2.d: Adjust expected output.
	* gas/ppc/power6.s: Fix lfdpx first operand.
	* gas/ppc/power6.d: Adjust expected output.

opcodes/
2011-09-28  Jan Beulich  <jbeulich@suse.com>

	* ppc-opc.c (insert_nbi, insert_rbx, FRAp, FRBp, FRSp, FRTp, NBI, RAX,
	RBX): New.
	(insert_bo, insert_boe): Reject bcctr with bit 2 in bo unset.
	(powerpc_opcodes): Use RAX for second and RBXC for third operand of
	lswx. Use NBI for third operand of lswi. Use FRTp for first operand of
	lfdp and lfdpx. Use FRSp for first operand of stfdp and stfdpx, and
	mark them as invalid on POWER7. Use FRTp, FRAp, and FRBp repsectively
	on DFP quad instructions.

--- 2011-09-28/gas/testsuite/gas/ppc/476.d	2010-05-07 15:46:10.000000000 +0200
+++ 2011-09-28/gas/testsuite/gas/ppc/476.d	2011-09-28 12:43:20.000000000 +0200
@@ -234,7 +234,7 @@ Disassembly of section \.text:
  380:	7e 96 c2 6e 	lhzux   r20,r22,r24
  384:	7e f8 ca 2e 	lhzx    r23,r24,r25
  388:	b8 61 ff f0 	lmw     r3,-16\(r1\)
- 38c:	7c 64 84 aa 	lswi    r3,r4,16
+ 38c:	7c a4 84 aa 	lswi    r5,r4,16
  390:	7c 64 2c 2a 	lswx    r3,r4,r5
  394:	7c 64 28 28 	lwarx   r3,r4,r5
  398:	7c 64 28 28 	lwarx   r3,r4,r5
--- 2011-09-28/gas/testsuite/gas/ppc/476.s	2010-05-07 15:46:10.000000000 +0200
+++ 2011-09-28/gas/testsuite/gas/ppc/476.s	2011-09-28 12:43:20.000000000 +0200
@@ -227,7 +227,7 @@ ppc476:
 	lhzux	20,22,24
 	lhzx	23,24,25
 	lmw	3,-16(1)
-	lswi	3,4,16
+	lswi	5,4,16
 	lswx	3,4,5
 	lwarx	3,4,5
 	lwarx	3,4,5,0
--- 2011-09-28/gas/testsuite/gas/ppc/a2.d	2010-06-09 17:04:13.000000000 +0200
+++ 2011-09-28/gas/testsuite/gas/ppc/a2.d	2011-09-28 12:43:20.000000000 +0200
@@ -322,7 +322,7 @@ Disassembly of section \.text:
  498:	7d 4b 62 2e 	lhzx    r10,r11,r12
  49c:	ba 8a 00 10 	lmw     r20,16\(r10\)
  4a0:	7d 4b 0c aa 	lswi    r10,r11,1
- 4a4:	7d 4b 04 aa 	lswi    r10,r11,32
+ 4a4:	7d 8b 04 aa 	lswi    r12,r11,32
  4a8:	7d 4b 64 2a 	lswx    r10,r11,r12
  4ac:	e9 4b ff fe 	lwa     r10,-4\(r11\)
  4b0:	e9 4b 00 06 	lwa     r10,4\(r11\)
--- 2011-09-28/gas/testsuite/gas/ppc/a2.s	2010-05-07 15:46:10.000000000 +0200
+++ 2011-09-28/gas/testsuite/gas/ppc/a2.s	2011-09-28 12:43:20.000000000 +0200
@@ -297,7 +297,7 @@ start:
 	lhzx	10,11,12
 	lmw	20,16(10)
 	lswi	10,11,1
-	lswi	10,11,32
+	lswi	12,11,32
 	lswx	10,11,12
 	lwa	10,-4(11)
 	lwa	10,4(11)
--- 2011-09-28/gas/testsuite/gas/ppc/power6.d	2009-04-15 08:47:27.000000000 +0200
+++ 2011-09-28/gas/testsuite/gas/ppc/power6.d	2011-09-28 12:43:20.000000000 +0200
@@ -19,7 +19,7 @@ Disassembly of section \.text:
   24:	7c c0 3c be 	mffgpr  f6,r7
   28:	7d 00 4d be 	mftgpr  r8,f9
   2c:	7d 4b 66 2a 	lwzcix  r10,r11,r12
-  30:	7d ae 7e 2e 	lfdpx   f13,r14,r15
+  30:	7d 8e 7e 2e 	lfdpx   f12,r14,r15
   34:	ee 11 90 04 	dadd    f16,f17,f18
   38:	fe 96 c0 04 	daddq   f20,f22,f24
   3c:	7c 60 06 6c 	dss     3
--- 2011-09-28/gas/testsuite/gas/ppc/power6.s	2009-04-15 08:47:27.000000000 +0200
+++ 2011-09-28/gas/testsuite/gas/ppc/power6.s	2011-09-28 12:43:20.000000000 +0200
@@ -14,7 +14,7 @@ start:
 	mffgpr	6,7
 	mftgpr	8,9
 	lwzcix	10,11,12
-	lfdpx	13,14,15
+	lfdpx	12,14,15
 	dadd	16,17,18
 	daddq	20,22,24
 	dss	3
--- 2011-09-28/opcodes/ppc-opc.c	2011-05-13 08:38:04.000000000 +0200
+++ 2011-09-28/opcodes/ppc-opc.c	2011-09-28 12:43:20.000000000 +0200
@@ -58,6 +58,7 @@ static long extract_mbe (unsigned long, 
 static unsigned long insert_mb6 (unsigned long, long, ppc_cpu_t, const char **);
 static long extract_mb6 (unsigned long, ppc_cpu_t, int *);
 static long extract_nb (unsigned long, ppc_cpu_t, int *);
+static unsigned long insert_nbi (unsigned long, long, ppc_cpu_t, const char **);
 static unsigned long insert_nsi (unsigned long, long, ppc_cpu_t, const char **);
 static long extract_nsi (unsigned long, ppc_cpu_t, int *);
 static unsigned long insert_ral (unsigned long, long, ppc_cpu_t, const char **);
@@ -66,6 +67,7 @@ static unsigned long insert_raq (unsigne
 static unsigned long insert_ras (unsigned long, long, ppc_cpu_t, const char **);
 static unsigned long insert_rbs (unsigned long, long, ppc_cpu_t, const char **);
 static long extract_rbs (unsigned long, ppc_cpu_t, int *);
+static unsigned long insert_rbx (unsigned long, long, ppc_cpu_t, const char **);
 static unsigned long insert_sh6 (unsigned long, long, ppc_cpu_t, const char **);
 static long extract_sh6 (unsigned long, ppc_cpu_t, int *);
 static unsigned long insert_spr (unsigned long, long, ppc_cpu_t, const char **);
@@ -269,13 +271,21 @@ const struct powerpc_operand powerpc_ope
 #define FRA_MASK (0x1f << 16)
   { 0x1f, 16, NULL, NULL, PPC_OPERAND_FPR },
 
+  /* The FRAp field of DFP instructions.  */
+#define FRAp FRA + 1
+  { 0x1e, 16, NULL, NULL, PPC_OPERAND_FPR },
+
   /* The FRB field in an X or A form instruction.  */
-#define FRB FRA + 1
+#define FRB FRAp + 1
 #define FRB_MASK (0x1f << 11)
   { 0x1f, 11, NULL, NULL, PPC_OPERAND_FPR },
 
+  /* The FRBp field of DFP instructions.  */
+#define FRBp FRB + 1
+  { 0x1e, 11, NULL, NULL, PPC_OPERAND_FPR },
+
   /* The FRC field in an A form instruction.  */
-#define FRC FRB + 1
+#define FRC FRBp + 1
 #define FRC_MASK (0x1f << 6)
   { 0x1f, 6, NULL, NULL, PPC_OPERAND_FPR },
 
@@ -285,8 +295,14 @@ const struct powerpc_operand powerpc_ope
 #define FRT FRS
   { 0x1f, 21, NULL, NULL, PPC_OPERAND_FPR },
 
+  /* The FRSp field of stfdp or the FRTp field of lfdp and DFP
+     instructions.  */
+#define FRSp FRS + 1
+#define FRTp FRSp
+  { 0x1e, 21, NULL, NULL, PPC_OPERAND_FPR },
+
   /* The FXM field in an XFX instruction.  */
-#define FXM FRS + 1
+#define FXM FRSp + 1
   { 0xff, 12, insert_fxm, extract_fxm, 0 },
 
   /* Power4 version for mfcr.  */
@@ -345,9 +361,14 @@ const struct powerpc_operand powerpc_ope
 #define NB MB6 + 1
   { 0x1f, 11, NULL, extract_nb, PPC_OPERAND_PLUS1 },
 
+  /* The NBI field in an lswi instruction, which has special value
+     restrictions.  The value 32 is stored as 0.  */
+#define NBI NB + 1
+  { 0x1f, 11, insert_nbi, extract_nb, PPC_OPERAND_PLUS1 },
+
   /* The NSI field in a D form instruction.  This is the same as the
      SI field, only negated.  */
-#define NSI NB + 1
+#define NSI NBI + 1
   { 0xffff, 0, insert_nsi, extract_nsi,
       PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
 
@@ -360,9 +381,10 @@ const struct powerpc_operand powerpc_ope
 #define RA0 RA + 1
   { 0x1f, 16, NULL, NULL, PPC_OPERAND_GPR_0 },
 
-  /* The RA field in the DQ form lq instruction, which has special
+  /* The RA field in the DQ form lq or an lswx instruction, which have special
      value restrictions.  */
 #define RAQ RA0 + 1
+#define RAX RAQ
   { 0x1f, 16, insert_raq, NULL, PPC_OPERAND_GPR_0 },
 
   /* The RA field in a D or X form instruction which is an updating
@@ -398,8 +420,13 @@ const struct powerpc_operand powerpc_ope
 #define RBS RB + 1
   { 0x1f, 11, insert_rbs, extract_rbs, PPC_OPERAND_FAKE },
 
+  /* The RB field in an lswx instruction, which has special value
+     restrictions.  */
+#define RBX RBS + 1
+  { 0x1f, 11, insert_rbx, NULL, PPC_OPERAND_GPR },
+
   /* The RB field of the dccci and iccci instructions, which are optional.  */
-#define RBOPT RBS + 1
+#define RBOPT RBX + 1
   { 0x1f, 11, NULL, NULL, PPC_OPERAND_GPR | PPC_OPERAND_OPTIONAL },
 
   /* The RS field in a D, DS, X, XFX, XS, M, MD or MDS form
@@ -877,6 +904,8 @@ insert_bo (unsigned long insn,
 {
   if (!valid_bo (value, dialect, 0))
     *errmsg = _("invalid conditional option");
+  else if (PPC_OP (insn) == 19 && (insn & 0x400) && ! (value & 4))
+    *errmsg = _("invalid counter access");
   return insn | ((value & 0x1f) << 21);
 }
 
@@ -905,6 +934,8 @@ insert_boe (unsigned long insn,
 {
   if (!valid_bo (value, dialect, 0))
     *errmsg = _("invalid conditional option");
+  else if (PPC_OP (insn) == 19 && (insn & 0x400) && ! (value & 4))
+    *errmsg = _("invalid counter access");
   else if ((value & 1) != 0)
     *errmsg = _("attempt to set y bit when using + or - modifier");
 
@@ -1120,6 +1151,26 @@ extract_nb (unsigned long insn,
   return ret;
 }
 
+/* The NB field in an lswi instruction, which has special value
+   restrictions.  The value 32 is stored as 0.  */
+
+static unsigned long
+insert_nbi (unsigned long insn,
+	    long value,
+	    ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+	    const char **errmsg ATTRIBUTE_UNUSED)
+{
+  long rtvalue = (insn & RT_MASK) >> 21;
+  long ravalue = (insn & RA_MASK) >> 16;
+
+  if (value == 0)
+    value = 32;
+  if (rtvalue + (value + 3) / 4 > (rtvalue > ravalue ? ravalue + 32
+						     : ravalue))
+    *errmsg = _("address register in load range");
+  return insn | ((value & 0x1f) << 11);
+}
+
 /* The NSI field in a D form instruction.  This is the same as the SI
    field, only negated.  The extraction function always marks it as
    invalid, since we never want to recognize an instruction which uses
@@ -1173,7 +1224,7 @@ insert_ram (unsigned long insn,
   return insn | ((value & 0x1f) << 16);
 }
 
-/* The RA field in the DQ form lq instruction, which has special
+/* The RA field in the DQ form lq or an lswx instruction, which have special
    value restrictions.  */
 
 static unsigned long
@@ -1229,6 +1280,22 @@ extract_rbs (unsigned long insn,
   return 0;
 }
 
+/* The RB field in an lswx instruction, which has special value
+   restrictions.  */
+
+static unsigned long
+insert_rbx (unsigned long insn,
+	    long value,
+	    ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+	    const char **errmsg)
+{
+  long rtvalue = (insn & RT_MASK) >> 21;
+
+  if (value == rtvalue)
+    *errmsg = _("source and target register operands must be different");
+  return insn | ((value & 0x1f) << 11);
+}
+
 /* The SH field in an MD form instruction.  This is split.  */
 
 static unsigned long
@@ -4421,7 +4488,7 @@ const struct powerpc_opcode powerpc_opco
 
 {"ldbrx",	X(31,532),	X_MASK, CELL|POWER7|PPCA2, PPCNONE,	{RT, RA0, RB}},
 
-{"lswx",	X(31,533),	X_MASK,      PPCCOM,	E500|E500MC,	{RT, RA0, RB}},
+{"lswx",	X(31,533),	X_MASK,      PPCCOM,	E500|E500MC,	{RT, RAX, RBX}},
 {"lsx",		X(31,533),	X_MASK,      PWRCOM,	PPCNONE,	{RT, RA, RB}},
 
 {"lwbrx",	X(31,534),	X_MASK,      PPCCOM,	PPCNONE,	{RT, RA0, RB}},
@@ -4467,7 +4534,7 @@ const struct powerpc_opcode powerpc_opco
 
 {"mfsr",	X(31,595), XRB_MASK|(1<<20), COM,	NON32,  	{RT, SR}},
 
-{"lswi",	X(31,597),	X_MASK,      PPCCOM,	E500|E500MC,	{RT, RA0, NB}},
+{"lswi",	X(31,597),	X_MASK,      PPCCOM,	E500|E500MC,	{RT, RA0, NBI}},
 {"lsi",		X(31,597),	X_MASK,      PWRCOM,	PPCNONE,	{RT, RA0, NB}},
 
 {"lwsync",	XSYNC(31,598,1), 0xffffffff, PPC,	E500,		{0}},
@@ -4625,7 +4692,7 @@ const struct powerpc_opcode powerpc_opco
 
 {"lhbrx",	X(31,790),	X_MASK,      COM,	PPCNONE,	{RT, RA0, RB}},
 
-{"lfdpx",	X(31,791),	X_MASK,      POWER6,	POWER7,		{FRT, RA, RB}},
+{"lfdpx",	X(31,791),	X_MASK,      POWER6,	POWER7,		{FRTp, RA, RB}},
 {"lfqx",	X(31,791),	X_MASK,      POWER2,	PPCNONE,	{FRT, RA, RB}},
 
 {"sraw",	XRC(31,792,0),	X_MASK,      PPCCOM,	PPCNONE,	{RA, RS, RB}},
@@ -4705,7 +4772,7 @@ const struct powerpc_opcode powerpc_opco
 
 {"sthbrx",	X(31,918),	X_MASK,      COM,	PPCNONE,	{RS, RA0, RB}},
 
-{"stfdpx",	X(31,919),	X_MASK,      POWER6,	PPCNONE,	{FRS, RA, RB}},
+{"stfdpx",	X(31,919),	X_MASK,      POWER6,	POWER7,		{FRSp, RA, RB}},
 {"stfqx",	X(31,919),	X_MASK,      POWER2,	PPCNONE,	{FRS, RA, RB}},
 
 {"sraq",	XRC(31,920,0),	X_MASK,      M601,	PPCNONE,	{RA, RS, RB}},
@@ -4869,7 +4936,7 @@ const struct powerpc_opcode powerpc_opco
 {"psq_l",	OP(56),		OP_MASK,     PPCPS,	PPCNONE,	{FRT,PSD,RA,PSW,PSQ}},
 {"lfq",		OP(56),		OP_MASK,     POWER2,	PPCNONE,	{FRT, D, RA0}},
 
-{"lfdp",	OP(57),		OP_MASK,     POWER6,	POWER7,		{FRT, D, RA0}},
+{"lfdp",	OP(57),		OP_MASK,     POWER6,	POWER7,		{FRTp, D, RA0}},
 {"psq_lu",	OP(57),		OP_MASK,     PPCPS,	PPCNONE,	{FRT,PSD,RA,PSW,PSQ}},
 {"lfqu",	OP(57),		OP_MASK,     POWER2,	PPCNONE,	{FRT, D, RA0}},
 
@@ -5132,7 +5199,7 @@ const struct powerpc_opcode powerpc_opco
 {"psq_st",	OP(60),		OP_MASK,     PPCPS,	PPCNONE,	{FRS,PSD,RA,PSW,PSQ}},
 {"stfq",	OP(60),		OP_MASK,     POWER2,	PPCNONE,	{FRS, D, RA}},
 
-{"stfdp",	OP(61),		OP_MASK,     POWER6,	PPCNONE,	{FRT, D, RA0}},
+{"stfdp",	OP(61),		OP_MASK,     POWER6,	POWER7,		{FRSp, D, RA0}},
 {"psq_stu",	OP(61),		OP_MASK,     PPCPS,	PPCNONE,	{FRS,PSD,RA,PSW,PSQ}},
 {"stfqu",	OP(61),		OP_MASK,     POWER2,	PPCNONE,	{FRS, D, RA}},
 
@@ -5142,11 +5209,11 @@ const struct powerpc_opcode powerpc_opco
 
 {"fcmpu",	X(63,0),     X_MASK|(3<<21), COM,	PPCEFS,		{BF, FRA, FRB}},
 
-{"daddq",	XRC(63,2,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
-{"daddq.",	XRC(63,2,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
+{"daddq",	XRC(63,2,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
+{"daddq.",	XRC(63,2,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
 
-{"dquaq",	ZRC(63,3,0),	Z2_MASK,     POWER6,	PPCNONE,	{FRT, FRA, FRB, RMC}},
-{"dquaq.",	ZRC(63,3,1),	Z2_MASK,     POWER6,	PPCNONE,	{FRT, FRA, FRB, RMC}},
+{"dquaq",	ZRC(63,3,0),	Z2_MASK,     POWER6,	PPCNONE,	{FRTp, FRAp, FRBp, RMC}},
+{"dquaq.",	ZRC(63,3,1),	Z2_MASK,     POWER6,	PPCNONE,	{FRTp, FRAp, FRBp, RMC}},
 
 {"fcpsgn",	XRC(63,8,0),	X_MASK, POWER6|PPCA2|PPC476, PPCNONE,	{FRT, FRA, FRB}},
 {"fcpsgn.",	XRC(63,8,1),	X_MASK, POWER6|PPCA2|PPC476, PPCNONE,	{FRT, FRA, FRB}},
@@ -5222,11 +5289,11 @@ const struct powerpc_opcode powerpc_opco
 
 {"fcmpo",	X(63,32),    X_MASK|(3<<21), COM,	PPCEFS,		{BF, FRA, FRB}},
 
-{"dmulq",	XRC(63,34,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
-{"dmulq.",	XRC(63,34,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
+{"dmulq",	XRC(63,34,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
+{"dmulq.",	XRC(63,34,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
 
-{"drrndq",	ZRC(63,35,0),	Z2_MASK,     POWER6,	PPCNONE,	{FRT, FRA, FRB, RMC}},
-{"drrndq.",	ZRC(63,35,1),	Z2_MASK,     POWER6,	PPCNONE,	{FRT, FRA, FRB, RMC}},
+{"drrndq",	ZRC(63,35,0),	Z2_MASK,     POWER6,	PPCNONE,	{FRTp, FRAp, FRBp, RMC}},
+{"drrndq.",	ZRC(63,35,1),	Z2_MASK,     POWER6,	PPCNONE,	{FRTp, FRAp, FRBp, RMC}},
 
 {"mtfsb1",	XRC(63,38,0),	XRARB_MASK,  COM,	PPCNONE,	{BT}},
 {"mtfsb1.",	XRC(63,38,1),	XRARB_MASK,  COM,	PPCNONE,	{BT}},
@@ -5236,11 +5303,11 @@ const struct powerpc_opcode powerpc_opco
 
 {"mcrfs",      X(63,64), XRB_MASK|(3<<21)|(3<<16), COM,	PPCNONE,	{BF, BFA}},
 
-{"dscliq",	ZRC(63,66,0),	Z_MASK,      POWER6,	PPCNONE,	{FRT, FRA, SH16}},
-{"dscliq.",	ZRC(63,66,1),	Z_MASK,      POWER6,	PPCNONE,	{FRT, FRA, SH16}},
+{"dscliq",	ZRC(63,66,0),	Z_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, SH16}},
+{"dscliq.",	ZRC(63,66,1),	Z_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, SH16}},
 
-{"dquaiq",	ZRC(63,67,0),	Z2_MASK,     POWER6,	PPCNONE,	{TE, FRT, FRB, RMC}},
-{"dquaiq.",	ZRC(63,67,1),	Z2_MASK,     POWER6,	PPCNONE,	{TE, FRT, FRB, RMC}},
+{"dquaiq",	ZRC(63,67,0),	Z2_MASK,     POWER6,	PPCNONE,	{TE, FRTp, FRBp, RMC}},
+{"dquaiq.",	ZRC(63,67,1),	Z2_MASK,     POWER6,	PPCNONE,	{TE, FRTp, FRBp, RMC}},
 
 {"mtfsb0",	XRC(63,70,0),	XRARB_MASK,  COM,	PPCNONE,	{BT}},
 {"mtfsb0.",	XRC(63,70,1),	XRARB_MASK,  COM,	PPCNONE,	{BT}},
@@ -5248,15 +5315,15 @@ const struct powerpc_opcode powerpc_opco
 {"fmr",		XRC(63,72,0),	XRA_MASK,    COM,	PPCEFS,		{FRT, FRB}},
 {"fmr.",	XRC(63,72,1),	XRA_MASK,    COM,	PPCEFS,		{FRT, FRB}},
 
-{"dscriq",	ZRC(63,98,0),	Z_MASK,      POWER6,	PPCNONE,	{FRT, FRA, SH16}},
-{"dscriq.",	ZRC(63,98,1),	Z_MASK,      POWER6,	PPCNONE,	{FRT, FRA, SH16}},
+{"dscriq",	ZRC(63,98,0),	Z_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, SH16}},
+{"dscriq.",	ZRC(63,98,1),	Z_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, SH16}},
 
-{"drintxq",	ZRC(63,99,0),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRT, FRB, RMC}},
-{"drintxq.",	ZRC(63,99,1),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRT, FRB, RMC}},
+{"drintxq",	ZRC(63,99,0),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRTp, FRBp, RMC}},
+{"drintxq.",	ZRC(63,99,1),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRTp, FRBp, RMC}},
 
 {"ftdiv",	X(63,128),   X_MASK|(3<<21), POWER7,	PPCNONE,	{BF, FRA, FRB}},
 
-{"dcmpoq",	X(63,130),	X_MASK,      POWER6,	PPCNONE,	{BF, FRA, FRB}},
+{"dcmpoq",	X(63,130),	X_MASK,      POWER6,	PPCNONE,	{BF, FRAp, FRBp}},
 
 {"mtfsfi",  XRC(63,134,0), XWRA_MASK|(3<<21)|(1<<11), POWER6|PPCA2|PPC476, PPCNONE, {BFF, U, W}},
 {"mtfsfi",  XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), COM, POWER6|PPCA2|PPC476, {BFF, U}},
@@ -5273,27 +5340,27 @@ const struct powerpc_opcode powerpc_opco
 
 {"ftsqrt",	X(63,160), X_MASK|(3<<21|FRA_MASK), POWER7, PPCNONE,	{BF, FRB}},
 
-{"dtstexq",	X(63,162),	X_MASK,      POWER6,	PPCNONE,	{BF, FRA, FRB}},
-{"dtstdcq",	Z(63,194),	Z_MASK,      POWER6,	PPCNONE,	{BF, FRA, DCM}},
-{"dtstdgq",	Z(63,226),	Z_MASK,      POWER6,	PPCNONE,	{BF, FRA, DGM}},
+{"dtstexq",	X(63,162),	X_MASK,      POWER6,	PPCNONE,	{BF, FRAp, FRB}},
+{"dtstdcq",	Z(63,194),	Z_MASK,      POWER6,	PPCNONE,	{BF, FRAp, DCM}},
+{"dtstdgq",	Z(63,226),	Z_MASK,      POWER6,	PPCNONE,	{BF, FRAp, DGM}},
 
-{"drintnq",	ZRC(63,227,0),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRT, FRB, RMC}},
-{"drintnq.",	ZRC(63,227,1),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRT, FRB, RMC}},
+{"drintnq",	ZRC(63,227,0),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRTp, FRBp, RMC}},
+{"drintnq.",	ZRC(63,227,1),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRTp, FRBp, RMC}},
 
-{"dctqpq",	XRC(63,258,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
-{"dctqpq.",	XRC(63,258,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
+{"dctqpq",	XRC(63,258,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
+{"dctqpq.",	XRC(63,258,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
 
 {"fabs",	XRC(63,264,0),	XRA_MASK,    COM,	PPCEFS,		{FRT, FRB}},
 {"fabs.",	XRC(63,264,1),	XRA_MASK,    COM,	PPCEFS,		{FRT, FRB}},
 
-{"dctfixq",	XRC(63,290,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
-{"dctfixq.",	XRC(63,290,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
+{"dctfixq",	XRC(63,290,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
+{"dctfixq.",	XRC(63,290,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
 
-{"ddedpdq",	XRC(63,322,0),	X_MASK,      POWER6,	PPCNONE,	{SP, FRT, FRB}},
-{"ddedpdq.",	XRC(63,322,1),	X_MASK,      POWER6,	PPCNONE,	{SP, FRT, FRB}},
+{"ddedpdq",	XRC(63,322,0),	X_MASK,      POWER6,	PPCNONE,	{SP, FRTp, FRBp}},
+{"ddedpdq.",	XRC(63,322,1),	X_MASK,      POWER6,	PPCNONE,	{SP, FRTp, FRBp}},
 
-{"dxexq",	XRC(63,354,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
-{"dxexq.",	XRC(63,354,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
+{"dxexq",	XRC(63,354,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
+{"dxexq.",	XRC(63,354,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
 
 {"frin",	XRC(63,392,0),	XRA_MASK,    POWER5,	PPCNONE,	{FRT, FRB}},
 {"frin.",	XRC(63,392,1),	XRA_MASK,    POWER5,	PPCNONE,	{FRT, FRB}},
@@ -5304,29 +5371,29 @@ const struct powerpc_opcode powerpc_opco
 {"frim",	XRC(63,488,0),	XRA_MASK,    POWER5,	PPCNONE,	{FRT, FRB}},
 {"frim.",	XRC(63,488,1),	XRA_MASK,    POWER5,	PPCNONE,	{FRT, FRB}},
 
-{"dsubq",	XRC(63,514,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
-{"dsubq.",	XRC(63,514,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
+{"dsubq",	XRC(63,514,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
+{"dsubq.",	XRC(63,514,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
 
-{"ddivq",	XRC(63,546,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
-{"ddivq.",	XRC(63,546,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
+{"ddivq",	XRC(63,546,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
+{"ddivq.",	XRC(63,546,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
 
 {"mffs",	XRC(63,583,0),	XRARB_MASK,  COM,	PPCEFS,		{FRT}},
 {"mffs.",	XRC(63,583,1),	XRARB_MASK,  COM,	PPCEFS,		{FRT}},
 
-{"dcmpuq",	X(63,642),	X_MASK,      POWER6,	PPCNONE,	{BF, FRA, FRB}},
+{"dcmpuq",	X(63,642),	X_MASK,      POWER6,	PPCNONE,	{BF, FRAp, FRBp}},
 
-{"dtstsfq",	X(63,674),	X_MASK,      POWER6,	PPCNONE,	{BF, FRA, FRB}},
+{"dtstsfq",	X(63,674),	X_MASK,      POWER6,	PPCNONE,	{BF, FRAp, FRBp}},
 
 {"mtfsf",	XFL(63,711,0),	XFL_MASK, POWER6|PPCA2|PPC476, PPCNONE,	{FLM, FRB, XFL_L, W}},
 {"mtfsf",	XFL(63,711,0),	XFL_MASK,    COM, POWER6|PPCA2|PPC476|PPCEFS,	{FLM, FRB}},
 {"mtfsf.",	XFL(63,711,1),	XFL_MASK, POWER6|PPCA2|PPC476, PPCNONE,	{FLM, FRB, XFL_L, W}},
 {"mtfsf.",	XFL(63,711,1),	XFL_MASK,    COM, POWER6|PPCA2|PPC476|PPCEFS,	{FLM, FRB}},
 
-{"drdpq",	XRC(63,770,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
-{"drdpq.",	XRC(63,770,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
+{"drdpq",	XRC(63,770,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
+{"drdpq.",	XRC(63,770,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
 
-{"dcffixq",	XRC(63,802,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
-{"dcffixq.",	XRC(63,802,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
+{"dcffixq",	XRC(63,802,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
+{"dcffixq.",	XRC(63,802,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
 
 {"fctid",	XRC(63,814,0),	XRA_MASK,    PPC64,	PPCNONE,	{FRT, FRB}},
 {"fctid",	XRC(63,814,0),	XRA_MASK,    PPC476,	PPCNONE,	{FRT, FRB}},
@@ -5338,16 +5405,16 @@ const struct powerpc_opcode powerpc_opco
 {"fctidz.",	XRC(63,815,1),	XRA_MASK,    PPC64,	PPCNONE,	{FRT, FRB}},
 {"fctidz.",	XRC(63,815,1),	XRA_MASK,    PPC476,	PPCNONE,	{FRT, FRB}},
 
-{"denbcdq",	XRC(63,834,0),	X_MASK,      POWER6,	PPCNONE,	{S, FRT, FRB}},
-{"denbcdq.",	XRC(63,834,1),	X_MASK,      POWER6,	PPCNONE,	{S, FRT, FRB}},
+{"denbcdq",	XRC(63,834,0),	X_MASK,      POWER6,	PPCNONE,	{S, FRTp, FRBp}},
+{"denbcdq.",	XRC(63,834,1),	X_MASK,      POWER6,	PPCNONE,	{S, FRTp, FRBp}},
 
 {"fcfid",	XRC(63,846,0),	XRA_MASK,    PPC64,	PPCNONE,	{FRT, FRB}},
 {"fcfid",	XRC(63,846,0),	XRA_MASK,    PPC476,	PPCNONE,	{FRT, FRB}},
 {"fcfid.",	XRC(63,846,1),	XRA_MASK,    PPC64,	PPCNONE,	{FRT, FRB}},
 {"fcfid.",	XRC(63,846,1),	XRA_MASK,    PPC476,	PPCNONE,	{FRT, FRB}},
 
-{"diexq",	XRC(63,866,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
-{"diexq.",	XRC(63,866,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
+{"diexq",	XRC(63,866,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
+{"diexq.",	XRC(63,866,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
 
 {"fctidu",	XRC(63,942,0),	XRA_MASK, POWER7|PPCA2,	PPCNONE,	{FRT, FRB}},
 {"fctidu.",	XRC(63,942,1),	XRA_MASK, POWER7|PPCA2,	PPCNONE,	{FRT, FRB}},



[-- Attachment #2: binutils-mainline-PPC.patch --]
[-- Type: text/plain, Size: 23631 bytes --]

While updating test cases for another disassembler I noticed a number of
cases where supposedly (as per the documentation) invalid instructions are
being happily accepted by the assembler. These were
- bcctr with a condition accessing the count register,
- lswi and lswx loading into their address register,
- lfdp{,x}, stfdp{,x}, and the DFP quad instructions accessing odd numbered
  register pairs.

Additionally I found that while lfdp{,x} get rejected as invalid for POWER7
as specified, stfdp{,x} were accepted.

There is one more case that this patch doesn't address (due it being unclear
to me how to actually do so): Instructions invalid in little endian mode (in
the server environment).

Finally I noticed that even in the documentation there is a pseudo opcode
apparently missing: While xvmov{d,s}p are aliases of xvcpsgn{d,s}p, there's
no xsmovdp alias of xscpsgndp.

gas/testsuite/
2011-09-28  Jan Beulich  <jbeulich@suse.com>

	* gas/ppc/476.s: Fix lswi first operand.
	* gas/ppc/476.d: Adjust expected output.
	* gas/ppc/a2.s: Fix lswi first operand.
	* gas/ppc/a2.d: Adjust expected output.
	* gas/ppc/power6.s: Fix lfdpx first operand.
	* gas/ppc/power6.d: Adjust expected output.

opcodes/
2011-09-28  Jan Beulich  <jbeulich@suse.com>

	* ppc-opc.c (insert_nbi, insert_rbx, FRAp, FRBp, FRSp, FRTp, NBI, RAX,
	RBX): New.
	(insert_bo, insert_boe): Reject bcctr with bit 2 in bo unset.
	(powerpc_opcodes): Use RAX for second and RBXC for third operand of
	lswx. Use NBI for third operand of lswi. Use FRTp for first operand of
	lfdp and lfdpx. Use FRSp for first operand of stfdp and stfdpx, and
	mark them as invalid on POWER7. Use FRTp, FRAp, and FRBp repsectively
	on DFP quad instructions.

--- 2011-09-28/gas/testsuite/gas/ppc/476.d	2010-05-07 15:46:10.000000000 +0200
+++ 2011-09-28/gas/testsuite/gas/ppc/476.d	2011-09-28 12:43:20.000000000 +0200
@@ -234,7 +234,7 @@ Disassembly of section \.text:
  380:	7e 96 c2 6e 	lhzux   r20,r22,r24
  384:	7e f8 ca 2e 	lhzx    r23,r24,r25
  388:	b8 61 ff f0 	lmw     r3,-16\(r1\)
- 38c:	7c 64 84 aa 	lswi    r3,r4,16
+ 38c:	7c a4 84 aa 	lswi    r5,r4,16
  390:	7c 64 2c 2a 	lswx    r3,r4,r5
  394:	7c 64 28 28 	lwarx   r3,r4,r5
  398:	7c 64 28 28 	lwarx   r3,r4,r5
--- 2011-09-28/gas/testsuite/gas/ppc/476.s	2010-05-07 15:46:10.000000000 +0200
+++ 2011-09-28/gas/testsuite/gas/ppc/476.s	2011-09-28 12:43:20.000000000 +0200
@@ -227,7 +227,7 @@ ppc476:
 	lhzux	20,22,24
 	lhzx	23,24,25
 	lmw	3,-16(1)
-	lswi	3,4,16
+	lswi	5,4,16
 	lswx	3,4,5
 	lwarx	3,4,5
 	lwarx	3,4,5,0
--- 2011-09-28/gas/testsuite/gas/ppc/a2.d	2010-06-09 17:04:13.000000000 +0200
+++ 2011-09-28/gas/testsuite/gas/ppc/a2.d	2011-09-28 12:43:20.000000000 +0200
@@ -322,7 +322,7 @@ Disassembly of section \.text:
  498:	7d 4b 62 2e 	lhzx    r10,r11,r12
  49c:	ba 8a 00 10 	lmw     r20,16\(r10\)
  4a0:	7d 4b 0c aa 	lswi    r10,r11,1
- 4a4:	7d 4b 04 aa 	lswi    r10,r11,32
+ 4a4:	7d 8b 04 aa 	lswi    r12,r11,32
  4a8:	7d 4b 64 2a 	lswx    r10,r11,r12
  4ac:	e9 4b ff fe 	lwa     r10,-4\(r11\)
  4b0:	e9 4b 00 06 	lwa     r10,4\(r11\)
--- 2011-09-28/gas/testsuite/gas/ppc/a2.s	2010-05-07 15:46:10.000000000 +0200
+++ 2011-09-28/gas/testsuite/gas/ppc/a2.s	2011-09-28 12:43:20.000000000 +0200
@@ -297,7 +297,7 @@ start:
 	lhzx	10,11,12
 	lmw	20,16(10)
 	lswi	10,11,1
-	lswi	10,11,32
+	lswi	12,11,32
 	lswx	10,11,12
 	lwa	10,-4(11)
 	lwa	10,4(11)
--- 2011-09-28/gas/testsuite/gas/ppc/power6.d	2009-04-15 08:47:27.000000000 +0200
+++ 2011-09-28/gas/testsuite/gas/ppc/power6.d	2011-09-28 12:43:20.000000000 +0200
@@ -19,7 +19,7 @@ Disassembly of section \.text:
   24:	7c c0 3c be 	mffgpr  f6,r7
   28:	7d 00 4d be 	mftgpr  r8,f9
   2c:	7d 4b 66 2a 	lwzcix  r10,r11,r12
-  30:	7d ae 7e 2e 	lfdpx   f13,r14,r15
+  30:	7d 8e 7e 2e 	lfdpx   f12,r14,r15
   34:	ee 11 90 04 	dadd    f16,f17,f18
   38:	fe 96 c0 04 	daddq   f20,f22,f24
   3c:	7c 60 06 6c 	dss     3
--- 2011-09-28/gas/testsuite/gas/ppc/power6.s	2009-04-15 08:47:27.000000000 +0200
+++ 2011-09-28/gas/testsuite/gas/ppc/power6.s	2011-09-28 12:43:20.000000000 +0200
@@ -14,7 +14,7 @@ start:
 	mffgpr	6,7
 	mftgpr	8,9
 	lwzcix	10,11,12
-	lfdpx	13,14,15
+	lfdpx	12,14,15
 	dadd	16,17,18
 	daddq	20,22,24
 	dss	3
--- 2011-09-28/opcodes/ppc-opc.c	2011-05-13 08:38:04.000000000 +0200
+++ 2011-09-28/opcodes/ppc-opc.c	2011-09-28 12:43:20.000000000 +0200
@@ -58,6 +58,7 @@ static long extract_mbe (unsigned long, 
 static unsigned long insert_mb6 (unsigned long, long, ppc_cpu_t, const char **);
 static long extract_mb6 (unsigned long, ppc_cpu_t, int *);
 static long extract_nb (unsigned long, ppc_cpu_t, int *);
+static unsigned long insert_nbi (unsigned long, long, ppc_cpu_t, const char **);
 static unsigned long insert_nsi (unsigned long, long, ppc_cpu_t, const char **);
 static long extract_nsi (unsigned long, ppc_cpu_t, int *);
 static unsigned long insert_ral (unsigned long, long, ppc_cpu_t, const char **);
@@ -66,6 +67,7 @@ static unsigned long insert_raq (unsigne
 static unsigned long insert_ras (unsigned long, long, ppc_cpu_t, const char **);
 static unsigned long insert_rbs (unsigned long, long, ppc_cpu_t, const char **);
 static long extract_rbs (unsigned long, ppc_cpu_t, int *);
+static unsigned long insert_rbx (unsigned long, long, ppc_cpu_t, const char **);
 static unsigned long insert_sh6 (unsigned long, long, ppc_cpu_t, const char **);
 static long extract_sh6 (unsigned long, ppc_cpu_t, int *);
 static unsigned long insert_spr (unsigned long, long, ppc_cpu_t, const char **);
@@ -269,13 +271,21 @@ const struct powerpc_operand powerpc_ope
 #define FRA_MASK (0x1f << 16)
   { 0x1f, 16, NULL, NULL, PPC_OPERAND_FPR },
 
+  /* The FRAp field of DFP instructions.  */
+#define FRAp FRA + 1
+  { 0x1e, 16, NULL, NULL, PPC_OPERAND_FPR },
+
   /* The FRB field in an X or A form instruction.  */
-#define FRB FRA + 1
+#define FRB FRAp + 1
 #define FRB_MASK (0x1f << 11)
   { 0x1f, 11, NULL, NULL, PPC_OPERAND_FPR },
 
+  /* The FRBp field of DFP instructions.  */
+#define FRBp FRB + 1
+  { 0x1e, 11, NULL, NULL, PPC_OPERAND_FPR },
+
   /* The FRC field in an A form instruction.  */
-#define FRC FRB + 1
+#define FRC FRBp + 1
 #define FRC_MASK (0x1f << 6)
   { 0x1f, 6, NULL, NULL, PPC_OPERAND_FPR },
 
@@ -285,8 +295,14 @@ const struct powerpc_operand powerpc_ope
 #define FRT FRS
   { 0x1f, 21, NULL, NULL, PPC_OPERAND_FPR },
 
+  /* The FRSp field of stfdp or the FRTp field of lfdp and DFP
+     instructions.  */
+#define FRSp FRS + 1
+#define FRTp FRSp
+  { 0x1e, 21, NULL, NULL, PPC_OPERAND_FPR },
+
   /* The FXM field in an XFX instruction.  */
-#define FXM FRS + 1
+#define FXM FRSp + 1
   { 0xff, 12, insert_fxm, extract_fxm, 0 },
 
   /* Power4 version for mfcr.  */
@@ -345,9 +361,14 @@ const struct powerpc_operand powerpc_ope
 #define NB MB6 + 1
   { 0x1f, 11, NULL, extract_nb, PPC_OPERAND_PLUS1 },
 
+  /* The NBI field in an lswi instruction, which has special value
+     restrictions.  The value 32 is stored as 0.  */
+#define NBI NB + 1
+  { 0x1f, 11, insert_nbi, extract_nb, PPC_OPERAND_PLUS1 },
+
   /* The NSI field in a D form instruction.  This is the same as the
      SI field, only negated.  */
-#define NSI NB + 1
+#define NSI NBI + 1
   { 0xffff, 0, insert_nsi, extract_nsi,
       PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
 
@@ -360,9 +381,10 @@ const struct powerpc_operand powerpc_ope
 #define RA0 RA + 1
   { 0x1f, 16, NULL, NULL, PPC_OPERAND_GPR_0 },
 
-  /* The RA field in the DQ form lq instruction, which has special
+  /* The RA field in the DQ form lq or an lswx instruction, which have special
      value restrictions.  */
 #define RAQ RA0 + 1
+#define RAX RAQ
   { 0x1f, 16, insert_raq, NULL, PPC_OPERAND_GPR_0 },
 
   /* The RA field in a D or X form instruction which is an updating
@@ -398,8 +420,13 @@ const struct powerpc_operand powerpc_ope
 #define RBS RB + 1
   { 0x1f, 11, insert_rbs, extract_rbs, PPC_OPERAND_FAKE },
 
+  /* The RB field in an lswx instruction, which has special value
+     restrictions.  */
+#define RBX RBS + 1
+  { 0x1f, 11, insert_rbx, NULL, PPC_OPERAND_GPR },
+
   /* The RB field of the dccci and iccci instructions, which are optional.  */
-#define RBOPT RBS + 1
+#define RBOPT RBX + 1
   { 0x1f, 11, NULL, NULL, PPC_OPERAND_GPR | PPC_OPERAND_OPTIONAL },
 
   /* The RS field in a D, DS, X, XFX, XS, M, MD or MDS form
@@ -877,6 +904,8 @@ insert_bo (unsigned long insn,
 {
   if (!valid_bo (value, dialect, 0))
     *errmsg = _("invalid conditional option");
+  else if (PPC_OP (insn) == 19 && (insn & 0x400) && ! (value & 4))
+    *errmsg = _("invalid counter access");
   return insn | ((value & 0x1f) << 21);
 }
 
@@ -905,6 +934,8 @@ insert_boe (unsigned long insn,
 {
   if (!valid_bo (value, dialect, 0))
     *errmsg = _("invalid conditional option");
+  else if (PPC_OP (insn) == 19 && (insn & 0x400) && ! (value & 4))
+    *errmsg = _("invalid counter access");
   else if ((value & 1) != 0)
     *errmsg = _("attempt to set y bit when using + or - modifier");
 
@@ -1120,6 +1151,26 @@ extract_nb (unsigned long insn,
   return ret;
 }
 
+/* The NB field in an lswi instruction, which has special value
+   restrictions.  The value 32 is stored as 0.  */
+
+static unsigned long
+insert_nbi (unsigned long insn,
+	    long value,
+	    ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+	    const char **errmsg ATTRIBUTE_UNUSED)
+{
+  long rtvalue = (insn & RT_MASK) >> 21;
+  long ravalue = (insn & RA_MASK) >> 16;
+
+  if (value == 0)
+    value = 32;
+  if (rtvalue + (value + 3) / 4 > (rtvalue > ravalue ? ravalue + 32
+						     : ravalue))
+    *errmsg = _("address register in load range");
+  return insn | ((value & 0x1f) << 11);
+}
+
 /* The NSI field in a D form instruction.  This is the same as the SI
    field, only negated.  The extraction function always marks it as
    invalid, since we never want to recognize an instruction which uses
@@ -1173,7 +1224,7 @@ insert_ram (unsigned long insn,
   return insn | ((value & 0x1f) << 16);
 }
 
-/* The RA field in the DQ form lq instruction, which has special
+/* The RA field in the DQ form lq or an lswx instruction, which have special
    value restrictions.  */
 
 static unsigned long
@@ -1229,6 +1280,22 @@ extract_rbs (unsigned long insn,
   return 0;
 }
 
+/* The RB field in an lswx instruction, which has special value
+   restrictions.  */
+
+static unsigned long
+insert_rbx (unsigned long insn,
+	    long value,
+	    ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+	    const char **errmsg)
+{
+  long rtvalue = (insn & RT_MASK) >> 21;
+
+  if (value == rtvalue)
+    *errmsg = _("source and target register operands must be different");
+  return insn | ((value & 0x1f) << 11);
+}
+
 /* The SH field in an MD form instruction.  This is split.  */
 
 static unsigned long
@@ -4421,7 +4488,7 @@ const struct powerpc_opcode powerpc_opco
 
 {"ldbrx",	X(31,532),	X_MASK, CELL|POWER7|PPCA2, PPCNONE,	{RT, RA0, RB}},
 
-{"lswx",	X(31,533),	X_MASK,      PPCCOM,	E500|E500MC,	{RT, RA0, RB}},
+{"lswx",	X(31,533),	X_MASK,      PPCCOM,	E500|E500MC,	{RT, RAX, RBX}},
 {"lsx",		X(31,533),	X_MASK,      PWRCOM,	PPCNONE,	{RT, RA, RB}},
 
 {"lwbrx",	X(31,534),	X_MASK,      PPCCOM,	PPCNONE,	{RT, RA0, RB}},
@@ -4467,7 +4534,7 @@ const struct powerpc_opcode powerpc_opco
 
 {"mfsr",	X(31,595), XRB_MASK|(1<<20), COM,	NON32,  	{RT, SR}},
 
-{"lswi",	X(31,597),	X_MASK,      PPCCOM,	E500|E500MC,	{RT, RA0, NB}},
+{"lswi",	X(31,597),	X_MASK,      PPCCOM,	E500|E500MC,	{RT, RA0, NBI}},
 {"lsi",		X(31,597),	X_MASK,      PWRCOM,	PPCNONE,	{RT, RA0, NB}},
 
 {"lwsync",	XSYNC(31,598,1), 0xffffffff, PPC,	E500,		{0}},
@@ -4625,7 +4692,7 @@ const struct powerpc_opcode powerpc_opco
 
 {"lhbrx",	X(31,790),	X_MASK,      COM,	PPCNONE,	{RT, RA0, RB}},
 
-{"lfdpx",	X(31,791),	X_MASK,      POWER6,	POWER7,		{FRT, RA, RB}},
+{"lfdpx",	X(31,791),	X_MASK,      POWER6,	POWER7,		{FRTp, RA, RB}},
 {"lfqx",	X(31,791),	X_MASK,      POWER2,	PPCNONE,	{FRT, RA, RB}},
 
 {"sraw",	XRC(31,792,0),	X_MASK,      PPCCOM,	PPCNONE,	{RA, RS, RB}},
@@ -4705,7 +4772,7 @@ const struct powerpc_opcode powerpc_opco
 
 {"sthbrx",	X(31,918),	X_MASK,      COM,	PPCNONE,	{RS, RA0, RB}},
 
-{"stfdpx",	X(31,919),	X_MASK,      POWER6,	PPCNONE,	{FRS, RA, RB}},
+{"stfdpx",	X(31,919),	X_MASK,      POWER6,	POWER7,		{FRSp, RA, RB}},
 {"stfqx",	X(31,919),	X_MASK,      POWER2,	PPCNONE,	{FRS, RA, RB}},
 
 {"sraq",	XRC(31,920,0),	X_MASK,      M601,	PPCNONE,	{RA, RS, RB}},
@@ -4869,7 +4936,7 @@ const struct powerpc_opcode powerpc_opco
 {"psq_l",	OP(56),		OP_MASK,     PPCPS,	PPCNONE,	{FRT,PSD,RA,PSW,PSQ}},
 {"lfq",		OP(56),		OP_MASK,     POWER2,	PPCNONE,	{FRT, D, RA0}},
 
-{"lfdp",	OP(57),		OP_MASK,     POWER6,	POWER7,		{FRT, D, RA0}},
+{"lfdp",	OP(57),		OP_MASK,     POWER6,	POWER7,		{FRTp, D, RA0}},
 {"psq_lu",	OP(57),		OP_MASK,     PPCPS,	PPCNONE,	{FRT,PSD,RA,PSW,PSQ}},
 {"lfqu",	OP(57),		OP_MASK,     POWER2,	PPCNONE,	{FRT, D, RA0}},
 
@@ -5132,7 +5199,7 @@ const struct powerpc_opcode powerpc_opco
 {"psq_st",	OP(60),		OP_MASK,     PPCPS,	PPCNONE,	{FRS,PSD,RA,PSW,PSQ}},
 {"stfq",	OP(60),		OP_MASK,     POWER2,	PPCNONE,	{FRS, D, RA}},
 
-{"stfdp",	OP(61),		OP_MASK,     POWER6,	PPCNONE,	{FRT, D, RA0}},
+{"stfdp",	OP(61),		OP_MASK,     POWER6,	POWER7,		{FRSp, D, RA0}},
 {"psq_stu",	OP(61),		OP_MASK,     PPCPS,	PPCNONE,	{FRS,PSD,RA,PSW,PSQ}},
 {"stfqu",	OP(61),		OP_MASK,     POWER2,	PPCNONE,	{FRS, D, RA}},
 
@@ -5142,11 +5209,11 @@ const struct powerpc_opcode powerpc_opco
 
 {"fcmpu",	X(63,0),     X_MASK|(3<<21), COM,	PPCEFS,		{BF, FRA, FRB}},
 
-{"daddq",	XRC(63,2,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
-{"daddq.",	XRC(63,2,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
+{"daddq",	XRC(63,2,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
+{"daddq.",	XRC(63,2,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
 
-{"dquaq",	ZRC(63,3,0),	Z2_MASK,     POWER6,	PPCNONE,	{FRT, FRA, FRB, RMC}},
-{"dquaq.",	ZRC(63,3,1),	Z2_MASK,     POWER6,	PPCNONE,	{FRT, FRA, FRB, RMC}},
+{"dquaq",	ZRC(63,3,0),	Z2_MASK,     POWER6,	PPCNONE,	{FRTp, FRAp, FRBp, RMC}},
+{"dquaq.",	ZRC(63,3,1),	Z2_MASK,     POWER6,	PPCNONE,	{FRTp, FRAp, FRBp, RMC}},
 
 {"fcpsgn",	XRC(63,8,0),	X_MASK, POWER6|PPCA2|PPC476, PPCNONE,	{FRT, FRA, FRB}},
 {"fcpsgn.",	XRC(63,8,1),	X_MASK, POWER6|PPCA2|PPC476, PPCNONE,	{FRT, FRA, FRB}},
@@ -5222,11 +5289,11 @@ const struct powerpc_opcode powerpc_opco
 
 {"fcmpo",	X(63,32),    X_MASK|(3<<21), COM,	PPCEFS,		{BF, FRA, FRB}},
 
-{"dmulq",	XRC(63,34,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
-{"dmulq.",	XRC(63,34,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
+{"dmulq",	XRC(63,34,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
+{"dmulq.",	XRC(63,34,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
 
-{"drrndq",	ZRC(63,35,0),	Z2_MASK,     POWER6,	PPCNONE,	{FRT, FRA, FRB, RMC}},
-{"drrndq.",	ZRC(63,35,1),	Z2_MASK,     POWER6,	PPCNONE,	{FRT, FRA, FRB, RMC}},
+{"drrndq",	ZRC(63,35,0),	Z2_MASK,     POWER6,	PPCNONE,	{FRTp, FRAp, FRBp, RMC}},
+{"drrndq.",	ZRC(63,35,1),	Z2_MASK,     POWER6,	PPCNONE,	{FRTp, FRAp, FRBp, RMC}},
 
 {"mtfsb1",	XRC(63,38,0),	XRARB_MASK,  COM,	PPCNONE,	{BT}},
 {"mtfsb1.",	XRC(63,38,1),	XRARB_MASK,  COM,	PPCNONE,	{BT}},
@@ -5236,11 +5303,11 @@ const struct powerpc_opcode powerpc_opco
 
 {"mcrfs",      X(63,64), XRB_MASK|(3<<21)|(3<<16), COM,	PPCNONE,	{BF, BFA}},
 
-{"dscliq",	ZRC(63,66,0),	Z_MASK,      POWER6,	PPCNONE,	{FRT, FRA, SH16}},
-{"dscliq.",	ZRC(63,66,1),	Z_MASK,      POWER6,	PPCNONE,	{FRT, FRA, SH16}},
+{"dscliq",	ZRC(63,66,0),	Z_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, SH16}},
+{"dscliq.",	ZRC(63,66,1),	Z_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, SH16}},
 
-{"dquaiq",	ZRC(63,67,0),	Z2_MASK,     POWER6,	PPCNONE,	{TE, FRT, FRB, RMC}},
-{"dquaiq.",	ZRC(63,67,1),	Z2_MASK,     POWER6,	PPCNONE,	{TE, FRT, FRB, RMC}},
+{"dquaiq",	ZRC(63,67,0),	Z2_MASK,     POWER6,	PPCNONE,	{TE, FRTp, FRBp, RMC}},
+{"dquaiq.",	ZRC(63,67,1),	Z2_MASK,     POWER6,	PPCNONE,	{TE, FRTp, FRBp, RMC}},
 
 {"mtfsb0",	XRC(63,70,0),	XRARB_MASK,  COM,	PPCNONE,	{BT}},
 {"mtfsb0.",	XRC(63,70,1),	XRARB_MASK,  COM,	PPCNONE,	{BT}},
@@ -5248,15 +5315,15 @@ const struct powerpc_opcode powerpc_opco
 {"fmr",		XRC(63,72,0),	XRA_MASK,    COM,	PPCEFS,		{FRT, FRB}},
 {"fmr.",	XRC(63,72,1),	XRA_MASK,    COM,	PPCEFS,		{FRT, FRB}},
 
-{"dscriq",	ZRC(63,98,0),	Z_MASK,      POWER6,	PPCNONE,	{FRT, FRA, SH16}},
-{"dscriq.",	ZRC(63,98,1),	Z_MASK,      POWER6,	PPCNONE,	{FRT, FRA, SH16}},
+{"dscriq",	ZRC(63,98,0),	Z_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, SH16}},
+{"dscriq.",	ZRC(63,98,1),	Z_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, SH16}},
 
-{"drintxq",	ZRC(63,99,0),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRT, FRB, RMC}},
-{"drintxq.",	ZRC(63,99,1),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRT, FRB, RMC}},
+{"drintxq",	ZRC(63,99,0),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRTp, FRBp, RMC}},
+{"drintxq.",	ZRC(63,99,1),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRTp, FRBp, RMC}},
 
 {"ftdiv",	X(63,128),   X_MASK|(3<<21), POWER7,	PPCNONE,	{BF, FRA, FRB}},
 
-{"dcmpoq",	X(63,130),	X_MASK,      POWER6,	PPCNONE,	{BF, FRA, FRB}},
+{"dcmpoq",	X(63,130),	X_MASK,      POWER6,	PPCNONE,	{BF, FRAp, FRBp}},
 
 {"mtfsfi",  XRC(63,134,0), XWRA_MASK|(3<<21)|(1<<11), POWER6|PPCA2|PPC476, PPCNONE, {BFF, U, W}},
 {"mtfsfi",  XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), COM, POWER6|PPCA2|PPC476, {BFF, U}},
@@ -5273,27 +5340,27 @@ const struct powerpc_opcode powerpc_opco
 
 {"ftsqrt",	X(63,160), X_MASK|(3<<21|FRA_MASK), POWER7, PPCNONE,	{BF, FRB}},
 
-{"dtstexq",	X(63,162),	X_MASK,      POWER6,	PPCNONE,	{BF, FRA, FRB}},
-{"dtstdcq",	Z(63,194),	Z_MASK,      POWER6,	PPCNONE,	{BF, FRA, DCM}},
-{"dtstdgq",	Z(63,226),	Z_MASK,      POWER6,	PPCNONE,	{BF, FRA, DGM}},
+{"dtstexq",	X(63,162),	X_MASK,      POWER6,	PPCNONE,	{BF, FRAp, FRB}},
+{"dtstdcq",	Z(63,194),	Z_MASK,      POWER6,	PPCNONE,	{BF, FRAp, DCM}},
+{"dtstdgq",	Z(63,226),	Z_MASK,      POWER6,	PPCNONE,	{BF, FRAp, DGM}},
 
-{"drintnq",	ZRC(63,227,0),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRT, FRB, RMC}},
-{"drintnq.",	ZRC(63,227,1),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRT, FRB, RMC}},
+{"drintnq",	ZRC(63,227,0),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRTp, FRBp, RMC}},
+{"drintnq.",	ZRC(63,227,1),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRTp, FRBp, RMC}},
 
-{"dctqpq",	XRC(63,258,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
-{"dctqpq.",	XRC(63,258,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
+{"dctqpq",	XRC(63,258,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
+{"dctqpq.",	XRC(63,258,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
 
 {"fabs",	XRC(63,264,0),	XRA_MASK,    COM,	PPCEFS,		{FRT, FRB}},
 {"fabs.",	XRC(63,264,1),	XRA_MASK,    COM,	PPCEFS,		{FRT, FRB}},
 
-{"dctfixq",	XRC(63,290,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
-{"dctfixq.",	XRC(63,290,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
+{"dctfixq",	XRC(63,290,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
+{"dctfixq.",	XRC(63,290,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
 
-{"ddedpdq",	XRC(63,322,0),	X_MASK,      POWER6,	PPCNONE,	{SP, FRT, FRB}},
-{"ddedpdq.",	XRC(63,322,1),	X_MASK,      POWER6,	PPCNONE,	{SP, FRT, FRB}},
+{"ddedpdq",	XRC(63,322,0),	X_MASK,      POWER6,	PPCNONE,	{SP, FRTp, FRBp}},
+{"ddedpdq.",	XRC(63,322,1),	X_MASK,      POWER6,	PPCNONE,	{SP, FRTp, FRBp}},
 
-{"dxexq",	XRC(63,354,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
-{"dxexq.",	XRC(63,354,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
+{"dxexq",	XRC(63,354,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
+{"dxexq.",	XRC(63,354,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
 
 {"frin",	XRC(63,392,0),	XRA_MASK,    POWER5,	PPCNONE,	{FRT, FRB}},
 {"frin.",	XRC(63,392,1),	XRA_MASK,    POWER5,	PPCNONE,	{FRT, FRB}},
@@ -5304,29 +5371,29 @@ const struct powerpc_opcode powerpc_opco
 {"frim",	XRC(63,488,0),	XRA_MASK,    POWER5,	PPCNONE,	{FRT, FRB}},
 {"frim.",	XRC(63,488,1),	XRA_MASK,    POWER5,	PPCNONE,	{FRT, FRB}},
 
-{"dsubq",	XRC(63,514,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
-{"dsubq.",	XRC(63,514,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
+{"dsubq",	XRC(63,514,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
+{"dsubq.",	XRC(63,514,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
 
-{"ddivq",	XRC(63,546,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
-{"ddivq.",	XRC(63,546,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
+{"ddivq",	XRC(63,546,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
+{"ddivq.",	XRC(63,546,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
 
 {"mffs",	XRC(63,583,0),	XRARB_MASK,  COM,	PPCEFS,		{FRT}},
 {"mffs.",	XRC(63,583,1),	XRARB_MASK,  COM,	PPCEFS,		{FRT}},
 
-{"dcmpuq",	X(63,642),	X_MASK,      POWER6,	PPCNONE,	{BF, FRA, FRB}},
+{"dcmpuq",	X(63,642),	X_MASK,      POWER6,	PPCNONE,	{BF, FRAp, FRBp}},
 
-{"dtstsfq",	X(63,674),	X_MASK,      POWER6,	PPCNONE,	{BF, FRA, FRB}},
+{"dtstsfq",	X(63,674),	X_MASK,      POWER6,	PPCNONE,	{BF, FRAp, FRBp}},
 
 {"mtfsf",	XFL(63,711,0),	XFL_MASK, POWER6|PPCA2|PPC476, PPCNONE,	{FLM, FRB, XFL_L, W}},
 {"mtfsf",	XFL(63,711,0),	XFL_MASK,    COM, POWER6|PPCA2|PPC476|PPCEFS,	{FLM, FRB}},
 {"mtfsf.",	XFL(63,711,1),	XFL_MASK, POWER6|PPCA2|PPC476, PPCNONE,	{FLM, FRB, XFL_L, W}},
 {"mtfsf.",	XFL(63,711,1),	XFL_MASK,    COM, POWER6|PPCA2|PPC476|PPCEFS,	{FLM, FRB}},
 
-{"drdpq",	XRC(63,770,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
-{"drdpq.",	XRC(63,770,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
+{"drdpq",	XRC(63,770,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
+{"drdpq.",	XRC(63,770,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
 
-{"dcffixq",	XRC(63,802,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
-{"dcffixq.",	XRC(63,802,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRB}},
+{"dcffixq",	XRC(63,802,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
+{"dcffixq.",	XRC(63,802,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
 
 {"fctid",	XRC(63,814,0),	XRA_MASK,    PPC64,	PPCNONE,	{FRT, FRB}},
 {"fctid",	XRC(63,814,0),	XRA_MASK,    PPC476,	PPCNONE,	{FRT, FRB}},
@@ -5338,16 +5405,16 @@ const struct powerpc_opcode powerpc_opco
 {"fctidz.",	XRC(63,815,1),	XRA_MASK,    PPC64,	PPCNONE,	{FRT, FRB}},
 {"fctidz.",	XRC(63,815,1),	XRA_MASK,    PPC476,	PPCNONE,	{FRT, FRB}},
 
-{"denbcdq",	XRC(63,834,0),	X_MASK,      POWER6,	PPCNONE,	{S, FRT, FRB}},
-{"denbcdq.",	XRC(63,834,1),	X_MASK,      POWER6,	PPCNONE,	{S, FRT, FRB}},
+{"denbcdq",	XRC(63,834,0),	X_MASK,      POWER6,	PPCNONE,	{S, FRTp, FRBp}},
+{"denbcdq.",	XRC(63,834,1),	X_MASK,      POWER6,	PPCNONE,	{S, FRTp, FRBp}},
 
 {"fcfid",	XRC(63,846,0),	XRA_MASK,    PPC64,	PPCNONE,	{FRT, FRB}},
 {"fcfid",	XRC(63,846,0),	XRA_MASK,    PPC476,	PPCNONE,	{FRT, FRB}},
 {"fcfid.",	XRC(63,846,1),	XRA_MASK,    PPC64,	PPCNONE,	{FRT, FRB}},
 {"fcfid.",	XRC(63,846,1),	XRA_MASK,    PPC476,	PPCNONE,	{FRT, FRB}},
 
-{"diexq",	XRC(63,866,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
-{"diexq.",	XRC(63,866,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRA, FRB}},
+{"diexq",	XRC(63,866,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
+{"diexq.",	XRC(63,866,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
 
 {"fctidu",	XRC(63,942,0),	XRA_MASK, POWER7|PPCA2,	PPCNONE,	{FRT, FRB}},
 {"fctidu.",	XRC(63,942,1),	XRA_MASK, POWER7|PPCA2,	PPCNONE,	{FRT, FRB}},

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

* Re: [PATCH] PPC: reject more instructions with invalid operand  combinations
  2011-09-28 12:26 [PATCH] PPC: reject more instructions with invalid operand combinations Jan Beulich
@ 2011-10-06  1:14 ` Alan Modra
  2011-10-27  2:11 ` Peter Bergner
  1 sibling, 0 replies; 6+ messages in thread
From: Alan Modra @ 2011-10-06  1:14 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

On Wed, Sep 28, 2011 at 01:26:16PM +0100, Jan Beulich wrote:
> gas/testsuite/
> 2011-09-28  Jan Beulich  <jbeulich@suse.com>
> 
> 	* gas/ppc/476.s: Fix lswi first operand.
> 	* gas/ppc/476.d: Adjust expected output.
> 	* gas/ppc/a2.s: Fix lswi first operand.
> 	* gas/ppc/a2.d: Adjust expected output.
> 	* gas/ppc/power6.s: Fix lfdpx first operand.
> 	* gas/ppc/power6.d: Adjust expected output.
> 
> opcodes/
> 2011-09-28  Jan Beulich  <jbeulich@suse.com>
> 
> 	* ppc-opc.c (insert_nbi, insert_rbx, FRAp, FRBp, FRSp, FRTp, NBI, RAX,
> 	RBX): New.
> 	(insert_bo, insert_boe): Reject bcctr with bit 2 in bo unset.
> 	(powerpc_opcodes): Use RAX for second and RBXC for third operand of
> 	lswx. Use NBI for third operand of lswi. Use FRTp for first operand of
> 	lfdp and lfdpx. Use FRSp for first operand of stfdp and stfdpx, and
> 	mark them as invalid on POWER7. Use FRTp, FRAp, and FRBp repsectively
> 	on DFP quad instructions.

OK, thanks!

-- 
Alan Modra
Australia Development Lab, IBM

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

* Re: [PATCH] PPC: reject more instructions with invalid operand combinations
  2011-09-28 12:26 [PATCH] PPC: reject more instructions with invalid operand combinations Jan Beulich
  2011-10-06  1:14 ` Alan Modra
@ 2011-10-27  2:11 ` Peter Bergner
  2011-10-27  3:26   ` Alan Modra
  1 sibling, 1 reply; 6+ messages in thread
From: Peter Bergner @ 2011-10-27  2:11 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Alan Modra, binutils

On Wed, Sep 28, 2011 at 01:26:16PM +0100, Jan Beulich wrote:
> While updating test cases for another disassembler I noticed a number of
> cases where supposedly (as per the documentation) invalid instructions are
> being happily accepted by the assembler. These were
[snip]
> - lfdp{,x}, stfdp{,x}, and the DFP quad instructions accessing odd numbered
>   register pairs.

After Jan's patch, someone started complaining that the assembler started
erroring out on some valid DFP instructions.  Looking through the ISA
document, some of the quad DFP instructions take a combination of FR*p
and FR* operands, not just always FR*p operands.  

I've gone through the DFP instructions in the ISA doc and come up with
the following patch to correctly specify the type of allowed operands for
DFP instructions.

Alan, is this ok to commit?

opcodes/

        * ppc-opc.c (powerpc_opcodes) <drrndq, drrndq., dtstexq, dctqpq,
	dctqpq., dctfixq, dctfixq., dxexq, dxexq., dtstsfq, dcffixq, dcffixq.,
	diexq, diexq.>: Use FRT, FRA, FRB and FRBp repsectively on DFP quad
	instructions.

Index: opcodes/ppc-opc.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
retrieving revision 1.138
diff -u -p -r1.138 ppc-opc.c
--- opcodes/ppc-opc.c	6 Oct 2011 09:22:58 -0000	1.138
+++ opcodes/ppc-opc.c	26 Oct 2011 20:49:41 -0000
@@ -5292,8 +5292,8 @@ const struct powerpc_opcode powerpc_opco
 {"dmulq",	XRC(63,34,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
 {"dmulq.",	XRC(63,34,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
 
-{"drrndq",	ZRC(63,35,0),	Z2_MASK,     POWER6,	PPCNONE,	{FRTp, FRAp, FRBp, RMC}},
-{"drrndq.",	ZRC(63,35,1),	Z2_MASK,     POWER6,	PPCNONE,	{FRTp, FRAp, FRBp, RMC}},
+{"drrndq",	ZRC(63,35,0),	Z2_MASK,     POWER6,	PPCNONE,	{FRTp, FRA, FRBp, RMC}},
+{"drrndq.",	ZRC(63,35,1),	Z2_MASK,     POWER6,	PPCNONE,	{FRTp, FRA, FRBp, RMC}},
 
 {"mtfsb1",	XRC(63,38,0),	XRARB_MASK,  COM,	PPCNONE,	{BT}},
 {"mtfsb1.",	XRC(63,38,1),	XRARB_MASK,  COM,	PPCNONE,	{BT}},
@@ -5340,27 +5340,27 @@ const struct powerpc_opcode powerpc_opco
 
 {"ftsqrt",	X(63,160), X_MASK|(3<<21|FRA_MASK), POWER7, PPCNONE,	{BF, FRB}},
 
-{"dtstexq",	X(63,162),	X_MASK,      POWER6,	PPCNONE,	{BF, FRAp, FRB}},
+{"dtstexq",	X(63,162),	X_MASK,      POWER6,	PPCNONE,	{BF, FRAp, FRBp}},
 {"dtstdcq",	Z(63,194),	Z_MASK,      POWER6,	PPCNONE,	{BF, FRAp, DCM}},
 {"dtstdgq",	Z(63,226),	Z_MASK,      POWER6,	PPCNONE,	{BF, FRAp, DGM}},
 
 {"drintnq",	ZRC(63,227,0),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRTp, FRBp, RMC}},
 {"drintnq.",	ZRC(63,227,1),	Z2_MASK,     POWER6,	PPCNONE,	{R, FRTp, FRBp, RMC}},
 
-{"dctqpq",	XRC(63,258,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
-{"dctqpq.",	XRC(63,258,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
+{"dctqpq",	XRC(63,258,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRB}},
+{"dctqpq.",	XRC(63,258,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRB}},
 
 {"fabs",	XRC(63,264,0),	XRA_MASK,    COM,	PPCEFS,		{FRT, FRB}},
 {"fabs.",	XRC(63,264,1),	XRA_MASK,    COM,	PPCEFS,		{FRT, FRB}},
 
-{"dctfixq",	XRC(63,290,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
-{"dctfixq.",	XRC(63,290,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
+{"dctfixq",	XRC(63,290,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRBp}},
+{"dctfixq.",	XRC(63,290,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRBp}},
 
 {"ddedpdq",	XRC(63,322,0),	X_MASK,      POWER6,	PPCNONE,	{SP, FRTp, FRBp}},
 {"ddedpdq.",	XRC(63,322,1),	X_MASK,      POWER6,	PPCNONE,	{SP, FRTp, FRBp}},
 
-{"dxexq",	XRC(63,354,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
-{"dxexq.",	XRC(63,354,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
+{"dxexq",	XRC(63,354,0),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRBp}},
+{"dxexq.",	XRC(63,354,1),	X_MASK,      POWER6,	PPCNONE,	{FRT, FRBp}},
 
 {"frin",	XRC(63,392,0),	XRA_MASK,    POWER5,	PPCNONE,	{FRT, FRB}},
 {"frin.",	XRC(63,392,1),	XRA_MASK,    POWER5,	PPCNONE,	{FRT, FRB}},
@@ -5382,7 +5382,7 @@ const struct powerpc_opcode powerpc_opco
 
 {"dcmpuq",	X(63,642),	X_MASK,      POWER6,	PPCNONE,	{BF, FRAp, FRBp}},
 
-{"dtstsfq",	X(63,674),	X_MASK,      POWER6,	PPCNONE,	{BF, FRAp, FRBp}},
+{"dtstsfq",	X(63,674),	X_MASK,      POWER6,	PPCNONE,	{BF, FRA, FRBp}},
 
 {"mtfsf",	XFL(63,711,0),	XFL_MASK, POWER6|PPCA2|PPC476, PPCNONE,	{FLM, FRB, XFL_L, W}},
 {"mtfsf",	XFL(63,711,0),	XFL_MASK,    COM, POWER6|PPCA2|PPC476|PPCEFS,	{FLM, FRB}},
@@ -5392,8 +5392,8 @@ const struct powerpc_opcode powerpc_opco
 {"drdpq",	XRC(63,770,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
 {"drdpq.",	XRC(63,770,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
 
-{"dcffixq",	XRC(63,802,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
-{"dcffixq.",	XRC(63,802,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRBp}},
+{"dcffixq",	XRC(63,802,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRB}},
+{"dcffixq.",	XRC(63,802,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRB}},
 
 {"fctid",	XRC(63,814,0),	XRA_MASK,    PPC64,	PPCNONE,	{FRT, FRB}},
 {"fctid",	XRC(63,814,0),	XRA_MASK,    PPC476,	PPCNONE,	{FRT, FRB}},
@@ -5413,8 +5413,8 @@ const struct powerpc_opcode powerpc_opco
 {"fcfid.",	XRC(63,846,1),	XRA_MASK,    PPC64,	PPCNONE,	{FRT, FRB}},
 {"fcfid.",	XRC(63,846,1),	XRA_MASK,    PPC476,	PPCNONE,	{FRT, FRB}},
 
-{"diexq",	XRC(63,866,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
-{"diexq.",	XRC(63,866,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRAp, FRBp}},
+{"diexq",	XRC(63,866,0),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRA, FRBp}},
+{"diexq.",	XRC(63,866,1),	X_MASK,      POWER6,	PPCNONE,	{FRTp, FRA, FRBp}},
 
 {"fctidu",	XRC(63,942,0),	XRA_MASK, POWER7|PPCA2,	PPCNONE,	{FRT, FRB}},
 {"fctidu.",	XRC(63,942,1),	XRA_MASK, POWER7|PPCA2,	PPCNONE,	{FRT, FRB}},

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

* Re: [PATCH] PPC: reject more instructions with invalid operand combinations
  2011-10-27  2:11 ` Peter Bergner
@ 2011-10-27  3:26   ` Alan Modra
  2011-10-27 16:06     ` Peter Bergner
  2011-11-02  9:35     ` Jan Beulich
  0 siblings, 2 replies; 6+ messages in thread
From: Alan Modra @ 2011-10-27  3:26 UTC (permalink / raw)
  To: Peter Bergner; +Cc: Jan Beulich, binutils

On Wed, Oct 26, 2011 at 09:09:41PM -0500, Peter Bergner wrote:
>         * ppc-opc.c (powerpc_opcodes) <drrndq, drrndq., dtstexq, dctqpq,
> 	dctqpq., dctfixq, dctfixq., dxexq, dxexq., dtstsfq, dcffixq, dcffixq.,
> 	diexq, diexq.>: Use FRT, FRA, FRB and FRBp repsectively on DFP quad
> 	instructions.

OK, I'll trust you got these correct (and I'll check Jan's next ppc
patch a little more thoroughly ;-) ).  Please apply to the branch too.

-- 
Alan Modra
Australia Development Lab, IBM

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

* Re: [PATCH] PPC: reject more instructions with invalid operand combinations
  2011-10-27  3:26   ` Alan Modra
@ 2011-10-27 16:06     ` Peter Bergner
  2011-11-02  9:35     ` Jan Beulich
  1 sibling, 0 replies; 6+ messages in thread
From: Peter Bergner @ 2011-10-27 16:06 UTC (permalink / raw)
  To: Alan Modra; +Cc: Jan Beulich, binutils

On Thu, 2011-10-27 at 13:55 +1030, Alan Modra wrote:
> On Wed, Oct 26, 2011 at 09:09:41PM -0500, Peter Bergner wrote:
> >         * ppc-opc.c (powerpc_opcodes) <drrndq, drrndq., dtstexq, dctqpq,
> > 	dctqpq., dctfixq, dctfixq., dxexq, dxexq., dtstsfq, dcffixq, dcffixq.,
> > 	diexq, diexq.>: Use FRT, FRA, FRB and FRBp repsectively on DFP quad
> > 	instructions.
> 
> OK, I'll trust you got these correct  

Oh sure, put the pressure on me now! ;)  I double checked with the latest
ISA 2.06 V2 document and they match up with these changes.


> Please apply to the branch too.

Ok, committed to trunk and the branch.  Thanks.

Peter




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

* Re: [PATCH] PPC: reject more instructions with invalid operand  combinations
  2011-10-27  3:26   ` Alan Modra
  2011-10-27 16:06     ` Peter Bergner
@ 2011-11-02  9:35     ` Jan Beulich
  1 sibling, 0 replies; 6+ messages in thread
From: Jan Beulich @ 2011-11-02  9:35 UTC (permalink / raw)
  To: Alan Modra, Peter Bergner; +Cc: binutils

>>> On 27.10.11 at 05:25, Alan Modra <amodra@gmail.com> wrote:
> On Wed, Oct 26, 2011 at 09:09:41PM -0500, Peter Bergner wrote:
>>         * ppc-opc.c (powerpc_opcodes) <drrndq, drrndq., dtstexq, dctqpq,
>> 	dctqpq., dctfixq, dctfixq., dxexq, dxexq., dtstsfq, dcffixq, dcffixq.,
>> 	diexq, diexq.>: Use FRT, FRA, FRB and FRBp repsectively on DFP quad
>> 	instructions.
> 
> OK, I'll trust you got these correct (and I'll check Jan's next ppc
> patch a little more thoroughly ;-) ).  Please apply to the branch too.

And I'm sorry for having overlooked this detail.

Jan

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

end of thread, other threads:[~2011-11-02  9:35 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-28 12:26 [PATCH] PPC: reject more instructions with invalid operand combinations Jan Beulich
2011-10-06  1:14 ` Alan Modra
2011-10-27  2:11 ` Peter Bergner
2011-10-27  3:26   ` Alan Modra
2011-10-27 16:06     ` Peter Bergner
2011-11-02  9:35     ` Jan Beulich

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).