This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils 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]

[binutils-gdb] Disallow 3-operand cmp[l][i] for ppc64


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a5721ba270ddf860e0e5a45bba456214e8eac2be

commit a5721ba270ddf860e0e5a45bba456214e8eac2be
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Sep 29 15:12:47 2016 +0930

    Disallow 3-operand cmp[l][i] for ppc64
    
    cmp[l][o] get an optional L field only when generating 32-bit code.
    dcbf, tlbie and tlbiel keep their optional L field, ditto for R field
    of tbegin.  cmprb, tsr., wlcr[all] and mtsle all change to a
    compulsory L field.
    
    L field of dcbf and wclr is 2 bits.
    
    	PR 20641
    include/
    	* opcode/ppc.h (PPC_OPERAND_OPTIONAL32): Define.
    opcodes/
    	* ppc-opc.c (L): Make compulsory.
    	(LOPT): New, optional form of L.
    	(HTM_R): Define as LOPT.
    	(L0, L1): Delete.
    	(L32OPT): New, optional for 32-bit L.
    	(L2OPT): New, 2-bit L for dcbf.
    	(SVC_LEC): Update.
    	(L2): Define.
    	(insert_l0, extract_l0, insert_l1, extract_l2): Delete.
    	(powerpc_opcodes <cmpli, cmpi, cmpl, cmp>): Use L32OPT.
    	<dcbf>: Use L2OPT.
    	<tlbiel, tlbie>: Use LOPT.
    	<wclr, wclrall>: Use L2.
    gas/
    	* config/tc-ppc.c (md_assemble): Handle PPC_OPERAND_OPTIONAL32.
    	* testsuite/gas/ppc/power8.s: Provide tbegin. operand.
    	* testsuite/gas/ppc/power9.d: Update cmprb disassembly.

Diff:
---
 gas/ChangeLog                  |  6 +++
 gas/config/tc-ppc.c            |  4 +-
 gas/testsuite/gas/ppc/power8.s |  2 +-
 gas/testsuite/gas/ppc/power9.d |  4 +-
 include/ChangeLog              |  4 ++
 include/opcode/ppc.h           |  4 ++
 opcodes/ChangeLog              | 16 +++++++
 opcodes/ppc-opc.c              | 96 ++++++++++--------------------------------
 8 files changed, 59 insertions(+), 77 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index d499099..e4db0f0 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
+2016-09-29  Alan Modra  <amodra@gmail.com>
+
+	* config/tc-ppc.c (md_assemble): Handle PPC_OPERAND_OPTIONAL32.
+	* testsuite/gas/ppc/power8.s: Provide tbegin. operand.
+	* testsuite/gas/ppc/power9.d: Update cmprb disassembly.
+
 2016-09-26  Trevor Saunders  <tbsaunde+binutils@tbsaunde.org>
 
 	* config/tc-xtensa.c (xg_reverse_shift_count): Pass cnt_arg instead of
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index d2b5316..5c7b09f 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -2695,7 +2695,8 @@ md_assemble (char *str)
       const struct powerpc_operand *operand;
 
       operand = &powerpc_operands[*opindex_ptr];
