Disallow 3-operand cmp[l][i] for ppc64
authorAlan Modra <amodra@gmail.com>
Thu, 29 Sep 2016 05:42:47 +0000 (15:12 +0930)
committerAlan Modra <amodra@gmail.com>
Thu, 29 Sep 2016 05:42:47 +0000 (15:12 +0930)
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.

gas/ChangeLog
gas/config/tc-ppc.c
gas/testsuite/gas/ppc/power8.s
gas/testsuite/gas/ppc/power9.d
include/ChangeLog
include/opcode/ppc.h
opcodes/ChangeLog
opcodes/ppc-opc.c

index d499099a7abcf1f5d2f251d4780c70a3a620b9a3..e4db0f0d595f1b0320fbe2b78190154384dcd277 100644 (file)
@@ -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
index d2b53169804cd8834066a8c44b4541148de54912..5c7b09f02bced5b9ecba4bfa6b2e45bf98ee659a 100644 (file)
@@ -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);
index 728caae3161d2cdbbe7ae66da5f5c5c1688df068..857bda2a910263981fc403bc4aaa6f907342331b 100644 (file)
@@ -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.
index 31e45304a14ab22d1507b6a3669e835320badbe6..6f2f53a72534c4826cd164160a213f087047feaf 100644 (file)
@@ -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
index 01d1c1416c24afb4d231d70e41c6fdfd6fe8f00c..652bb212f23029618c65a2a9afa6224beeb744f5 100644 (file)
@@ -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.
index d9f973ddea89134c111d22c934f17cedfd1504cf..66d2ceb31db52a8ddb28da7588ffb66376607a60 100644 (file)
@@ -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)
 \f
 /* The POWER and PowerPC assemblers use a few macros.  We keep them
    with the operands table for simplicity.  The macro table is an
index 1613154249ba5cc9424f7a24a738c5f967fe7413..98866efe17bb4acdb4208a12ba79a0877bbc4a4c 100644 (file)
@@ -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.
index 1c6e9704d90c002b129aa4b66fe125c88fc19cdc..8c590332fd0279a7e2ab2192af5adedfe5bfee82 100644 (file)
@@ -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}},