PowerPC64 fails reloc-discard test
[deliverable/binutils-gdb.git] / opcodes / ppc-dis.c
index f8b0292c4e467764c777dbfac85ce49a36081044..bd6072ef0c11c31a08e54315d6894b433608e104 100644 (file)
@@ -367,12 +367,12 @@ powerpc_init_dialect (struct disassemble_info *info)
   POWERPC_DIALECT(info) = dialect;
 }
 
-#define PPC_OPCD_SEGS 64
-static unsigned short powerpc_opcd_indices[PPC_OPCD_SEGS+1];
-#define VLE_OPCD_SEGS 32
-static unsigned short vle_opcd_indices[VLE_OPCD_SEGS+1];
-#define SPE2_OPCD_SEGS 13
-static unsigned short spe2_opcd_indices[SPE2_OPCD_SEGS+1];
+#define PPC_OPCD_SEGS (1 + PPC_OP (-1))
+static unsigned short powerpc_opcd_indices[PPC_OPCD_SEGS + 1];
+#define VLE_OPCD_SEGS (1 + VLE_OP_TO_SEG (VLE_OP (-1, 0xffff)))
+static unsigned short vle_opcd_indices[VLE_OPCD_SEGS + 1];
+#define SPE2_OPCD_SEGS (1 + SPE2_XOP_TO_SEG (SPE2_XOP (-1)))
+static unsigned short spe2_opcd_indices[SPE2_OPCD_SEGS + 1];
 
 /* Calculate opcode table indices to speed up disassembly,
    and init dialect.  */
@@ -660,28 +660,22 @@ print_insn_powerpc (bfd_vma memaddr,
   int status;
   uint64_t insn;
   const struct powerpc_opcode *opcode;
-  bfd_boolean insn_is_short;
+  int insn_length = 4;  /* Assume we have a normal 4-byte instruction.  */
 
   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+
+  /* The final instruction may be a 2-byte VLE insn.  */
+  if (status != 0 && (dialect & PPC_OPCODE_VLE) != 0)
+    {
+      /* Clear buffer so unused bytes will not have garbage in them.  */
+      buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0;
+      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
+    }
+
   if (status != 0)
     {
-      /* The final instruction may be a 2-byte VLE insn.  */
-      if ((dialect & PPC_OPCODE_VLE) != 0)
-        {
-          /* Clear buffer so unused bytes will not have garbage in them.  */
-          buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0;
-          status = (*info->read_memory_func) (memaddr, buffer, 2, info);
-          if (status != 0)
-            {
-              (*info->memory_error_func) (status, memaddr, info);
-              return -1;
-            }
-        }
-      else
-        {
-          (*info->memory_error_func) (status, memaddr, info);
-          return -1;
-        }
+      (*info->memory_error_func) (status, memaddr, info);
+      return -1;
     }
 
   if (bigendian)
@@ -691,12 +685,15 @@ print_insn_powerpc (bfd_vma memaddr,
 
   /* Get the major opcode of the insn.  */
   opcode = NULL;
-  insn_is_short = FALSE;
   if ((dialect & PPC_OPCODE_VLE) != 0)
     {
       opcode = lookup_vle (insn);
-      if (opcode != NULL)
-       insn_is_short = PPC_OP_SE_VLE(opcode->mask);
+      if (opcode != NULL && PPC_OP_SE_VLE (opcode->mask))
+       {
+         /* The operands will be fetched out of the 16-bit instruction.  */
+         insn >>= 16;
+         insn_length = 2;
+       }
     }
   if (opcode == NULL && (dialect & PPC_OPCODE_SPE2) != 0)
     opcode = lookup_spe2 (insn);
@@ -718,10 +715,6 @@ print_insn_powerpc (bfd_vma memaddr,
       else
        (*info->fprintf_func) (info->stream, "%s", opcode->name);
 
-      if (insn_is_short)
-        /* The operands will be fetched out of the 16-bit instruction.  */
-        insn >>= 16;
-
       /* Now extract and print the operands.  */
       need_comma = 0;
       need_paren = 0;
@@ -732,12 +725,6 @@ print_insn_powerpc (bfd_vma memaddr,
 
          operand = powerpc_operands + *opindex;
 
-         /* Operands that are marked FAKE are simply ignored.  We
-            already made sure that the extract function considered
-            the instruction to be valid.  */
-         if ((operand->flags & PPC_OPERAND_FAKE) != 0)
-           continue;
-
          /* If all of the optional operands have the value zero,
             then don't print any of them.  */
          if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
@@ -813,16 +800,8 @@ print_insn_powerpc (bfd_vma memaddr,
            }
        }
 
-      /* We have found and printed an instruction.
-         If it was a short VLE instruction we have more to do.  */
-      if (insn_is_short)
-        {
-          memaddr += 2;
-          return 2;
-        }
-      else
-        /* Otherwise, return.  */
-        return 4;
+      /* We have found and printed an instruction.  */
+      return insn_length;
     }
 
   /* We could not find a match.  */
@@ -831,24 +810,30 @@ print_insn_powerpc (bfd_vma memaddr,
   return 4;
 }
 
-const disasm_options_t *
+const disasm_options_and_args_t *
 disassembler_options_powerpc (void)
 {
-  static disasm_options_t *opts = NULL;
+  static disasm_options_and_args_t *opts_and_args;
 
-  if (opts == NULL)
+  if (opts_and_args == NULL)
     {
       size_t i, num_options = ARRAY_SIZE (ppc_opts);
-      opts = XNEW (disasm_options_t);
+      disasm_options_t *opts;
+
+      opts_and_args = XNEW (disasm_options_and_args_t);
+      opts_and_args->args = NULL;
+
+      opts = &opts_and_args->options;
       opts->name = XNEWVEC (const char *, num_options + 1);
+      opts->description = NULL;
+      opts->arg = NULL;
       for (i = 0; i < num_options; i++)
        opts->name[i] = ppc_opts[i].opt;
       /* The array we return must be NULL terminated.  */
       opts->name[i] = NULL;
-      opts->description = NULL;
     }
 
-  return opts;
+  return opts_and_args;
 }
 
 void
This page took 0.026455 seconds and 4 git commands to generate.