This is the mail archive of the binutils@sources.redhat.com 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]

powerpc64 fixes



Fixes a number of powerpc64 bugs.
o  Re-enable instructions zapped by 2001-10-12 patch.
o  Corrects branch hints for 64 bit ppc, which are different to 32 bit.
   I chose to pass another param to the insert/extract functions rather
   than the "nice" way of using new 64 bit insert/extract functions
   because that would bloat the powerpc_opcodes table, or make it
   read/write.
o  Fixes disassembly of insns with branch hints.

gas/ChangeLog
	* config/tc-ppc.c (ppc_insert_operand): Pass ppc_size to
	operand->insert.
	(md_assemble): Likewise.

include/opcode/ChangeLog
	* ppc.h (struct powerpc_operand <insert, extract>): Add dialect param.

opcodes/ChangeLog
	* ppc-opc.c (PPC64): Revert 2001-10-12. Do include PPC_OPCODE_PPC.
	(insert_bat, extract_bat, insert_bba, extract_bba,
	insert_bd, extract_bd, insert_bdm, extract_bdm,
	insert_bdp, extract_bdp, valid_bo,
	insert_bo, extract_bo, insert_boe, extract_boe,
	insert_ds, extract_ds, insert_de, extract_de,
	insert_des, extract_des, insert_li, extract_li,
	insert_mbe, extract_mbe, insert_mb6, extract_mb6,
	insert_nb, extract_nb, insert_nsi, extract_nsi,
	insert_ral, insert_ram, insert_ras,
	insert_rbs, extract_rbs, insert_sh6, extract_sh6,
	insert_spr, extract_spr, insert_tbr, extract_tbr): Add dialect param.
	(extract_bd, extract_bdm, extract_bdp,
	extract_ds, extract_des,
	extract_li, extract_nsi): Implement sign extension without conditional.
	(insert_bdm, extract_bdm,
	insert_bdp, extract_bdp, valid_bo): Handle 64 bit branch hints.
	(extract_bdm, extract_bdp): Correct 32 bit validation.

	* ppc-dis.c (powerpc_dialect): Set PPC_OPCODE_64 in dialect for
	64 bit default targets, and parse "32" and "64" in options.
	Formatting fixes.
	(print_insn_powerpc): Pass dialect to operand->extract.

One little issue: the powerpc64 branch hint validation causes BookE
test failures.  I'm not sure whether the failures are real, or whether
the testsuite needs updating.  With this patch applied,
"bce 1, 5, branch_target_1", and "bcea 3, 7, branch_target_3" both
fail because the BO field on these insns has 'z' in the lsb for a
64 bit target.  booke64 may differ, in which case I'll need to pass
(ppc_size | ppc_cpu) to operand->insert in the assembler and tweak
valid_bo.

-- 
Alan Modra

Index: gas/config/tc-ppc.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-ppc.c,v
retrieving revision 1.38
diff -u -p -r1.38 tc-ppc.c
--- gas/config/tc-ppc.c	2001/10/17 13:13:15	1.38
+++ gas/config/tc-ppc.c	2001/11/01 12:09:30
@@ -1304,7 +1304,7 @@ ppc_insert_operand (insn, operand, val, 
       const char *errmsg;
 
       errmsg = NULL;
-      insn = (*operand->insert) (insn, (long) val, &errmsg);
+      insn = (*operand->insert) (insn, (long) val, ppc_size, &errmsg);
       if (errmsg != (const char *) NULL)
 	as_bad_where (file, line, errmsg);
     }
