Blame SOURCES/gdb-rhbz1320945-power9-19of38.patch

2c2fa1
commit 7b9341139a693eac8d316275004b2d752b1f0cb8
2c2fa1
Author: Peter Bergner <bergner@vnet.ibm.com>
2c2fa1
Date:   Mon Jun 22 14:55:24 2015 -0500
2c2fa1
2c2fa1
    PPC sync instruction accepts invalid and incompatible operands
2c2fa1
    
2c2fa1
    ISA 2.07 added a new category called Elemental Memory Barriers that modifies
2c2fa1
    the sync instruction to accept an additional operand ESYNC.  Edmar added
2c2fa1
    support for this insruction varient here:
2c2fa1
    
2c2fa1
        https://sourceware.org/ml/binutils/2012-02/msg00221.html
2c2fa1
    
2c2fa1
    Looking at this closer, I see that the insert_ls() function is misnamed
2c2fa1
    (since it's attached to the ESYNC operand, not the LS operand) but more
2c2fa1
    importantly, it is silently modifying the LS operand value behind the
2c2fa1
    users back when the LS operand is either invalid or is incompatible with
2c2fa1
    the new ESYNC operand.  The ISA 2.07 doc has an Assembler Note that clearly
2c2fa1
    states that assemblers that support the ESYNC operand should report all
2c2fa1
    invalid uses of LS and ESYNC.  This patch changes the assembler to
2c2fa1
    error out on invalid and incompatible operand usage.
2c2fa1
    
2c2fa1
    opcodes/
2c2fa1
            * ppc-opc.c (insert_ls): Test for invalid LS operands.
2c2fa1
            (insert_esync): New function.
2c2fa1
            (LS, WC): Use insert_ls.
2c2fa1
            (ESYNC): Use insert_esync.
2c2fa1
    
2c2fa1
    gas/testsuite/
2c2fa1
            * gas/ppc/e6500.s <sync>: Fix invalid test.
2c2fa1
            * gas/ppc/e6500.d: Likewise.
2c2fa1
2c2fa1
### a/opcodes/ChangeLog
2c2fa1
### b/opcodes/ChangeLog
2c2fa1
## -1,3 +1,10 @@
2c2fa1
+2015-06-22  Peter Bergner  <bergner@vnet.ibm.com>
2c2fa1
+
2c2fa1
+	* ppc-opc.c (insert_ls): Test for invalid LS operands.
2c2fa1
+	(insert_esync): New function.
2c2fa1
+	(LS, WC): Use insert_ls.
2c2fa1
+	(ESYNC): Use insert_esync.
2c2fa1
+
2c2fa1
 2015-06-22  Nick Clifton  <nickc@redhat.com>
2c2fa1
 
2c2fa1
 	* dis-buf.c (buffer_read_memory): Fail is stop_vma is set and the
2c2fa1
--- a/opcodes/ppc-opc.c
2c2fa1
+++ b/opcodes/ppc-opc.c
2c2fa1
@@ -53,6 +53,7 @@ static unsigned long insert_bo (unsigned long, long, ppc_cpu_t, const char **);
2c2fa1
 static long extract_bo (unsigned long, ppc_cpu_t, int *);
2c2fa1
 static unsigned long insert_boe (unsigned long, long, ppc_cpu_t, const char **);
2c2fa1
 static long extract_boe (unsigned long, ppc_cpu_t, int *);
2c2fa1
+static unsigned long insert_esync (unsigned long, long, ppc_cpu_t, const char **);
2c2fa1
 static unsigned long insert_fxm (unsigned long, long, ppc_cpu_t, const char **);
2c2fa1
 static long extract_fxm (unsigned long, ppc_cpu_t, int *);
2c2fa1
 static unsigned long insert_li20 (unsigned long, long, ppc_cpu_t, const char **);
2c2fa1
@@ -417,7 +418,7 @@ const struct powerpc_operand powerpc_operands[] =
2c2fa1
   /* The LS or WC field in an X (sync or wait) form instruction.  */
2c2fa1
 #define LS LIA + 1
2c2fa1
 #define WC LS
2c2fa1
-  { 0x3, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
2c2fa1
+  { 0x3, 21, insert_ls, NULL, PPC_OPERAND_OPTIONAL },
2c2fa1
 
2c2fa1
   /* The ME field in an M form instruction.  */
2c2fa1
 #define ME LS + 1
2c2fa1
@@ -635,7 +636,7 @@ const struct powerpc_operand powerpc_operands[] =
2c2fa1
 
2c2fa1
   /* The ESYNC field in an X (sync) form instruction.  */
2c2fa1
 #define ESYNC STRM + 1
2c2fa1
-  { 0xf, 16, insert_ls, NULL, PPC_OPERAND_OPTIONAL },
2c2fa1
+  { 0xf, 16, insert_esync, NULL, PPC_OPERAND_OPTIONAL },
2c2fa1
 
2c2fa1
   /* The SV field in a POWER SC form instruction.  */
2c2fa1
 #define SV ESYNC + 1
2c2fa1
@@ -1365,17 +1366,40 @@ extract_li20 (unsigned long insn,
2c2fa1
          | (insn & 0x7ff);
2c2fa1
 }
2c2fa1
 
2c2fa1
-/* The LS field in a sync instruction that accepts 2 operands
2c2fa1
-   Values 2 and 3 are reserved,
2c2fa1
-     must be treated as 0 for future compatibility
2c2fa1
-   Values 0 and 1 can be accepted, if field ESYNC is zero
2c2fa1
-   Otherwise L = complement of ESYNC-bit2 (1<<18) */
2c2fa1
+/* The 2-bit L field in a SYNC or WC field in a WAIT instruction.
2c2fa1
+   For SYNC, some L values are reserved:
2c2fa1
+     * Value 3 is reserved on newer server cpus.
2c2fa1
+     * Values 2 and 3 are reserved on all other cpus.  */
2c2fa1
 
2c2fa1
 static unsigned long
2c2fa1
 insert_ls (unsigned long insn,
2c2fa1
 	   long value,
2c2fa1
-	   ppc_cpu_t dialect ATTRIBUTE_UNUSED,
2c2fa1
-	   const char **errmsg ATTRIBUTE_UNUSED)
2c2fa1
+	   ppc_cpu_t dialect,
2c2fa1
+	   const char **errmsg)
2c2fa1
+{
2c2fa1
+  /* For SYNC, some L values are illegal.  */
2c2fa1
+  if (((insn >> 1) & 0x3ff) == 598)
2c2fa1
+    {
2c2fa1
+      long max_lvalue = (dialect & PPC_OPCODE_POWER4) ? 2 : 1;
2c2fa1
+      if (value > max_lvalue)
2c2fa1
+	{
2c2fa1
+	  *errmsg = _("illegal L operand value");
2c2fa1
+	  return insn;
2c2fa1
+	}
2c2fa1
+    }
2c2fa1
+
2c2fa1
+  return insn | ((value & 0x3) << 21);
2c2fa1
+}
2c2fa1
+
2c2fa1
+/* The 4-bit E field in a sync instruction that accepts 2 operands.
2c2fa1
+   If ESYNC is non-zero, then the L field must be either 0 or 1 and
2c2fa1
+   the complement of ESYNC-bit2.  */
2c2fa1
+
2c2fa1
+static unsigned long
2c2fa1
+insert_esync (unsigned long insn,
2c2fa1
+	      long value,
2c2fa1
+	      ppc_cpu_t dialect ATTRIBUTE_UNUSED,
2c2fa1
+	      const char **errmsg)
2c2fa1
 {
2c2fa1
   unsigned long ls;
2c2fa1
 
2c2fa1
@@ -1383,12 +1407,15 @@ insert_ls (unsigned long insn,
2c2fa1
   if (value == 0)
2c2fa1
     {
2c2fa1
       if (ls > 1)
2c2fa1
-	return insn & ~(0x3 << 21);
2c2fa1
+	*errmsg = _("illegal L operand value");
2c2fa1
       return insn;
2c2fa1
     }
2c2fa1
-  if ((value & 0x2) != 0)
2c2fa1
-    return (insn & ~(0x3 << 21)) | ((value & 0xf) << 16);
2c2fa1
-  return (insn & ~(0x3 << 21)) | (0x1 << 21) | ((value & 0xf) << 16);
2c2fa1
+
2c2fa1
+  if ((ls & ~0x1)
2c2fa1
+      || (((value >> 1) & 0x1) ^ ls) == 0)
2c2fa1
+        *errmsg = _("incompatible L operand value");
2c2fa1
+
2c2fa1
+  return insn | ((value & 0xf) << 16);
2c2fa1
 }
2c2fa1
 
2c2fa1
 /* The MB and ME fields in an M form instruction expressed as a single
2c2fa1
@@ -2024,6 +2051,7 @@ extract_dm (unsigned long insn,
2c2fa1
     *invalid = 1;
2c2fa1
   return (value) ? 1 : 0;
2c2fa1
 }
2c2fa1
+
2c2fa1
 /* The VLESIMM field in an I16A form instruction.  This is split.  */
2c2fa1
 
2c2fa1
 static unsigned long