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

a094f6
commit 11a0cf2ec0ed6e70ff25e9a50c2223dcd98c1c10
a094f6
Author: Peter Bergner <bergner@vnet.ibm.com>
a094f6
Date:   Fri Jun 19 17:17:07 2015 -0500
a094f6
a094f6
    Allow for optional operands with non-zero default values.
a094f6
    
a094f6
    ISA 2.07 (ie, POWER8) added the rfebb instruction which takes one operand
a094f6
    with the value of either a 0 or 1.  It also defines an extended mnemonic
a094f6
    with no operands (ie, "rfebb") that is supposed to be equivalent to "rfebb 1".
a094f6
    I implemented rfebb's lone operand with PPC_OPERAND_OPTIONAL, but the
a094f6
    problem is, optional operands that are ommitted always default to the
a094f6
    value 0, which is wrong in this case.  I have added support for allowing
a094f6
    non-zero default values by adding an additional flag PPC_OPERAND_OPTIONAL_VALUE
a094f6
    that specifies that the default operand value to be used is stored in the
a094f6
    SHIFT field of the operand field immediately following this one.
a094f6
    
a094f6
    This fixes the rfebb issue.  I also fixed the mftb and mfcr instructions
a094f6
    so they use the same mechanism.  This allows us to flag invalid uses of
a094f6
    mfcr where we explicitly pass in a zero FXM value, like the use in a2.[sd].
a094f6
    
a094f6
    include/opcode/
a094f6
    
a094f6
            * ppc.h (PPC_OPERAND_OPTIONAL_VALUE): New.
a094f6
            (ppc_optional_operand_value): New inline function.
a094f6
    
a094f6
    opcodes/
a094f6
            * ppc-dis.h (skip_optional_operands): Use ppc_optional_operand_value.
a094f6
            * ppc-opc.c (FXM4): Add non-zero optional value.
a094f6
            (TBR): Likewise.
a094f6
            (SXL): Likewise.
a094f6
            (insert_fxm): Handle new default operand value.
a094f6
            (extract_fxm): Likewise.
a094f6
            (insert_tbr): Likewise.
a094f6
            (extract_tbr): Likewise.
a094f6
    
a094f6
    gas/
a094f6
            * config/tc-ppc.c (md_assemble): Use ppc_optional_operand_value.
a094f6
            Allow for optional operands without insert functions.
a094f6
    
a094f6
    gas/testsuite/
a094f6
            * gas/ppc/power8.d: Fixup rfebb test results.
a094f6
            * gas/ppc/a2.s: Fix invalid mfcr test.
a094f6
            * gas/ppc/a2.d: Likewise.
a094f6
a094f6
### a/include/opcode/ChangeLog
a094f6
### b/include/opcode/ChangeLog
a094f6
## -1,3 +1,8 @@
a094f6
+2015-06-19  Peter Bergner <bergner@vnet.ibm.com>
a094f6
+
a094f6
+	* ppc.h (PPC_OPERAND_OPTIONAL_VALUE): New.
a094f6
+	(ppc_optional_operand_value): New inline function.
a094f6
+
a094f6
 2015-06-04  Matthew Wahab  <matthew.wahab@arm.com>
a094f6
 
a094f6
 	* aarch64.h (AARCH64_V8_1): New.
a094f6
--- a/include/opcode/ppc.h
a094f6
+++ b/include/opcode/ppc.h
a094f6
@@ -380,6 +380,11 @@ extern const unsigned int num_powerpc_operands;
a094f6
 
a094f6
 /* This is a CR FIELD that does not use symbolic names.  */
a094f6
 #define PPC_OPERAND_CR_REG (0x200000)
a094f6
+
a094f6
+/* This flag is only used with PPC_OPERAND_OPTIONAL.  If this operand
a094f6
+   is omitted, then the value it should use for the operand is stored
a094f6
+   in the SHIFT field of the immediatly following operand field.  */
a094f6
+#define PPC_OPERAND_OPTIONAL_VALUE (0x400000)
a094f6
 
a094f6
 /* The POWER and PowerPC assemblers use a few macros.  We keep them
a094f6
    with the operands table for simplicity.  The macro table is an
a094f6
@@ -409,4 +414,12 @@ extern const int powerpc_num_macros;
a094f6
 
a094f6
 extern ppc_cpu_t ppc_parse_cpu (ppc_cpu_t, ppc_cpu_t *, const char *);
a094f6
 
a094f6
+static inline long
a094f6
+ppc_optional_operand_value (const struct powerpc_operand *operand)
a094f6
+{
a094f6
+  if ((operand->flags & PPC_OPERAND_OPTIONAL_VALUE) != 0)
a094f6
+    return (operand+1)->shift;
a094f6
+  return 0;
a094f6
+}
a094f6
+
a094f6
 #endif /* PPC_H */