-      if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
+      if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
+	  && !((operand->flags & PPC_OPERAND_OPTIONAL32) != 0 && ppc_obj64))
 	{
 	  unsigned int opcount;
 	  unsigned int num_operands_expected;
@@ -2765,6 +2766,7 @@ md_assemble (char *str)
       /* If this is an optional operand, and we are skipping it, just
 	 insert a zero.  */
       if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
+	  && !((operand->flags & PPC_OPERAND_OPTIONAL32) != 0 && ppc_obj64)
 	  && skip_optional)
 	{
 	  long val = ppc_optional_operand_value (operand);
diff --git a/gas/testsuite/gas/ppc/power8.s b/gas/testsuite/gas/ppc/power8.s
index 728caae..857bda2 100644
--- a/gas/testsuite/gas/ppc/power8.s
+++ b/gas/testsuite/gas/ppc/power8.s
@@ -5,7 +5,7 @@ power8:
 	tabortdc.    20,11,10
 	tabortwci.   17,10,-13
 	tabortdci.   29,3,-5
-	tbegin.
+	tbegin.      0
 	tcheck       7
 	tend.        0
 	tend.
diff --git a/gas/testsuite/gas/ppc/power9.d b/gas/testsuite/gas/ppc/power9.d
index 31e4530..6f2f53a 100644
--- a/gas/testsuite/gas/ppc/power9.d
+++ b/gas/testsuite/gas/ppc/power9.d
@@ -274,8 +274,8 @@ Disassembly of section \.text:
 .*:	(f3 89 ef 6f|6f ef 89 f3) 	xvxsigsp vs60,vs61
 .*:	(7c 06 39 c0|c0 39 06 7c) 	cmpeqb  cr0,r6,r7
 .*:	(7f 86 39 c0|c0 39 86 7f) 	cmpeqb  cr7,r6,r7
-.*:	(7c 08 49 80|80 49 08 7c) 	cmprb   cr0,r8,r9
-.*:	(7f 88 49 80|80 49 88 7f) 	cmprb   cr7,r8,r9
+.*:	(7c 08 49 80|80 49 08 7c) 	cmprb   cr0,0,r8,r9
+.*:	(7f 88 49 80|80 49 88 7f) 	cmprb   cr7,0,r8,r9
 .*:	(7c 28 49 80|80 49 28 7c) 	cmprb   cr0,1,r8,r9
 .*:	(7f a8 49 80|80 49 a8 7f) 	cmprb   cr7,1,r8,r9
 .*:	(7d e0 01 00|00 01 e0 7d) 	setb    r15,cr0
diff --git a/include/ChangeLog b/include/ChangeLog
index 01d1c14..652bb21 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
+2016-09-29  Alan Modra  <amodra@gmail.com>
+
+	* opcode/ppc.h (PPC_OPERAND_OPTIONAL32): Define.
+
 2016-09-26  Claudiu Zissulescu  <claziss@synopsys.com>
 
 	* opcode/arc.h (insn_class_t): Add two new classes.
diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h
index d9f973d..66d2ceb 100644
--- a/include/opcode/ppc.h
+++ b/include/opcode/ppc.h
@@ -407,6 +407,10 @@ extern const unsigned int num_powerpc_operands;
    is omitted, then the value it should use for the operand is stored
    in the SHIFT field of the immediatly following operand field.  */
 #define PPC_OPERAND_OPTIONAL_VALUE (0x400000)
+
+/* This flag is only used with PPC_OPERAND_OPTIONAL.  The operand is
+   only optional when generating 32-bit code.  */
+#define PPC_OPERAND_OPTIONAL32 (0x800000)
 
 /* The POWER and PowerPC assemblers use a few macros.  We keep them
    with the operands table for simplicity.  The macro table is an
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 1613154..98866ef 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,19 @@
+2016-09-29  Alan Modra  <amodra@gmail.com>
+
+	* ppc-opc.c (L): Make compulsory.
+	(LOPT): New, optional form of L.
+	(HTM_R): Define as LOPT.
+	(L0, L1): Delete.
+	(L32OPT): New, optional for 32-bit L.
+	(L2OPT): New, 2-bit L for dcbf.
+	(SVC_LEC): Update.
+	(L2): Define.
+	(insert_l0, extract_l0, insert_l1, extract_l2): Delete.
+	(powerpc_opcodes <cmpli, cmpi, cmpl, cmp>): Use L32OPT.
+	<dcbf>: Use L2OPT.
+	<tlbiel, tlbie>: Use LOPT.
+	<wclr, wclrall>: Use L2.
+
 2016-09-26  Vlad Zakharov  <vzakhar@synopsys.com>
 
 	* Makefile.in: Regenerate.
diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c
index 1c6e970..8c59033 100644
--- a/opcodes/ppc-opc.c
+++ b/opcodes/ppc-opc.c
@@ -62,10 +62,6 @@ static unsigned long insert_dxdn (unsigned long, long, ppc_cpu_t, const char **)
 static long extract_dxdn (unsigned long, ppc_cpu_t, int *);
 static unsigned long insert_fxm (unsigned long, long, ppc_cpu_t, const char **);
 static long extract_fxm (unsigned long, ppc_cpu_t, int *);
-static unsigned long insert_l0 (unsigned long, long, ppc_cpu_t, const char **);
-static long extract_l0 (unsigned long, ppc_cpu_t, int *);
-static unsigned long insert_l1 (unsigned long, long, ppc_cpu_t, const char **);
-static long extract_l1 (unsigned long, ppc_cpu_t, int *);
 static unsigned long insert_li20 (unsigned long, long, ppc_cpu_t, const char **);
 static long extract_li20 (unsigned long, ppc_cpu_t, int *);
 static unsigned long insert_ls (unsigned long, long, ppc_cpu_t, const char **);
@@ -429,20 +425,24 @@ const struct powerpc_operand powerpc_operands[] =
 
   /* The L field in a D or X form instruction.  */
 #define L IMM20 + 1
+  { 0x1, 21, NULL, NULL, 0 },
+
+  /* The optional L field in tlbie and tlbiel instructions.  */
+#define LOPT L + 1
   /* The R field in a HTM X form instruction.  */
-#define HTM_R L
+#define HTM_R LOPT
   { 0x1, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
 
-  /* The L field in an X form instruction which must be zero.  */
-#define L0 L + 1
-  { 0x1, 21, insert_l0, extract_l0, PPC_OPERAND_OPTIONAL },
+  /* The optional (for 32-bit) L field in cmp[l][i] instructions.  */
+#define L32OPT LOPT + 1
+  { 0x1, 21, NULL, NULL, PPC_OPERAND_OPTIONAL | PPC_OPERAND_OPTIONAL32 },
 
-  /* The L field in an X form instruction which must be one.  */
-#define L1 L0 + 1
-  { 0x1, 21, insert_l1, extract_l1, 0 },
+  /* The L field in dcbf instruction.  */
+#define L2OPT L32OPT + 1
+  { 0x3, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
 
   /* The LEV field in a POWER SVC form instruction.  */
-#define SVC_LEV L1 + 1
+#define SVC_LEV L2OPT + 1
   { 0x7f, 5, NULL, NULL, 0 },
 
   /* The LEV field in an SC form instruction.  */
@@ -688,6 +688,8 @@ const struct powerpc_operand powerpc_operands[] =
 #define STRM SR + 1
   /* The T field in a tlbilx form instruction.  */
 #define T STRM
+  /* The L field in wclr instructions.  */
+#define L2 STRM
   { 0x3, 21, NULL, NULL, 0 },
 
   /* The ESYNC field in an X (sync) form instruction.  */
@@ -1483,58 +1485,6 @@ extract_fxm (unsigned long insn,
   return mask;
 }
 
-/* The L field in an X form instruction which must have the value zero.  */
-
-static unsigned long
-insert_l0 (unsigned long insn,
-	   long value,
-	   ppc_cpu_t dialect ATTRIBUTE_UNUSED,
-	   const char **errmsg)
-{
-  if (value != 0)
-    *errmsg = _("invalid operand constant");
-  return insn & ~(0x1 << 21);
-}
-
-static long
-extract_l0 (unsigned long insn,
-	    ppc_cpu_t dialect ATTRIBUTE_UNUSED,
-	    int *invalid)
-{
-  long value;
-
-  value = (insn >> 21) & 0x1;
-  if (value != 0)
-    *invalid = 1;
-  return value;
-}
-
-/* The L field in an X form instruction which must have the value one.  */
-
-static unsigned long
-insert_l1 (unsigned long insn,
-	   long value,
-	   ppc_cpu_t dialect ATTRIBUTE_UNUSED,
-	   const char **errmsg)
-{
-  if (value != 1)
-    *errmsg = _("invalid operand constant");
-  return insn | (0x1 << 21);
-}
-
-static long
-extract_l1 (unsigned long insn,
-	    ppc_cpu_t dialect ATTRIBUTE_UNUSED,
-	    int *invalid)
-{
-  long value;
-
-  value = (insn >> 21) & 0x1;
-  if (value != 1)
-    *invalid = 1;
-  return value;
-}
-
 static unsigned long
 insert_li20 (unsigned long insn,
 	     long value,
@@ -3890,12 +3840,12 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 
 {"cmplwi",	OPL(10,0),	OPL_MASK,    PPCCOM,	PPCVLE,		{OBF, RA, UISIGNOPT}},
 {"cmpldi",	OPL(10,1),	OPL_MASK,    PPC64,	PPCVLE,		{OBF, RA, UISIGNOPT}},
-{"cmpli",	OP(10),		OP_MASK,     PPC,	PPCVLE,		{BF, L, RA, UISIGNOPT}},
+{"cmpli",	OP(10),		OP_MASK,     PPC,	PPCVLE,		{BF, L32OPT, RA, UISIGNOPT}},
 {"cmpli",	OP(10),		OP_MASK,     PWRCOM,	PPC|PPCVLE,	{BF, RA, UISIGNOPT}},
 
 {"cmpwi",	OPL(11,0),	OPL_MASK,    PPCCOM,	PPCVLE,		{OBF, RA, SI}},
 {"cmpdi",	OPL(11,1),	OPL_MASK,    PPC64,	PPCVLE,		{OBF, RA, SI}},
-{"cmpi",	OP(11),		OP_MASK,     PPC,	PPCVLE,		{BF, L, RA, SI}},
+{"cmpi",	OP(11),		OP_MASK,     PPC,	PPCVLE,		{BF, L32OPT, RA, SI}},
 {"cmpi",	OP(11),		OP_MASK,     PWRCOM,	PPC|PPCVLE,	{BF, RA, SI}},
 
 {"addic",	OP(12),		OP_MASK,     PPCCOM,	PPCVLE,		{RT, RA, SI}},
@@ -4713,7 +4663,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 
 {"cmpw",	XOPL(31,0,0),	XCMPL_MASK,  PPCCOM,	0,		{OBF, RA, RB}},
 {"cmpd",	XOPL(31,0,1),	XCMPL_MASK,  PPC64,	0,		{OBF, RA, RB}},
-{"cmp",		X(31,0),	XCMP_MASK,   PPC,	0,		{BF, L, RA, RB}},
+{"cmp",		X(31,0),	XCMP_MASK,   PPC,	0,		{BF, L32OPT, RA, RB}},
 {"cmp",		X(31,0),	XCMPL_MASK,  PWRCOM,	PPC,		{BF, RA, RB}},
 
 {"twlgt",	XTO(31,4,TOLGT), XTO_MASK,   PPCCOM,	0,		{RA, RB}},
@@ -4821,7 +4771,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 
 {"cmplw",	XOPL(31,32,0),	XCMPL_MASK,  PPCCOM,	0,		{OBF, RA, RB}},
 {"cmpld",	XOPL(31,32,1),	XCMPL_MASK,  PPC64,	0,		{OBF, RA, RB}},
-{"cmpl",	X(31,32),	XCMP_MASK,   PPC,	0,		{BF, L, RA, RB}},
+{"cmpl",	X(31,32),	XCMP_MASK,   PPC,	0,		{BF, L32OPT, RA, RB}},
 {"cmpl",	X(31,32),	XCMPL_MASK,  PWRCOM,	PPC,		{BF, RA, RB}},
 
 {"lvsr",	X(31,38),	X_MASK,	     PPCVEC,	0,		{VD, RA0, RB}},
@@ -4907,7 +4857,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 {"ldarx",	X(31,84),	XEH_MASK,    PPC64,	0,		{RT, RA0, RB, EH}},
 
 {"dcbfl",	XOPL(31,86,1),	XRT_MASK,    POWER5,	PPC476,		{RA0, RB}},
-{"dcbf",	X(31,86),	XLRT_MASK,   PPC,	0,		{RA0, RB, L}},
+{"dcbf",	X(31,86),	XLRT_MASK,   PPC,	0,		{RA0, RB, L2OPT}},
 
 {"lbzx",	X(31,87),	X_MASK,	     COM,	0,		{RT, RA0, RB}},
 
@@ -5149,7 +5099,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 {"ehpriv",	X(31,270),	0xffffffff,  E500MC|PPCA2, 0,		{0}},
 
 {"tlbiel",	X(31,274),	X_MASK|1<<20,POWER9,	PPC476,		{RB, RSO, RIC, PRS, X_R}},
-{"tlbiel",	X(31,274),	XRTLRA_MASK, POWER4,	POWER9|PPC476,	{RB, L}},
+{"tlbiel",	X(31,274),	XRTLRA_MASK, POWER4,	POWER9|PPC476,	{RB, LOPT}},
 
 {"mfapidi",	X(31,275),	X_MASK,	     BOOKE,	E500|TITAN,	{RT, RA}},
 
@@ -5183,7 +5133,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 
 {"tlbie",	X(31,306),	X_MASK|1<<20,POWER9,	TITAN,		{RB, RS, RIC, PRS, X_R}},
 {"tlbie",	X(31,306),	XRA_MASK,    POWER7,	POWER9|TITAN,	{RB, RS}},
-{"tlbie",	X(31,306),	XRTLRA_MASK, PPC,    E500|POWER7|TITAN,	{RB, L}},
+{"tlbie",	X(31,306),	XRTLRA_MASK, PPC,    E500|POWER7|TITAN,	{RB, LOPT}},
 {"tlbi",	X(31,306),	XRT_MASK,    POWER,	0,		{RA0, RB}},
 
 {"mfvsrld",	X(31,307),	XX1RB_MASK,  PPCVSX3,	0,		{RA, XS6}},
@@ -6234,8 +6184,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 {"stvfrxl",	X(31,933),	X_MASK,	     PPCVEC2,	0,		{VS, RA0, RB}},
 
 {"wclrone",	XOPL2(31,934,2),XRT_MASK,    PPCA2,	0,		{RA0, RB}},
-{"wclrall",	X(31,934),	XRARB_MASK,  PPCA2,	0,		{L}},
-{"wclr",	X(31,934),	X_MASK,	     PPCA2,	0,		{L, RA0, RB}},
+{"wclrall",	X(31,934),	XRARB_MASK,  PPCA2,	0,		{L2}},
+{"wclr",	X(31,934),	X_MASK,	     PPCA2,	0,		{L2, RA0, RB}},
 
 {"stvrxl",	X(31,935),	X_MASK,	     CELL,	0,		{VS, RA0, RB}},


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