gdb/
[deliverable/binutils-gdb.git] / opcodes / ppc-dis.c
index 331a3a17b766eb8df5d848b42926433ccfca7f4d..4e2bcd7835b9ceea208967012e8b0e802d7804dc 100644 (file)
    Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
-#include <stdio.h>
 #include "sysdep.h"
+#include <stdio.h>
 #include "dis-asm.h"
 #include "elf-bfd.h"
-#include "elf32-ppc.h"
 #include "elf/ppc.h"
 #include "opintl.h"
 #include "opcode/ppc.h"
@@ -89,7 +88,7 @@ struct ppc_mopt ppc_opts[] = {
                | PPC_OPCODE_A2),
     0 },
   { "altivec", (PPC_OPCODE_PPC),
-    PPC_OPCODE_ALTIVEC },
+    PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 },
   { "any",     0,
     PPC_OPCODE_ANY },
   { "booke",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE),
@@ -148,6 +147,11 @@ struct ppc_mopt ppc_opts[] = {
                | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
                | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
     0 },
+  { "power8",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
+               | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
+               | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_HTM
+               | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_VSX),
+    0 },
   { "ppc",     (PPC_OPCODE_PPC),
     0 },
   { "ppc32",   (PPC_OPCODE_PPC),
@@ -177,6 +181,11 @@ struct ppc_mopt ppc_opts[] = {
                | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
                | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
     0 },
+  { "pwr8",    (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
+               | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
+               | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_HTM
+               | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_VSX),
+    0 },
   { "pwrx",    (PPC_OPCODE_POWER | PPC_OPCODE_POWER2),
     0 },
   { "spe",     (PPC_OPCODE_PPC | PPC_OPCODE_EFS),
@@ -188,6 +197,8 @@ struct ppc_mopt ppc_opts[] = {
     PPC_OPCODE_VLE },
   { "vsx",     (PPC_OPCODE_PPC),
     PPC_OPCODE_VSX },
+  { "htm",     (PPC_OPCODE_PPC),
+    PPC_OPCODE_HTM },
 };
 
 /* Switch between Booke and VLE dialects for interlinked dumps.  */
@@ -200,7 +211,10 @@ get_powerpc_dialect (struct disassemble_info *info)
 
   /* Disassemble according to the section headers flags for VLE-mode.  */
   if (dialect & PPC_OPCODE_VLE
-      && is_ppc_vle (info->section))
+      && info->section->owner != NULL
+      && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour
+      && elf_object_id (info->section->owner) == PPC32_ELF_DATA
+      && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)
     return dialect;
   else
     return dialect & ~ PPC_OPCODE_VLE;
@@ -209,13 +223,8 @@ get_powerpc_dialect (struct disassemble_info *info)
 /* Handle -m and -M options that set cpu type, and .machine arg.  */
 
 ppc_cpu_t
