OSDN Git Service

* ppc-dis.c (operand_value_powerpc, skip_optional_operands): New.
authorbergner <bergner>
Thu, 17 May 2007 00:52:14 +0000 (00:52 +0000)
committerbergner <bergner>
Thu, 17 May 2007 00:52:14 +0000 (00:52 +0000)
(print_insn_powerpc): Use the new operand_value_powerpc and
skip_optional_operands functions to omit or print all optional
operands as a group.
* ppc-opc.c (BFF, W, XFL_L, XWRA_MASK): New.
(XFL_MASK): Delete L and W bits from the mask.
(mtfsfi, mtfsfi.): Replace use of BF with BFF.  Relpace use of XRA_MASK
with XWRA_MASK.  Use W.
(mtfsf, mtfsf.): Use XFL_L and W.

opcodes/ChangeLog
opcodes/ppc-dis.c
opcodes/ppc-opc.c

index 3d999bb..5634096 100644 (file)
@@ -1,3 +1,15 @@
+2007-05-16  Peter Bergner  <bergner@vnet.ibm.com>
+
+       * ppc-dis.c (operand_value_powerpc, skip_optional_operands): New.
+       (print_insn_powerpc): Use the new operand_value_powerpc and
+       skip_optional_operands functions to omit or print all optional
+       operands as a group.
+       * ppc-opc.c (BFF, W, XFL_L, XWRA_MASK): New.
+       (XFL_MASK): Delete L and W bits from the mask.
+       (mtfsfi, mtfsfi.): Replace use of BF with BFF.  Relpace use of XRA_MASK
+       with XWRA_MASK.  Use W.
+       (mtfsf, mtfsf.): Use XFL_L and W.
+
 2007-05-14  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR binutils/4502
index 557e5a5..295b04d 100644 (file)
@@ -127,6 +127,56 @@ print_insn_rs6000 (bfd_vma memaddr, struct disassemble_info *info)
   return print_insn_powerpc (memaddr, info, 1, PPC_OPCODE_POWER);
 }
 
+/* Extract the operand value from the PowerPC or POWER instruction.  */
+
+static long
+operand_value_powerpc (const struct powerpc_operand *operand,
+                      unsigned long insn, int dialect)
+{
+  long value;
+  int invalid;
+  /* Extract the value from the instruction.  */
+  if (operand->extract)
+    value = (*operand->extract) (insn, dialect, &invalid);
+  else
+    {
+      value = (insn >> operand->shift) & operand->bitm;
+      if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+       {
+         /* BITM is always some number of zeros followed by some
+            number of ones, followed by some numer of zeros.  */
+         unsigned long top = operand->bitm;
+         /* top & -top gives the rightmost 1 bit, so this
+            fills in any trailing zeros.  */
+         top |= (top & -top) - 1;
+         top &= ~(top >> 1);
+         value = (value ^ top) - top;
+       }
+    }
+
+  return value;
+}
+
+/* Determine whether the optional operand(s) should be printed.  */
+
+static int
+skip_optional_operands (const unsigned char *opindex,
+                       unsigned long insn, int dialect)
+{
+  const struct powerpc_operand *operand;
+
+  for (; *opindex != 0; 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))
+       return 0;
+    }
+
+  return 1;
+}
+
 /* Print a PowerPC or POWER instruction.  */
 
 static int