a094f6
### a/opcodes/ChangeLog
a094f6
### b/opcodes/ChangeLog
a094f6
## -1,3 +1,14 @@
a094f6
+2015-06-19  Peter Bergner  <bergner@vnet.ibm.com>
a094f6
+
a094f6
+        * ppc-dis.h (skip_optional_operands): Use ppc_optional_operand_value.
a094f6
+	* ppc-opc.c (FXM4): Add non-zero optional value.
a094f6
+	(TBR): Likewise.
a094f6
+	(SXL): Likewise.
a094f6
+	(insert_fxm): Handle new default operand value.
a094f6
+	(extract_fxm): Likewise.
a094f6
+	(insert_tbr): Likewise.
a094f6
+	(extract_tbr): Likewise.
a094f6
+
a094f6
 2015-06-16  Matthew Wahab  <matthew.wahab@arm.com>
a094f6
 
a094f6
 	* arch64-opc.c (aarch64_sys_regs): Add "id_mmfr4_el1".
a094f6
--- a/opcodes/ppc-dis.c
a094f6
+++ b/opcodes/ppc-dis.c
a094f6
@@ -452,7 +452,8 @@ skip_optional_operands (const unsigned char *opindex,
a094f6
       operand = &powerpc_operands[*opindex];
a094f6
       if ((operand->flags & PPC_OPERAND_NEXT) != 0
a094f6
 	  || ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
a094f6
-	      && operand_value_powerpc (operand, insn, dialect) != 0))
a094f6
+	      && operand_value_powerpc (operand, insn, dialect) !=
a094f6
+		 ppc_optional_operand_value (operand)))
a094f6
 	return 0;
a094f6
     }
a094f6
 
a094f6
--- a/opcodes/ppc-opc.c
a094f6
+++ b/opcodes/ppc-opc.c
a094f6
@@ -382,10 +382,12 @@ const struct powerpc_operand powerpc_operands[] =
a094f6
 
a094f6
   /* Power4 version for mfcr.  */
a094f6
 #define FXM4 FXM + 1
a094f6
-  { 0xff, 12, insert_fxm, extract_fxm, PPC_OPERAND_OPTIONAL },
a094f6
+  { 0xff, 12, insert_fxm, extract_fxm, PPC_OPERAND_OPTIONAL | PPC_OPERAND_OPTIONAL_VALUE},
a094f6
+  /* If the FXM4 operand is ommitted, use the sentinel value -1.  */
a094f6
+  { -1, -1, NULL, NULL, 0},
a094f6
 
a094f6
   /* The IMM20 field in an LI instruction.  */
a094f6
-#define IMM20 FXM4 + 1
a094f6
+#define IMM20 FXM4 + 2
a094f6
   { 0xfffff, PPC_OPSHIFT_INV, insert_li20, extract_li20, PPC_OPERAND_SIGNED},
a094f6
 
a094f6
   /* The L field in a D or X form instruction.  */
a094f6
@@ -642,10 +644,12 @@ const struct powerpc_operand powerpc_operands[] =
a094f6
   /* The TBR field in an XFX form instruction.  This is like the SPR
a094f6
      field, but it is optional.  */
a094f6
 #define TBR SV + 1
a094f6
-  { 0x3ff, 11, insert_tbr, extract_tbr, PPC_OPERAND_OPTIONAL },
a094f6
+  { 0x3ff, 11, insert_tbr, extract_tbr, PPC_OPERAND_OPTIONAL | PPC_OPERAND_OPTIONAL_VALUE},
a094f6
+  /* If the TBR operand is ommitted, use the value 268.  */
a094f6
+  { -1, 268, NULL, NULL, 0},
a094f6
 
a094f6
   /* The TO field in a D or X form instruction.  */
a094f6
-#define TO TBR + 1
a094f6
+#define TO TBR + 2
a094f6
 #define DUI TO
a094f6
 #define TO_MASK (0x1f << 21)
a094f6
   { 0x1f, 21, NULL, NULL, 0 },
a094f6
@@ -766,10 +770,12 @@ const struct powerpc_operand powerpc_operands[] =
a094f6
 
a094f6
   /* The S field in a XL form instruction.  */
a094f6
 #define SXL S + 1