-ppc_parse_cpu (ppc_cpu_t ppc_cpu, const char *arg)
+ppc_parse_cpu (ppc_cpu_t ppc_cpu, ppc_cpu_t *sticky, const char *arg)
 {
-  const ppc_cpu_t retain_mask = (PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX
-                                | PPC_OPCODE_SPE | PPC_OPCODE_ANY
-                                | PPC_OPCODE_VLE | PPC_OPCODE_PMR);
-  /* Sticky bits.  */
-  ppc_cpu_t retain_flags = ppc_cpu & retain_mask;
   unsigned int i;
 
   for (i = 0; i < sizeof (ppc_opts) / sizeof (ppc_opts[0]); i++)
@@ -223,8 +232,8 @@ ppc_parse_cpu (ppc_cpu_t ppc_cpu, const char *arg)
       {
        if (ppc_opts[i].sticky)
          {
-           retain_flags |= ppc_opts[i].sticky;
-           if ((ppc_cpu & ~retain_mask) != 0)
+           *sticky |= ppc_opts[i].sticky;
+           if ((ppc_cpu & ~*sticky) != 0)
              break;
          }
        ppc_cpu = ppc_opts[i].cpu;
@@ -233,7 +242,7 @@ ppc_parse_cpu (ppc_cpu_t ppc_cpu, const char *arg)
   if (i >= sizeof (ppc_opts) / sizeof (ppc_opts[0]))
     return 0;
 
-  ppc_cpu |= retain_flags;
+  ppc_cpu |= *sticky;
   return ppc_cpu;
 }
 
@@ -243,12 +252,72 @@ static void
 powerpc_init_dialect (struct disassemble_info *info)
 {
   ppc_cpu_t dialect = 0;
+  ppc_cpu_t sticky = 0;
   char *arg;
   struct dis_private *priv = calloc (sizeof (*priv), 1);
 
   if (priv == NULL)
     priv = &private;
 
+  switch (info->mach)
+    {
+    case bfd_mach_ppc_403:
+    case bfd_mach_ppc_403gc:
+      dialect = (PPC_OPCODE_PPC | PPC_OPCODE_403);
+      break;
+    case bfd_mach_ppc_405:
+      dialect = (PPC_OPCODE_PPC | PPC_OPCODE_403 | PPC_OPCODE_405);
+      break;
+    case bfd_mach_ppc_601:
+      dialect = (PPC_OPCODE_PPC | PPC_OPCODE_601);
+      break;
+    case bfd_mach_ppc_a35:
+    case bfd_mach_ppc_rs64ii:
+    case bfd_mach_ppc_rs64iii:
+      dialect = (PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_64);
+      break;
+    case bfd_mach_ppc_e500:
+      dialect = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
+                | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
+                | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+                | PPC_OPCODE_E500);
+      break;
+    case bfd_mach_ppc_e500mc:
+      dialect = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
+                | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+                | PPC_OPCODE_E500MC);
+      break;
+    case bfd_mach_ppc_e500mc64:
+      dialect = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
+                | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+                | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER5
+                | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7);
+      break;
+    case bfd_mach_ppc_e5500:
+      dialect = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
+                | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+                | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
+                | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
+                | PPC_OPCODE_POWER7);
+      break;
+    case bfd_mach_ppc_e6500:
+      dialect = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
+                | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+                | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_ALTIVEC
+                | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_E6500 | PPC_OPCODE_POWER4
+                | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7);
+      break;
+    case bfd_mach_ppc_titan:
+      dialect = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_PMR
+                | PPC_OPCODE_RFMCI | PPC_OPCODE_TITAN);
+      break;
+    case bfd_mach_ppc_vle:
+      dialect = (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_VLE);
+      break;
+    default:
+      dialect = ppc_parse_cpu (dialect, &sticky, "power8") | PPC_OPCODE_ANY;
+    }
+
   arg = info->disassembler_options;
   while (arg != NULL)
     {
@@ -258,7 +327,7 @@ powerpc_init_dialect (struct disassemble_info *info)
       if (end != NULL)
        *end = 0;
 
-      if ((new_cpu = ppc_parse_cpu (dialect, arg)) != 0)
+      if ((new_cpu = ppc_parse_cpu (dialect, &sticky, arg)) != 0)
        dialect = new_cpu;
       else if (strcmp (arg, "32") == 0)
        dialect &= ~(ppc_cpu_t) PPC_OPCODE_64;
@@ -272,20 +341,6 @@ powerpc_init_dialect (struct disassemble_info *info)
       arg = end;
     }
 
-  if ((dialect & ~(ppc_cpu_t) PPC_OPCODE_64) == 0)
-    {
-      if (info->mach == bfd_mach_ppc64)
-       dialect |= PPC_OPCODE_64;
-      else
-       dialect &= ~(ppc_cpu_t) PPC_OPCODE_64;
-      if (info->mach == bfd_mach_ppc_vle)
-        dialect |= PPC_OPCODE_PPC | PPC_OPCODE_VLE;
-      else
-        /* Choose a reasonable default.  */
-        dialect |= (PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_601
-                   | PPC_OPCODE_ALTIVEC);
-    }
-
   info->private_data = priv;
   POWERPC_DIALECT(info) = dialect;
 }
@@ -664,7 +719,7 @@ print_insn_powerpc (bfd_vma memaddr,
              (*info->fprintf_func) (info->stream, "%s", cbnames[cc]);
            }
          else
-           (*info->fprintf_func) (info->stream, "%d", value);
+           (*info->fprintf_func) (info->stream, "%d", (int) value);
 
          if (need_paren)
            {
This page took 0.026644 seconds and 4 git commands to generate.