@@ -172,6 +222,7 @@ print_insn_powerpc (bfd_vma memaddr,
       int invalid;
       int need_comma;
       int need_paren;
+      int skip_optional;
 
       table_op = PPC_OP (opcode->opcode);
       if (op < table_op)
@@ -205,6 +256,7 @@ print_insn_powerpc (bfd_vma memaddr,
       /* Now extract and print the operands.  */
       need_comma = 0;
       need_paren = 0;
+      skip_optional = -1;
       for (opindex = opcode->operands; *opindex != 0; opindex++)
        {
          long value;
@@ -217,32 +269,17 @@ print_insn_powerpc (bfd_vma memaddr,
          if ((operand->flags & PPC_OPERAND_FAKE) != 0)
            continue;
 
-         /* Extract the value from the instruction.  */
-         if (operand->extract)
-           value = (*operand->extract) (insn, dialect, &invalid);
-         else
-           {
-             value = (insn >> operand->shift) & operand->bitm;
-             if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
-               {
-                 /* BITM is always some number of zeros followed by some
-                    number of ones, followed by some numer of zeros.  */
-                 unsigned long top = operand->bitm;
-                 /* top & -top gives the rightmost 1 bit, so this
-                    fills in any trailing zeros.  */
-                 top |= (top & -top) - 1;
-                 top &= ~(top >> 1);
-                 value = (value ^ top) - top;
-               }
-           }
+         /* If all of the optional operands have the value zero,
+            then don't print any of them.  */
+         if (skip_optional < 0
+             && (operand->flags & PPC_OPERAND_OPTIONAL) != 0)
+           skip_optional = skip_optional_operands (opindex, insn, dialect);
 
-         /* If the operand is optional, and the value is zero, don't
-            print anything.  */
-         if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
-             && (operand->flags & PPC_OPERAND_NEXT) == 0
-             && value == 0)
+         if (skip_optional > 0)
            continue;
 
+         value = operand_value_powerpc (operand, insn, dialect);
+
          if (need_comma)
            {
              (*info->fprintf_func) (info->stream, ",");
index 5e2fb28..5995f81 100644 (file)
@@ -154,9 +154,13 @@ const struct powerpc_operand powerpc_operands[] =
 #define CRFD BF
   { 0x7, 23, NULL, NULL, PPC_OPERAND_CR },
 
+  /* The BF field in an X or XL form instruction.  */
+#define BFF BF + 1
+  { 0x7, 23, NULL, NULL, 0 },
+
   /* An optional BF field.  This is used for comparison instructions,
      in which an omitted BF field is taken as zero.  */
-#define OBF BF + 1
+#define OBF BFF + 1
   { 0x7, 23, NULL, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
 
   /* The BFA field in an X or XL form instruction.  */
@@ -515,8 +519,9 @@ const struct powerpc_operand powerpc_operands[] =
 #define WS EVUIMM_8 + 1
   { 0x7, 11, NULL, NULL, 0 },
 
-  /* The L field in an mtmsrd or A form instruction.  */
+  /* The L field in an mtmsrd or A form instruction or W in an X form.  */
 #define A_L WS + 1
+#define W A_L
   { 0x1, 16, NULL, NULL, PPC_OPERAND_OPTIONAL },
 
 #define RMC A_L + 1
@@ -541,6 +546,10 @@ const struct powerpc_operand powerpc_operands[] =
   /* The EH field in larx instruction.  */
 #define EH SH16 + 1
   { 0x1, 0, NULL, NULL, PPC_OPERAND_OPTIONAL },
+
+  /* The L field in an mtfsf or XFL form instruction.  */
+#define XFL_L EH + 1
+  { 0x1, 25, NULL, NULL, PPC_OPERAND_OPTIONAL},
 };
 
 const unsigned int num_powerpc_operands = (sizeof (powerpc_operands)
@@ -1400,6 +1409,9 @@ extract_tbr (unsigned long insn,
 /* An X_MASK with the RA field fixed.  */
 #define XRA_MASK (X_MASK | RA_MASK)
 
+/* An XRA_MASK with the W field clear.  */
+#define XWRA_MASK (XRA_MASK & ~((unsigned long) 1 << 16))
+
 /* An X_MASK with the RB field fixed.  */
 #define XRB_MASK (X_MASK | RB_MASK)
 
@@ -1454,7 +1466,7 @@ extract_tbr (unsigned long insn,
 
 /* An XFL form instruction.  */
 #define XFL(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1) | (((unsigned long)(rc)) & 1))
-#define XFL_MASK (XFL (0x3f, 0x3ff, 1) | (((unsigned long)1) << 25) | (((unsigned long)1) << 16))
+#define XFL_MASK XFL (0x3f, 0x3ff, 1)
 
 /* An X form isel instruction.  */
 #define XISEL(op, xop)  (OP (op) | ((((unsigned long)(xop)) & 0x1f) << 1))
@@ -4586,8 +4598,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 
 { "dcmpoq",  X(63,130),           X_MASK,      POWER6,         { BF,  FRA, FRB } },
 
-{ "mtfsfi",  XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } },
-{ "mtfsfi.", XRC(63,134,1), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } },
+{ "mtfsfi",  XRC(63,134,0), XWRA_MASK|(3<<21)|(1<<11), COM, { BFF, U, W } },
+{ "mtfsfi.", XRC(63,134,1), XWRA_MASK|(3<<21)|(1<<11), COM, { BFF, U, W } },
 
 { "fnabs",   XRC(63,136,0), XRA_MASK,  COM,            { FRT, FRB } },
 { "fnabs.",  XRC(63,136,1), XRA_MASK,  COM,            { FRT, FRB } },
@@ -4636,8 +4648,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 
 { "dtstsfq", X(63,674),            X_MASK,     POWER6,         { BF,  FRA, FRB } },
 
-{ "mtfsf",   XFL(63,711,0), XFL_MASK,  COM,            { FLM, FRB } },
-{ "mtfsf.",  XFL(63,711,1), XFL_MASK,  COM,            { FLM, FRB } },
+{ "mtfsf",   XFL(63,711,0), XFL_MASK,  COM,            { FLM, FRB, XFL_L, W } },
+{ "mtfsf.",  XFL(63,711,1), XFL_MASK,  COM,            { FLM, FRB, XFL_L, W } },
 
 { "drdpq",   XRC(63,770,0), X_MASK,    POWER6,         { FRT, FRB } },
 { "drdpq.",  XRC(63,770,1), X_MASK,    POWER6,         { FRT, FRB } },