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/binutils-2_25-branch] Allow for optional operands with non-zero default values.


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

commit 2df35d63fa1af4afceb5bdf5475a10028c479531
Author: Peter Bergner <bergner@vnet.ibm.com>
Date:   Fri Jun 19 17:17:07 2015 -0500

    Allow for optional operands with non-zero default values.
    
    ISA 2.07 (ie, POWER8) added the rfebb instruction which takes one operand
    with the value of either a 0 or 1.  It also defines an extended mnemonic
    with no operands (ie, "rfebb") that is supposed to be equivalent to "rfebb 1".
    I implemented rfebb's lone operand with PPC_OPERAND_OPTIONAL, but the
    problem is, optional operands that are ommitted always default to the
    value 0, which is wrong in this case.  I have added support for allowing
    non-zero default values by adding an additional flag PPC_OPERAND_OPTIONAL_VALUE
    that specifies that the default operand value to be used is stored in the
    SHIFT field of the operand field immediately following this one.
    
    This fixes the rfebb issue.  I also fixed the mftb and mfcr instructions
    so they use the same mechanism.  This allows us to flag invalid uses of
    mfcr where we explicitly pass in a zero FXM value, like the use in a2.[sd].
    
    include/opcode/
    
    	* ppc.h (PPC_OPERAND_OPTIONAL_VALUE): New.
    	(ppc_optional_operand_value): New inline function.
    
    opcodes/
    	* ppc-dis.h (skip_optional_operands): Use ppc_optional_operand_value.
    	* ppc-opc.c (FXM4): Add non-zero optional value.
    	(TBR): Likewise.
    	(SXL): Likewise.
    	(insert_fxm): Handle new default operand value.
    	(extract_fxm): Likewise.
    	(insert_tbr): Likewise.
    	(extract_tbr): Likewise.
    
    gas/
    	* config/tc-ppc.c (md_assemble): Use ppc_optional_operand_value.
    	Allow for optional operands without insert functions.
    
    gas/testsuite/
    	* gas/ppc/power8.d: Fixup rfebb test results.
    	* gas/ppc/a2.s: Fix invalid mfcr test.
    	* gas/ppc/a2.d: Likewise.

Diff:
---
 gas/ChangeLog                  |  4 ++++
 gas/config/tc-ppc.c            |  8 +++++++-
 gas/testsuite/ChangeLog        |  5 +++++
 gas/testsuite/gas/ppc/a2.d     |  2 +-
 gas/testsuite/gas/ppc/a2.s     |  2 +-
 gas/testsuite/gas/ppc/power8.d |  6 +++---
 include/opcode/ChangeLog       |  7 +++++++
 include/opcode/ppc.h           | 13 ++++++++++++
 opcodes/ChangeLog              | 10 +++++++++
 opcodes/ppc-dis.c              |  3 ++-
 opcodes/ppc-opc.c              | 46 +++++++++++++++++++-----------------------
 11 files changed, 74 insertions(+), 32 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 68f5b7b..6ca5067 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,6 +1,10 @@
 2015-07-10  Alan Modra  <amodra@gmail.com>
 
 	Apply from master