a094f6
-  { 0x1, 11, NULL, NULL, PPC_OPERAND_OPTIONAL },
a094f6
+  { 0x1, 11, NULL, NULL, PPC_OPERAND_OPTIONAL | PPC_OPERAND_OPTIONAL_VALUE},
a094f6
+  /* If the SXL operand is ommitted, use the value 1.  */
a094f6
+  { -1, 1, NULL, NULL, 0},
a094f6
 
a094f6
   /* SH field starting at bit position 16.  */
a094f6
-#define SH16 SXL + 1
a094f6
+#define SH16 SXL + 2
a094f6
   /* The DCM and DGM fields in a Z form instruction.  */
a094f6
 #define DCM SH16
a094f6
 #define DGM DCM
a094f6
@@ -1284,19 +1290,13 @@ insert_fxm (unsigned long insn,
a094f6
 	}
a094f6
     }
a094f6
 
a094f6
-  /* If the optional field on mfcr is missing that means we want to use
a094f6
-     the old form of the instruction that moves the whole cr.  In that
a094f6
-     case we'll have VALUE zero.  There doesn't seem to be a way to
a094f6
-     distinguish this from the case where someone writes mfcr %r3,0.  */
a094f6
-  else if (value == 0)
a094f6
-    ;
a094f6
-
a094f6
   /* If only one bit of the FXM field is set, we can use the new form
a094f6
      of the instruction, which is faster.  Unlike the Power4 branch hint
a094f6
      encoding, this is not backward compatible.  Do not generate the
a094f6
      new form unless -mpower4 has been given, or -many and the two
a094f6
      operand form of mfcr was used.  */
a094f6
-  else if ((value & -value) == value
a094f6
+  else if (value > 0
a094f6
+	   && (value & -value) == value
a094f6
 	   && ((dialect & PPC_OPCODE_POWER4) != 0
a094f6
 	       || ((dialect & PPC_OPCODE_ANY) != 0
a094f6
 		   && (insn & (0x3ff << 1)) == 19 << 1)))
a094f6
@@ -1305,7 +1305,10 @@ insert_fxm (unsigned long insn,
a094f6
   /* Any other value on mfcr is an error.  */
a094f6
   else if ((insn & (0x3ff << 1)) == 19 << 1)
a094f6
     {
a094f6
-      *errmsg = _("ignoring invalid mfcr mask");
a094f6
+      /* A value of -1 means we used the one operand form of
a094f6
+	 mfcr which is valid.  */
a094f6
+      if (value != -1)
a094f6
+        *errmsg = _("ignoring invalid mfcr mask");
a094f6
       value = 0;
a094f6
     }
a094f6
 
a094f6
@@ -1332,6 +1335,8 @@ extract_fxm (unsigned long insn,
a094f6
     {
a094f6
       if (mask != 0)
a094f6
 	*invalid = 1;
a094f6
+      else
a094f6
+	mask = -1;
a094f6
     }
a094f6
 
a094f6
   return mask;
a094f6
@@ -1868,12 +1873,7 @@ extract_sprg (unsigned long insn,
a094f6
 }
a094f6
 
a094f6
 /* The TBR field in an XFX instruction.  This is just like SPR, but it
a094f6
-   is optional.  When TBR is omitted, it must be inserted as 268 (the
a094f6
-   magic number of the TB register).  These functions treat 0
a094f6
-   (indicating an omitted optional operand) as 268.  This means that
a094f6
-   ``mftb 4,0'' is not handled correctly.  This does not matter very
a094f6
-   much, since the architecture manual does not define mftb as
a094f6
-   accepting any values other than 268 or 269.  */
a094f6
+   is optional.  */
a094f6
 
a094f6
 static unsigned long
a094f6
 insert_tbr (unsigned long insn,
a094f6
@@ -1881,8 +1881,6 @@ insert_tbr (unsigned long insn,
a094f6
 	    ppc_cpu_t dialect ATTRIBUTE_UNUSED,
a094f6
 	    const char **errmsg)
a094f6
 {
a094f6
-  if (value == 0)
a094f6
-    value = 268;
a094f6
   if (value != 268 && value != 269)
a094f6
     *errmsg = _("invalid tbr number");
a094f6
   return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
a094f6
@@ -1898,8 +1896,6 @@ extract_tbr (unsigned long insn,
a094f6
   ret = ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
a094f6
   if (ret != 268 && ret != 269)
a094f6
     *invalid = 1;
a094f6
-  if (ret == 268)
a094f6
-    ret = 0;
a094f6
   return ret;
a094f6
 }
a094f6