@@ -1942,7 +1942,7 @@ md_assemble (str)
 	 from the input.  */
       if ((operand->flags & PPC_OPERAND_FAKE) != 0)
 	{
-	  insn = (*operand->insert) (insn, 0L, &errmsg);
+	  insn = (*operand->insert) (insn, 0L, ppc_size, &errmsg);
 	  if (errmsg != (const char *) NULL)
 	    as_bad (errmsg);
 	  continue;
@@ -1955,7 +1955,7 @@ md_assemble (str)
 	{
 	  if (operand->insert)
 	    {
-	      insn = (*operand->insert) (insn, 0L, &errmsg);
+	      insn = (*operand->insert) (insn, 0L, ppc_size, &errmsg);
 	      if (errmsg != (const char *) NULL)
 		as_bad (errmsg);
 	    }
Index: include/opcode/ppc.h
===================================================================
RCS file: /cvs/src/src/include/opcode/ppc.h,v
retrieving revision 1.9
diff -u -p -r1.9 ppc.h
--- include/opcode/ppc.h	2001/10/17 13:13:15	1.9
+++ include/opcode/ppc.h	2001/11/01 12:09:37
@@ -130,6 +130,7 @@ struct powerpc_operand
      operand value is legal, *ERRMSG will be unchanged (most operands
      can accept any value).  */
   unsigned long (*insert) PARAMS ((unsigned long instruction, long op,
+				   int dialect,
 				   const char **errmsg));
 
   /* Extraction function.  This is used by the disassembler.  To
@@ -149,7 +150,8 @@ struct powerpc_operand
      non-zero if this operand type can not actually be extracted from
      this operand (i.e., the instruction does not match).  If the
      operand is valid, *INVALID will not be changed.  */
-  long (*extract) PARAMS ((unsigned long instruction, int *invalid));
+  long (*extract) PARAMS ((unsigned long instruction, int dialect,
+			   int *invalid));
 
   /* One bit syntax flags.  */
   unsigned long flags;
Index: opcodes/ppc-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-dis.c,v
retrieving revision 1.5
diff -u -p -r1.5 ppc-dis.c
--- opcodes/ppc-dis.c	2001/10/13 01:59:09	1.5
+++ opcodes/ppc-dis.c	2001/11/01 12:09:40
@@ -44,13 +44,28 @@ powerpc_dialect(info)
 {
   int dialect = PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC;
 
-  if (info->disassembler_options &&
-      (strcmp(info->disassembler_options, "booke") == 0 ||
-       strcmp(info->disassembler_options, "booke32") == 0 ||
-       strcmp(info->disassembler_options, "booke64") == 0))
+  if (info->disassembler_options
+      && (strcmp (info->disassembler_options, "booke") == 0
+	  || strcmp (info->disassembler_options, "booke32") == 0
+	  || strcmp (info->disassembler_options, "booke64") == 0))
     dialect |= PPC_OPCODE_BOOKE | PPC_OPCODE_BOOKE64;
   else 
     dialect |= PPC_OPCODE_403 | PPC_OPCODE_601;
+
+  if (BFD_DEFAULT_TARGET_SIZE == 64)
+    {
+      dialect |= PPC_OPCODE_64;
+      if (info->disassembler_options
+	  && strstr (info->disassembler_options, "32") == 0)
+	dialect &= ~PPC_OPCODE_64;
+    }
+  else
+    {
+      if (info->disassembler_options
+	  && strstr (info->disassembler_options, "64") == 0)
+	dialect |= PPC_OPCODE_64;
+    }
+
   return dialect;
 }
 
@@ -145,7 +160,7 @@ print_insn_powerpc (memaddr, info, bigen
 	{
 	  operand = powerpc_operands + *opindex;
 	  if (operand->extract)
-	    (*operand->extract) (insn, &invalid);
+	    (*operand->extract) (insn, dialect, &invalid);
 	}
       if (invalid)
 	continue;
@@ -172,7 +187,7 @@ print_insn_powerpc (memaddr, info, bigen
 
 	  /* Extract the value from the instruction.  */
 	  if (operand->extract)
-	    value = (*operand->extract) (insn, (int *) NULL);
+	    value = (*operand->extract) (insn, dialect, (int *) NULL);
 	  else
 	    {
 	      value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
Index: opcodes/ppc-opc.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
retrieving revision 1.22
diff -u -p -r1.22 ppc-opc.c
--- opcodes/ppc-opc.c	2001/10/20 13:50:16	1.22
+++ opcodes/ppc-opc.c	2001/11/01 13:51:27
@@ -38,48 +38,90 @@ Software Foundation, 59 Temple Place - S
 
 /* Local insertion and extraction functions.  */
 
-static unsigned long insert_bat PARAMS ((unsigned long, long, const char **));
-static long extract_bat PARAMS ((unsigned long, int *));
-static unsigned long insert_bba PARAMS ((unsigned long, long, const char **));
-static long extract_bba PARAMS ((unsigned long, int *));
-static unsigned long insert_bd PARAMS ((unsigned long, long, const char **));
-static long extract_bd PARAMS ((unsigned long, int *));
-static unsigned long insert_bdm PARAMS ((unsigned long, long, const char **));
-static long extract_bdm PARAMS ((unsigned long, int *));
-static unsigned long insert_bdp PARAMS ((unsigned long, long, const char **));
-static long extract_bdp PARAMS ((unsigned long, int *));
-static int valid_bo PARAMS ((long));
-static unsigned long insert_bo PARAMS ((unsigned long, long, const char **));
-static long extract_bo PARAMS ((unsigned long, int *));
-static unsigned long insert_boe PARAMS ((unsigned long, long, const char **));
-static long extract_boe PARAMS ((unsigned long, int *));
-static unsigned long insert_ds PARAMS ((unsigned long, long, const char **));
-static long extract_ds PARAMS ((unsigned long, int *));
-static unsigned long insert_de PARAMS ((unsigned long, long, const char **));
-static long extract_de PARAMS ((unsigned long, int *));
-static unsigned long insert_des PARAMS ((unsigned long, long, const char **));
-static long extract_des PARAMS ((unsigned long, int *));
-static unsigned long insert_li PARAMS ((unsigned long, long, const char **));
-static long extract_li PARAMS ((unsigned long, int *));
-static unsigned long insert_mbe PARAMS ((unsigned long, long, const char **));
-static long extract_mbe PARAMS ((unsigned long, int *));
-static unsigned long insert_mb6 PARAMS ((unsigned long, long, const char **));
-static long extract_mb6 PARAMS ((unsigned long, int *));
-static unsigned long insert_nb PARAMS ((unsigned long, long, const char **));
-static long extract_nb PARAMS ((unsigned long, int *));
-static unsigned long insert_nsi PARAMS ((unsigned long, long, const char **));
-static long extract_nsi PARAMS ((unsigned long, int *));
-static unsigned long insert_ral PARAMS ((unsigned long, long, const char **));
-static unsigned long insert_ram PARAMS ((unsigned long, long, const char **));
-static unsigned long insert_ras PARAMS ((unsigned long, long, const char **));
-static unsigned long insert_rbs PARAMS ((unsigned long, long, const char **));
-static long extract_rbs PARAMS ((unsigned long, int *));
-static unsigned long insert_sh6 PARAMS ((unsigned long, long, const char **));
-static long extract_sh6 PARAMS ((unsigned long, int *));
-static unsigned long insert_spr PARAMS ((unsigned long, long, const char **));
-static long extract_spr PARAMS ((unsigned long, int *));
-static unsigned long insert_tbr PARAMS ((unsigned long, long, const char **));
-static long extract_tbr PARAMS ((unsigned long, int *));
+static unsigned long insert_bat
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_bat
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_bba
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_bba
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_bd
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_bd
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_bdm
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_bdm
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_bdp
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_bdp
+  PARAMS ((unsigned long, int, int *));
+static int valid_bo
+  PARAMS ((long, int));
+static unsigned long insert_bo
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_bo
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_boe
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_boe
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_ds
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_ds
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_de
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_de
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_des
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_des
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_li
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_li
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_mbe
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_mbe
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_mb6
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_mb6
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_nb
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_nb
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_nsi
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_nsi
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_ral
+  PARAMS ((unsigned long, long, int, const char **));
+static unsigned long insert_ram
+  PARAMS ((unsigned long, long, int, const char **));
+static unsigned long insert_ras
+  PARAMS ((unsigned long, long, int, const char **));
+static unsigned long insert_rbs
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_rbs
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_sh6
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_sh6
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_spr
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_spr
+  PARAMS ((unsigned long, int, int *));
+static unsigned long insert_tbr
+  PARAMS ((unsigned long, long, int, const char **));
+static long extract_tbr
+  PARAMS ((unsigned long, int, int *));
 
 /* The operands table.
 
@@ -474,17 +516,19 @@ const struct powerpc_operand powerpc_ope
 
 /*ARGSUSED*/
 static unsigned long
-insert_bat (insn, value, errmsg)
+insert_bat (insn, value, dialect, errmsg)
      unsigned long insn;
      long value ATTRIBUTE_UNUSED;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg ATTRIBUTE_UNUSED;
 {
   return insn | (((insn >> 21) & 0x1f) << 16);
 }
 
 static long
-extract_bat (insn, invalid)
+extract_bat (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid;
 {
   if (invalid != (int *) NULL
@@ -501,17 +545,19 @@ extract_bat (insn, invalid)
 
 /*ARGSUSED*/
 static unsigned long
-insert_bba (insn, value, errmsg)
+insert_bba (insn, value, dialect, errmsg)
      unsigned long insn;
      long value ATTRIBUTE_UNUSED;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg ATTRIBUTE_UNUSED;
 {
   return insn | (((insn >> 16) & 0x1f) << 11);
 }
 
 static long
-extract_bba (insn, invalid)
+extract_bba (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid;
 {
   if (invalid != (int *) NULL
@@ -525,9 +571,10 @@ extract_bba (insn, invalid)
 
 /*ARGSUSED*/
 static unsigned long
-insert_bd (insn, value, errmsg)
+insert_bd (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg ATTRIBUTE_UNUSED;
 {
   return insn | (value & 0xfffc);
@@ -535,48 +582,69 @@ insert_bd (insn, value, errmsg)
 
 /*ARGSUSED*/
 static long
-extract_bd (insn, invalid)
+extract_bd (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid ATTRIBUTE_UNUSED;
 {
-  if ((insn & 0x8000) != 0)
-    return (insn & 0xfffc) - 0x10000;
-  else
-    return insn & 0xfffc;
+  return ((insn & 0xfffc) ^ 0x8000) - 0x8000;
 }
 
 /* The BD field in a B form instruction when the - modifier is used.
    This modifier means that the branch is not expected to be taken.
-   We must set the y bit of the BO field to 1 if the offset is
-   negative.  When extracting, we require that the y bit be 1 and that
-   the offset be positive, since if the y bit is 0 we just want to
-   print the normal form of the instruction.  */
+   For 32 bit targets we set the y bit of the BO field to 1 if the
+   offset is negative.  When extracting, we require that the y bit be
+   1 and that the offset be positive, since if the y bit is 0 we just
+   want to print the normal form of the instruction.
+   64 bit targets use two bits, "a", and "t", instead of the "y" bit.
+   at == 10 => not taken, at == 11 => taken.  The t bit is 00001 in
+   BO field, the a bit is 00010 for branch on CR(BI) and 01000 for
+   branch on CTR.  */
 
 /*ARGSUSED*/
 static unsigned long
-insert_bdm (insn, value, errmsg)
+insert_bdm (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect;
      const char **errmsg ATTRIBUTE_UNUSED;
 {
-  if ((value & 0x8000) != 0)
-    insn |= 1 << 21;
+  if ((dialect & PPC_OPCODE_64) == 0)
+    {
+      if ((value & 0x8000) != 0)
+	insn |= 1 << 21;
+    }
+  else
+    {
+      if ((insn & (0x14 << 21)) == (0x04 << 21))
+	insn |= 0x02 << 21;
+      else if ((insn & (0x14 << 21)) == (0x10 << 21))
+	insn |= 0x08 << 21;
+    }
   return insn | (value & 0xfffc);
 }
 
 static long
-extract_bdm (insn, invalid)
+extract_bdm (insn, dialect, invalid)
      unsigned long insn;
+     int dialect;
      int *invalid;
 {
-  if (invalid != (int *) NULL
-      && ((insn & (1 << 21)) == 0
-	  || (insn & (1 << 15)) == 0))
-    *invalid = 1;
-  if ((insn & 0x8000) != 0)
-    return (insn & 0xfffc) - 0x10000;
-  else
-    return insn & 0xfffc;
+  if (invalid != (int *) NULL)
+    {
+      if ((dialect & PPC_OPCODE_64) == 0)
+	{
+	  if (((insn & (1 << 21)) == 0) != ((insn & (1 << 15)) == 0))
+	    *invalid = 1;
+	}
+      else
+	{
+	  if ((insn & (0x17 << 21)) != (0x06 << 21)
+	      && (insn & (0x1d << 21)) != (0x18 << 21))
+	    *invalid = 1;
+	}
+    }
+  return ((insn & 0xfffc) ^ 0x8000) - 0x8000;
 }
 
 /* The BD field in a B form instruction when the + modifier is used.
@@ -585,56 +653,100 @@ extract_bdm (insn, invalid)
 
 /*ARGSUSED*/
 static unsigned long
-insert_bdp (insn, value, errmsg)
+insert_bdp (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect;
      const char **errmsg ATTRIBUTE_UNUSED;
 {
-  if ((value & 0x8000) == 0)
-    insn |= 1 << 21;
+  if ((dialect & PPC_OPCODE_64) == 0)
+    {
+      if ((value & 0x8000) == 0)
+	insn |= 1 << 21;
+    }
+  else
+    {
+      if ((insn & (0x14 << 21)) == (0x04 << 21))
+	insn |= 0x03 << 21;
+      else if ((insn & (0x14 << 21)) == (0x10 << 21))
+	insn |= 0x09 << 21;
+    }
   return insn | (value & 0xfffc);
 }
 
 static long
-extract_bdp (insn, invalid)
+extract_bdp (insn, dialect, invalid)
      unsigned long insn;
+     int dialect;
      int *invalid;
 {
-  if (invalid != (int *) NULL
-      && ((insn & (1 << 21)) == 0
-	  || (insn & (1 << 15)) != 0))
-    *invalid = 1;
-  if ((insn & 0x8000) != 0)
-    return (insn & 0xfffc) - 0x10000;
-  else
-    return insn & 0xfffc;
+  if (invalid != (int *) NULL)
+    {
+      if ((dialect & PPC_OPCODE_64) == 0)
+	{
+	  if (((insn & (1 << 21)) == 0) == ((insn & (1 << 15)) == 0))
+	    *invalid = 1;
+	}
+      else
+	{
+	  if ((insn & (0x17 << 21)) != (0x07 << 21)
+	      && (insn & (0x1d << 21)) != (0x19 << 21))
+	    *invalid = 1;
+	}
+    }
+  return ((insn & 0xfffc) ^ 0x8000) - 0x8000;
 }
 
 /* Check for legal values of a BO field.  */
 
 static int
-valid_bo (value)
+valid_bo (value, dialect)
      long value;
+     int dialect;
 {
-  /* Certain encodings have bits that are required to be zero.  These
-     are (z must be zero, y may be anything):
-         001zy
-	 011zy
-	 1z00y
-	 1z01y
-	 1z1zz
-     */
-  switch (value & 0x14)
+  if ((dialect & PPC_OPCODE_64) == 0)
+    {
+      /* Certain encodings have bits that are required to be zero.
+	 These are (z must be zero, y may be anything):
+	     001zy
+	     011zy
+	     1z00y
+	     1z01y
+	     1z1zz
+      */
+      switch (value & 0x14)
+	{
+	default:
+	case 0:
+	  return 1;
+	case 0x4:
+	  return (value & 0x2) == 0;
+	case 0x10:
+	  return (value & 0x8) == 0;
+	case 0x14:
+	  return value == 0x14;
+	}
+    }
+  else
     {
-    default:
-    case 0:
-      return 1;
-    case 0x4:
-      return (value & 0x2) == 0;
-    case 0x10:
-      return (value & 0x8) == 0;
-    case 0x14:
-      return value == 0x14;
+      /* Certain encodings have bits that are required to be zero.
+	 These are (z must be zero, a & t may be anything):
+	     0000z
+	     0001z
+	     0100z
+	     0101z
+	     001at
+	     011at
+	     1a00t
+	     1a01t
+	     1z1zz
+      */
+      if ((value & 0x14) == 0)
+	return (value & 0x1) == 0;
+      else if ((value & 0x14) == 0x14)
+	return value == 0x14;
+      else
+	return 1;
     }
 }
 
@@ -642,27 +754,29 @@ valid_bo (value)
    the field to an illegal value.  */
 
 static unsigned long
-insert_bo (insn, value, errmsg)
+insert_bo (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect;
      const char **errmsg;
 {
   if (errmsg != (const char **) NULL
-      && ! valid_bo (value))
+      && ! valid_bo (value, dialect))
     *errmsg = _("invalid conditional option");
   return insn | ((value & 0x1f) << 21);
 }
 
 static long
-extract_bo (insn, invalid)
+extract_bo (insn, dialect, invalid)
      unsigned long insn;
+     int dialect;
      int *invalid;
 {
   long value;
 
   value = (insn >> 21) & 0x1f;
   if (invalid != (int *) NULL
-      && ! valid_bo (value))
+      && ! valid_bo (value, dialect))
     *invalid = 1;
   return value;
 }
@@ -672,14 +786,15 @@ extract_bo (insn, invalid)
    extracting it, we force it to be even.  */
 
 static unsigned long
-insert_boe (insn, value, errmsg)
+insert_boe (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect;
      const char **errmsg;
 {
   if (errmsg != (const char **) NULL)
     {
-      if (! valid_bo (value))
+      if (! valid_bo (value, dialect))
 	*errmsg = _("invalid conditional option");
       else if ((value & 1) != 0)
 	*errmsg = _("attempt to set y bit when using + or - modifier");
@@ -688,15 +803,16 @@ insert_boe (insn, value, errmsg)
 }
 
 static long
-extract_boe (insn, invalid)
+extract_boe (insn, dialect, invalid)
      unsigned long insn;
+     int dialect;
      int *invalid;
 {
   long value;
 
   value = (insn >> 21) & 0x1f;
   if (invalid != (int *) NULL
-      && ! valid_bo (value))
+      && ! valid_bo (value, dialect))
     *invalid = 1;
   return value & 0x1e;
 }
@@ -706,9 +822,10 @@ extract_boe (insn, invalid)
 
 /*ARGSUSED*/
 static unsigned long
-insert_ds (insn, value, errmsg)
+insert_ds (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg;
 {
   if ((value & 3) != 0 && errmsg != NULL)
@@ -718,23 +835,22 @@ insert_ds (insn, value, errmsg)
 
 /*ARGSUSED*/
 static long
-extract_ds (insn, invalid)
+extract_ds (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid ATTRIBUTE_UNUSED;
 {
-  if ((insn & 0x8000) != 0)
-    return (insn & 0xfffc) - 0x10000;
-  else
-    return insn & 0xfffc;
+  return ((insn & 0xfffc) ^ 0x8000) - 0x8000;
 }
 
 /* The DE field in a DE form instruction.  */
 
 /*ARGSUSED*/
 static unsigned long
-insert_de (insn, value, errmsg)
+insert_de (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg;
 {
   if ((value > 2047 || value < -2048) && errmsg != NULL)
@@ -744,8 +860,9 @@ insert_de (insn, value, errmsg)
 
 /*ARGSUSED*/
 static long
-extract_de (insn, invalid)
+extract_de (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid ATTRIBUTE_UNUSED;
 {
   return (insn & 0xfff0) >> 4;
@@ -755,9 +872,10 @@ extract_de (insn, invalid)
 
 /*ARGSUSED*/
 static unsigned long
-insert_des (insn, value, errmsg)
+insert_des (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg;
 {
   if ((value > 8191 || value < -8192) && errmsg != NULL)
@@ -769,14 +887,12 @@ insert_des (insn, value, errmsg)
 
 /*ARGSUSED*/
 static long
-extract_des (insn, invalid)
+extract_des (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid ATTRIBUTE_UNUSED;
 {
-  if ((insn & 0x8000) != 0)
-    return ((insn & 0xfff0) >> 2) - 0x4000;
-  else
-    return (insn & 0xfff0) >> 2;
+  return (((insn >> 2) & 0x3ffc) ^ 0x2000) - 0x2000;
 }
 
 /* The LI field in an I form instruction.  The lower two bits are
@@ -784,9 +900,10 @@ extract_des (insn, invalid)
 
 /*ARGSUSED*/
 static unsigned long
-insert_li (insn, value, errmsg)
+insert_li (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg;
 {
   if ((value & 3) != 0 && errmsg != (const char **) NULL)
@@ -796,14 +913,12 @@ insert_li (insn, value, errmsg)
 
 /*ARGSUSED*/
 static long
-extract_li (insn, invalid)
+extract_li (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid ATTRIBUTE_UNUSED;
 {
-  if ((insn & 0x2000000) != 0)
-    return (insn & 0x3fffffc) - 0x4000000;
-  else
-    return insn & 0x3fffffc;
+  return ((insn & 0x3fffffc) ^ 0x2000000) - 0x2000000;
 }
 
 /* The MB and ME fields in an M form instruction expressed as a single
@@ -812,9 +927,10 @@ extract_li (insn, invalid)
    instruction which uses a field of this type.  */
 
 static unsigned long
-insert_mbe (insn, value, errmsg)
+insert_mbe (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg;
 {
   unsigned long uval, mask;
@@ -869,8 +985,9 @@ insert_mbe (insn, value, errmsg)
 }
 
 static long
-extract_mbe (insn, invalid)
+extract_mbe (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid;
 {
   long ret;
@@ -904,9 +1021,10 @@ extract_mbe (insn, invalid)
 
 /*ARGSUSED*/
 static unsigned long
-insert_mb6 (insn, value, errmsg)
+insert_mb6 (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg ATTRIBUTE_UNUSED;
 {
   return insn | ((value & 0x1f) << 6) | (value & 0x20);
@@ -914,8 +1032,9 @@ insert_mb6 (insn, value, errmsg)
 
 /*ARGSUSED*/
 static long
-extract_mb6 (insn, invalid)
+extract_mb6 (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid ATTRIBUTE_UNUSED;
 {
   return ((insn >> 6) & 0x1f) | (insn & 0x20);
@@ -925,9 +1044,10 @@ extract_mb6 (insn, invalid)
    0.  */
 
 static unsigned long
-insert_nb (insn, value, errmsg)
+insert_nb (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg;
 {
   if (value < 0 || value > 32)
@@ -939,8 +1059,9 @@ insert_nb (insn, value, errmsg)
 
 /*ARGSUSED*/
 static long
-extract_nb (insn, invalid)
+extract_nb (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid ATTRIBUTE_UNUSED;
 {
   long ret;
@@ -958,25 +1079,24 @@ extract_nb (insn, invalid)
 
 /*ARGSUSED*/
 static unsigned long
-insert_nsi (insn, value, errmsg)
+insert_nsi (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg ATTRIBUTE_UNUSED;
 {
   return insn | ((- value) & 0xffff);
 }
 
 static long
-extract_nsi (insn, invalid)
+extract_nsi (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid;
 {
   if (invalid != (int *) NULL)
     *invalid = 1;
-  if ((insn & 0x8000) != 0)
-    return - ((long)(insn & 0xffff) - 0x10000);
-  else
-    return - (long)(insn & 0xffff);
+  return - (((insn & 0xffff) ^ 0x8000) - 0x8000);
 }
 
 /* The RA field in a D or X form instruction which is an updating
@@ -984,9 +1104,10 @@ extract_nsi (insn, invalid)
    equal the RT field.  */
 
 static unsigned long
-insert_ral (insn, value, errmsg)
+insert_ral (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg;
 {
   if (value == 0
@@ -999,9 +1120,10 @@ insert_ral (insn, value, errmsg)
    restrictions.  */
 
 static unsigned long
-insert_ram (insn, value, errmsg)
+insert_ram (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg;
 {
   if ((unsigned long) value >= ((insn >> 21) & 0x1f))
@@ -1014,9 +1136,10 @@ insert_ram (insn, value, errmsg)
    field may not be zero.  */
 
 static unsigned long
-insert_ras (insn, value, errmsg)
+insert_ras (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg;
 {
   if (value == 0)
@@ -1032,17 +1155,19 @@ insert_ras (insn, value, errmsg)
 
 /*ARGSUSED*/
 static unsigned long
-insert_rbs (insn, value, errmsg)
+insert_rbs (insn, value, dialect, errmsg)
      unsigned long insn;
      long value ATTRIBUTE_UNUSED;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg ATTRIBUTE_UNUSED;
 {
   return insn | (((insn >> 21) & 0x1f) << 11);
 }
 
 static long
-extract_rbs (insn, invalid)
+extract_rbs (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid;
 {
   if (invalid != (int *) NULL
@@ -1055,9 +1180,10 @@ extract_rbs (insn, invalid)
 
 /*ARGSUSED*/
 static unsigned long
-insert_sh6 (insn, value, errmsg)
+insert_sh6 (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg ATTRIBUTE_UNUSED;
 {
   return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4);
@@ -1065,8 +1191,9 @@ insert_sh6 (insn, value, errmsg)
 
 /*ARGSUSED*/
 static long
-extract_sh6 (insn, invalid)
+extract_sh6 (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid ATTRIBUTE_UNUSED;
 {
   return ((insn >> 11) & 0x1f) | ((insn << 4) & 0x20);
@@ -1076,17 +1203,19 @@ extract_sh6 (insn, invalid)
    lower 5 bits are stored in the upper 5 and vice- versa.  */
 
 static unsigned long
-insert_spr (insn, value, errmsg)
+insert_spr (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg ATTRIBUTE_UNUSED;
 {
   return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
 }
 
 static long
-extract_spr (insn, invalid)
+extract_spr (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid ATTRIBUTE_UNUSED;
 {
   return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
@@ -1103,9 +1232,10 @@ extract_spr (insn, invalid)
 #define TB (268)
 
 static unsigned long
-insert_tbr (insn, value, errmsg)
+insert_tbr (insn, value, dialect, errmsg)
      unsigned long insn;
      long value;
+     int dialect ATTRIBUTE_UNUSED;
      const char **errmsg ATTRIBUTE_UNUSED;
 {
   if (value == 0)
@@ -1114,8 +1244,9 @@ insert_tbr (insn, value, errmsg)
 }
 
 static long
-extract_tbr (insn, invalid)
+extract_tbr (insn, dialect, invalid)
      unsigned long insn;
+     int dialect ATTRIBUTE_UNUSED;
      int *invalid ATTRIBUTE_UNUSED;
 {
   long ret;
@@ -1422,7 +1553,7 @@ extract_tbr (insn, invalid)
 #define PPC     PPC_OPCODE_PPC | PPC_OPCODE_ANY
 #define PPCCOM	PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_ANY
 #define PPC32   PPC_OPCODE_PPC | PPC_OPCODE_32 | PPC_OPCODE_ANY
-#define PPC64   PPC_OPCODE_64 | PPC_OPCODE_ANY
+#define PPC64   PPC_OPCODE_64 | PPC_OPCODE_PPC | PPC_OPCODE_ANY
 #define PPCONLY	PPC_OPCODE_PPC
 #define PPC403	PPC_OPCODE_403
 #define PPC405	PPC403


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