+	2015-06-19  Peter Bergner  <bergner@vnet.ibm.com>
+	* config/tc-ppc.c (md_assemble): Use ppc_optional_operand_value.
+	Allow for optional operands without insert functions.
+
 	2015-03-11  Alan Modra  <amodra@gmail.com>
 	* config/tc-ppc.c (md_assemble): Don't abort on 8 byte insn fixups.
 	(md_apply_fix): Report an error on data-only fixups used with insns.
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 13d8dba..00e20f9 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -2752,12 +2752,18 @@ md_assemble (char *str)
       if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
 	  && skip_optional)
 	{
+	  long val = ppc_optional_operand_value (operand);
 	  if (operand->insert)
 	    {
-	      insn = (*operand->insert) (insn, 0L, ppc_cpu, &errmsg);
+	      insn = (*operand->insert) (insn, val, ppc_cpu, &errmsg);
 	      if (errmsg != (const char *) NULL)
 		as_bad ("%s", errmsg);
 	    }
+	  else if (operand->shift >= 0)
+	    insn |= ((long) val & operand->bitm) << operand->shift;
+	  else
+	    insn |= ((long) val & operand->bitm) >> -operand->shift;
+
 	  if ((operand->flags & PPC_OPERAND_NEXT) != 0)
 	    next_opindex = *opindex_ptr + 1;
 	  continue;
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 3ebb81b..4af0bb0 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,6 +1,11 @@
 2015-07-10  Alan Modra  <amodra@gmail.com>
 
 	Apply from master
+	2015-06-19  Peter Bergner  <bergner@vnet.ibm.com>
+	* gas/ppc/power8.d: Fixup rfebb test results.
+	* gas/ppc/a2.s: Fix invalid mfcr test.
+	* gas/ppc/a2.d: Likewise.
+
 	2015-06-04  Peter Bergner  <bergner@vnet.ibm.com>
 	* gas/ppc/a2.d: Fixup test case due to new extended mnemonic.
 	* gas/ppc/power4.s <hwsync, lwsync, ptesync, sync>: Add tests.
diff --git a/gas/testsuite/gas/ppc/a2.d b/gas/testsuite/gas/ppc/a2.d
index aa05cbc..bb60275 100644
--- a/gas/testsuite/gas/ppc/a2.d
+++ b/gas/testsuite/gas/ppc/a2.d
@@ -347,7 +347,7 @@ Disassembly of section \.text:
  4fc:	(7c 00 04 00|00 04 00 7c) 	mcrxr   cr0
  500:	(7d 80 04 00|00 04 80 7d) 	mcrxr   cr3
  504:	(7c 60 00 26|26 00 60 7c) 	mfcr    r3
- 508:	(7c 60 00 26|26 00 60 7c) 	mfcr    r3
+ 508:	(7c 70 20 26|26 20 70 7c) 	mfocrf  r3,2
  50c:	(7c 70 10 26|26 10 70 7c) 	mfocrf  r3,1
  510:	(7c 78 00 26|26 00 78 7c) 	mfocrf  r3,128
  514:	(7d 4a 3a 87|87 3a 4a 7d) 	mfdcr\.  r10,234
diff --git a/gas/testsuite/gas/ppc/a2.s b/gas/testsuite/gas/ppc/a2.s
index 7d0ddc7..ecb8668 100644
--- a/gas/testsuite/gas/ppc/a2.s
+++ b/gas/testsuite/gas/ppc/a2.s
@@ -322,7 +322,7 @@ start:
 	mcrxr	0
 	mcrxr	3
 	mfcr	3
-	mfcr	3,0
+	mfcr	3,0x02
 	mfcr	3,0x01
 	mfcr	3,0x80
 	mfdcr.	10,234
diff --git a/gas/testsuite/gas/ppc/power8.d b/gas/testsuite/gas/ppc/power8.d
index e66951e..61e1cab 100644
--- a/gas/testsuite/gas/ppc/power8.d
+++ b/gas/testsuite/gas/ppc/power8.d
@@ -27,9 +27,9 @@ Disassembly of section \.text:
   44:	(60 42 00 00|00 00 42 60) 	ori     r2,r2,0
   48:	(60 00 00 00|00 00 00 60) 	nop
   4c:	(60 42 00 00|00 00 42 60) 	ori     r2,r2,0
-  50:	(4c 00 01 24|24 01 00 4c) 	rfebb   
-  54:	(4c 00 01 24|24 01 00 4c) 	rfebb   
-  58:	(4c 00 09 24|24 09 00 4c) 	rfebb   1
+  50:	(4c 00 01 24|24 01 00 4c) 	rfebb   0
+  54:	(4c 00 09 24|24 09 00 4c) 	rfebb   
+  58:	(4c 00 09 24|24 09 00 4c) 	rfebb   
   5c:	(4d 95 04 60|60 04 95 4d) 	bctar-  12,4\*cr5\+gt
   60:	(4c 87 04 61|61 04 87 4c) 	bctarl- 4,4\*cr1\+so
   64:	(4d ac 04 60|60 04 ac 4d) 	bctar\+  12,4\*cr3\+lt
diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog
index d378910..e3132d8 100644
--- a/include/opcode/ChangeLog
+++ b/include/opcode/ChangeLog
@@ -1,3 +1,10 @@
+2015-07-10  Alan Modra  <amodra@gmail.com>
+
+	Apply from master
+	2015-06-19  Peter Bergner <bergner@vnet.ibm.com>
+	* ppc.h (PPC_OPERAND_OPTIONAL_VALUE): New.
+	(ppc_optional_operand_value): New inline function.
+
 2014-10-09  Jose E. Marchesi  <jose.marchesi@oracle.com>
 
 	* sparc.h (sparc_opcode): new field `hwcaps2'.
diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h
index c797fa5..5add00f 100644
--- a/include/opcode/ppc.h
+++ b/include/opcode/ppc.h
@@ -380,6 +380,11 @@ extern const unsigned int num_powerpc_operands;
 
 /* This is a CR FIELD that does not use symbolic names.  */
 #define PPC_OPERAND_CR_REG (0x200000)
+
+/* This flag is only used with PPC_OPERAND_OPTIONAL.  If this operand
+   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)
 
 /* The POWER and PowerPC assemblers use a few macros.  We keep them
    with the operands table for simplicity.  The macro table is an
@@ -409,4 +414,12 @@ extern const int powerpc_num_macros;
 
 extern ppc_cpu_t ppc_parse_cpu (ppc_cpu_t, ppc_cpu_t *, const char *);
 
+static inline long
+ppc_optional_operand_value (const struct powerpc_operand *operand)
+{
+  if ((operand->flags & PPC_OPERAND_OPTIONAL_VALUE) != 0)
+    return (operand+1)->shift;
+  return 0;
+}
+
 #endif /* PPC_H */
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index da1fdac..64b28e2 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,6 +1,16 @@
 2015-07-10  Alan Modra  <amodra@gmail.com>
 
 	Apply from master
+	2015-06-19  Peter Bergner  <bergner@vnet.ibm.com>
+        * ppc-dis.h (skip_optional_operands): Use ppc_optional_operand_value.
+	* ppc-opc.c (FXM4): Add non-zero optional value.
+	(TBR): Likewise.
+	(SXL): Likewise.
+	(insert_fxm): Handle new default operand value.
+	(extract_fxm): Likewise.
+	(insert_tbr): Likewise.
+	(extract_tbr): Likewise.
+
 	2015-06-12  Peter Bergner  <bergner@vnet.ibm.com>
 	* ppc-opc.c: Add comment accidentally removed by old commit.
 	(MTMSRD_L): Delete.
diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c
index 85bbeba..2e1075c 100644
--- a/opcodes/ppc-dis.c
+++ b/opcodes/ppc-dis.c
@@ -452,7 +452,8 @@ skip_optional_operands (const unsigned char *opindex,
       operand = &powerpc_operands[*opindex];
       if ((operand->flags & PPC_OPERAND_NEXT) != 0
 	  || ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
-	      && operand_value_powerpc (operand, insn, dialect) != 0))
+	      && operand_value_powerpc (operand, insn, dialect) !=
+		 ppc_optional_operand_value (operand)))
 	return 0;
     }
 
diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c
index f68d9de..40c73ad 100644
--- a/opcodes/ppc-opc.c
+++ b/opcodes/ppc-opc.c
@@ -382,10 +382,12 @@ const struct powerpc_operand powerpc_operands[] =
 
   /* Power4 version for mfcr.  */
 #define FXM4 FXM + 1
-  { 0xff, 12, insert_fxm, extract_fxm, PPC_OPERAND_OPTIONAL },
+  { 0xff, 12, insert_fxm, extract_fxm, PPC_OPERAND_OPTIONAL | PPC_OPERAND_OPTIONAL_VALUE},
+  /* If the FXM4 operand is ommitted, use the sentinel value -1.  */
+  { -1, -1, NULL, NULL, 0},
 
   /* The IMM20 field in an LI instruction.  */
-#define IMM20 FXM4 + 1
+#define IMM20 FXM4 + 2
   { 0xfffff, PPC_OPSHIFT_INV, insert_li20, extract_li20, PPC_OPERAND_SIGNED},
 
   /* The L field in a D or X form instruction.  */
@@ -642,10 +644,12 @@ const struct powerpc_operand powerpc_operands[] =
   /* The TBR field in an XFX form instruction.  This is like the SPR
      field, but it is optional.  */
 #define TBR SV + 1
-  { 0x3ff, 11, insert_tbr, extract_tbr, PPC_OPERAND_OPTIONAL },
+  { 0x3ff, 11, insert_tbr, extract_tbr, PPC_OPERAND_OPTIONAL | PPC_OPERAND_OPTIONAL_VALUE},
+  /* If the TBR operand is ommitted, use the value 268.  */
+  { -1, 268, NULL, NULL, 0},
 
   /* The TO field in a D or X form instruction.  */
-#define TO TBR + 1
+#define TO TBR + 2
 #define DUI TO
 #define TO_MASK (0x1f << 21)
   { 0x1f, 21, NULL, NULL, 0 },
@@ -766,10 +770,12 @@ const struct powerpc_operand powerpc_operands[] =
 
   /* The S field in a XL form instruction.  */
 #define SXL S + 1
-  { 0x1, 11, NULL, NULL, PPC_OPERAND_OPTIONAL },
+  { 0x1, 11, NULL, NULL, PPC_OPERAND_OPTIONAL | PPC_OPERAND_OPTIONAL_VALUE},
+  /* If the SXL operand is ommitted, use the value 1.  */
+  { -1, 1, NULL, NULL, 0},
 
   /* SH field starting at bit position 16.  */
-#define SH16 SXL + 1
+#define SH16 SXL + 2
   /* The DCM and DGM fields in a Z form instruction.  */
 #define DCM SH16
 #define DGM DCM
@@ -1284,19 +1290,13 @@ insert_fxm (unsigned long insn,
 	}
     }
 
-  /* If the optional field on mfcr is missing that means we want to use
-     the old form of the instruction that moves the whole cr.  In that
-     case we'll have VALUE zero.  There doesn't seem to be a way to
-     distinguish this from the case where someone writes mfcr %r3,0.  */
-  else if (value == 0)
-    ;
-
   /* If only one bit of the FXM field is set, we can use the new form
      of the instruction, which is faster.  Unlike the Power4 branch hint
      encoding, this is not backward compatible.  Do not generate the
      new form unless -mpower4 has been given, or -many and the two
      operand form of mfcr was used.  */
-  else if ((value & -value) == value
+  else if (value > 0
+	   && (value & -value) == value
 	   && ((dialect & PPC_OPCODE_POWER4) != 0
 	       || ((dialect & PPC_OPCODE_ANY) != 0
 		   && (insn & (0x3ff << 1)) == 19 << 1)))
@@ -1305,7 +1305,10 @@ insert_fxm (unsigned long insn,
   /* Any other value on mfcr is an error.  */
   else if ((insn & (0x3ff << 1)) == 19 << 1)
     {
-      *errmsg = _("ignoring invalid mfcr mask");
+      /* A value of -1 means we used the one operand form of
+	 mfcr which is valid.  */
+      if (value != -1)
+        *errmsg = _("ignoring invalid mfcr mask");
       value = 0;
     }
 
@@ -1332,6 +1335,8 @@ extract_fxm (unsigned long insn,
     {
       if (mask != 0)
 	*invalid = 1;
+      else
+	mask = -1;
     }
 
   return mask;
@@ -1868,12 +1873,7 @@ extract_sprg (unsigned long insn,
 }
 
 /* The TBR field in an XFX instruction.  This is just like SPR, but it
-   is optional.  When TBR is omitted, it must be inserted as 268 (the
-   magic number of the TB register).  These functions treat 0
-   (indicating an omitted optional operand) as 268.  This means that
-   ``mftb 4,0'' is not handled correctly.  This does not matter very
-   much, since the architecture manual does not define mftb as
-   accepting any values other than 268 or 269.  */
+   is optional.  */
 
 static unsigned long
 insert_tbr (unsigned long insn,
@@ -1881,8 +1881,6 @@ insert_tbr (unsigned long insn,
 	    ppc_cpu_t dialect ATTRIBUTE_UNUSED,
 	    const char **errmsg)
 {
-  if (value == 0)
-    value = 268;
   if (value != 268 && value != 269)
     *errmsg = _("invalid tbr number");
   return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
@@ -1898,8 +1896,6 @@ extract_tbr (unsigned long insn,
   ret = ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
   if (ret != 268 && ret != 269)
     *invalid = 1;
-  if (ret == 268)
-    ret = 0;
   return ret;
 }


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