2011-05-24 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
[deliverable/binutils-gdb.git] / opcodes / ppc-dis.c
index 2cbbec84a71bb60ef16fd34f9d509cfe11b49897..8771f95b15b6f89e109064238ec19c988d307fba 100644 (file)
@@ -1,6 +1,6 @@
 /* ppc-dis.c -- Disassemble PowerPC instructions
    Copyright 1994, 1995, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008, 2009 Free Software Foundation, Inc.
+   2008, 2009, 2010 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support
 
    This file is part of the GNU opcodes library.
@@ -50,108 +50,126 @@ struct ppc_mopt {
 };
 
 struct ppc_mopt ppc_opts[] = {
-  { "403",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_403
-               | PPC_OPCODE_32),
+  { "403",     (PPC_OPCODE_PPC | PPC_OPCODE_403),
     0 },
-  { "405",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_403
-               | PPC_OPCODE_405 | PPC_OPCODE_32),
+  { "405",     (PPC_OPCODE_PPC | PPC_OPCODE_403 | PPC_OPCODE_405),
     0 },
-  { "440",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32
-               | PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
+  { "440",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440
+               | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
     0 },
-  { "464",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32
-               | PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
+  { "464",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440
+               | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
     0 },
-  { "601",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_601
-               | PPC_OPCODE_32),
+  { "476",     (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_440
+               | PPC_OPCODE_476 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5),
     0 },
-  { "603",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32),
+  { "601",     (PPC_OPCODE_PPC | PPC_OPCODE_601),
     0 },
-  { "604",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32),
+  { "603",     (PPC_OPCODE_PPC),
     0 },
-  { "620",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64),
+  { "604",     (PPC_OPCODE_PPC),
     0 },
-  { "7400",    (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC
-               | PPC_OPCODE_32),
+  { "620",     (PPC_OPCODE_PPC | PPC_OPCODE_64),
     0 },
-  { "7410",    (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC
-               | PPC_OPCODE_32),
+  { "7400",    (PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC),
     0 },
-  { "7450",    (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC
-               | PPC_OPCODE_32),
+  { "7410",    (PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC),
     0 },
-  { "7455",    (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC
-               | PPC_OPCODE_32),
+  { "7450",    (PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC),
+    0 },
+  { "7455",    (PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC),
     0 },
   { "750cl",   (PPC_OPCODE_PPC | PPC_OPCODE_PPCPS)
     , 0 },
-  { "altivec", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC),
+  { "a2",      (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_POWER4
+               | PPC_OPCODE_POWER5 | PPC_OPCODE_CACHELCK | PPC_OPCODE_64
+               | PPC_OPCODE_A2),
+    0 },
+  { "altivec", (PPC_OPCODE_PPC),
     PPC_OPCODE_ALTIVEC },
   { "any",     0,
     PPC_OPCODE_ANY },
-  { "booke",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32),
+  { "booke",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE),
     0 },
-  { "booke32", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32),
+  { "booke32", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE),
     0 },
-  { "cell",    (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64
-               | PPC_OPCODE_POWER4 | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC),
+  { "cell",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
+               | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC),
     0 },
-  { "com",     (PPC_OPCODE_COMMON | PPC_OPCODE_32),
+  { "com",     (PPC_OPCODE_COMMON),
     0 },
-  { "e300",    (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32
-               | PPC_OPCODE_E300),
+  { "e300",    (PPC_OPCODE_PPC | PPC_OPCODE_E300),
     0 },
   { "e500",    (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_E500MC),
+               | PPC_OPCODE_E500),
     0 },
   { "e500mc",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
                | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
                | PPC_OPCODE_E500MC),
     0 },
+  { "e500mc64",  (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),
+    0 },
   { "e500x2",  (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_E500MC),
+               | PPC_OPCODE_E500),
     0 },
   { "efs",     (PPC_OPCODE_PPC | PPC_OPCODE_EFS),
     0 },
-  { "power4",  (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64
-               | PPC_OPCODE_POWER4),
+  { "power4",  (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4),
     0 },
-  { "power5",  (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64
-               | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5),
+  { "power5",  (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
+               | PPC_OPCODE_POWER5),
     0 },
-  { "power6",  (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64
-               | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
-               | PPC_OPCODE_ALTIVEC),
+  { "power6",  (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
+               | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC),
     0 },
-  { "power7",  (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ISEL
-               | PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5
-               | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC
-               | PPC_OPCODE_VSX),
+  { "power7",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
+               | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
+               | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
     0 },
-  { "ppc",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32),
+  { "ppc",     (PPC_OPCODE_PPC),
     0 },
-  { "ppc32",   (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32),
+  { "ppc32",   (PPC_OPCODE_PPC),
     0 },
-  { "ppc64",   (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64),
+  { "ppc64",   (PPC_OPCODE_PPC | PPC_OPCODE_64),
     0 },
-  { "ppc64bridge", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64_BRIDGE
-                   | PPC_OPCODE_64),
+  { "ppc64bridge", (PPC_OPCODE_PPC | PPC_OPCODE_64_BRIDGE),
     0 },
   { "ppcps",   (PPC_OPCODE_PPC | PPC_OPCODE_PPCPS),
     0 },
-  { "pwr",     (PPC_OPCODE_POWER | PPC_OPCODE_32),
+  { "pwr",     (PPC_OPCODE_POWER),
+    0 },
+  { "pwr2",    (PPC_OPCODE_POWER | PPC_OPCODE_POWER2),
+    0 },
+  { "pwr4",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4),
+    0 },
+  { "pwr5",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
+               | PPC_OPCODE_POWER5),
     0 },
-  { "pwr2",    (PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_32),
+  { "pwr5x",   (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
+               | PPC_OPCODE_POWER5),
+    0 },
+  { "pwr6",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
+               | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC),
+    0 },
+  { "pwr7",    (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
+               | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
+               | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
     0 },
-  { "pwrx",    (PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_32),
+  { "pwrx",    (PPC_OPCODE_POWER | PPC_OPCODE_POWER2),
     0 },
   { "spe",     (PPC_OPCODE_PPC | PPC_OPCODE_EFS),
     PPC_OPCODE_SPE },
-  { "vsx",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC),
+  { "titan",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_PMR
+               | PPC_OPCODE_RFMCI | PPC_OPCODE_TITAN),
+    0 },
+  { "vsx",     (PPC_OPCODE_PPC),
     PPC_OPCODE_VSX },
 };
 
@@ -171,8 +189,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 & ~(PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX
-                            | PPC_OPCODE_SPE | PPC_OPCODE_ANY)) != 0)
+           if ((ppc_cpu & ~(ppc_cpu_t) (PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX
+                                        | PPC_OPCODE_SPE | PPC_OPCODE_ANY)) != 0)
              break;
          }
        ppc_cpu = ppc_opts[i].cpu;
@@ -209,15 +227,9 @@ powerpc_init_dialect (struct disassemble_info *info)
       if ((new_cpu = ppc_parse_cpu (dialect, arg)) != 0)
        dialect = new_cpu;
       else if (strcmp (arg, "32") == 0)
-       {
-         dialect &= ~PPC_OPCODE_64;
-         dialect |= PPC_OPCODE_32;
-       }
+       dialect &= ~(ppc_cpu_t) PPC_OPCODE_64;
       else if (strcmp (arg, "64") == 0)
-       {
-         dialect |= PPC_OPCODE_64;
-         dialect &= ~PPC_OPCODE_32;
-       }
+       dialect |= PPC_OPCODE_64;
       else
        fprintf (stderr, _("warning: ignoring unknown -M%s option\n"), arg);
 
@@ -226,18 +238,15 @@ powerpc_init_dialect (struct disassemble_info *info)
       arg = end;
     }
 
-  if ((dialect & ~(PPC_OPCODE_ANY | PPC_OPCODE_32 | PPC_OPCODE_64)) == 0)
+  if ((dialect & ~(ppc_cpu_t) PPC_OPCODE_64) == 0)
     {
-      if ((dialect & (PPC_OPCODE_32 | PPC_OPCODE_64)) == 0)
-       {
-         if (info->mach == bfd_mach_ppc64)
-           dialect |= PPC_OPCODE_64;
-         else
-           dialect |= PPC_OPCODE_32;
-       }
+      if (info->mach == bfd_mach_ppc64)
+       dialect |= PPC_OPCODE_64;
+      else
+       dialect &= ~(ppc_cpu_t) PPC_OPCODE_64;
       /* Choose a reasonable default.  */
-      dialect |= (PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_CLASSIC
-                 | PPC_OPCODE_601 | PPC_OPCODE_ALTIVEC);
+      dialect |= (PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_601
+                 | PPC_OPCODE_ALTIVEC);
     }
 
   info->private_data = priv;
@@ -338,6 +347,7 @@ print_insn_powerpc (bfd_vma memaddr,
   const struct powerpc_opcode *opcode;
   const struct powerpc_opcode *opcode_end;
   unsigned long op;
+  ppc_cpu_t dialect_orig = dialect;
 
   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
   if (status != 0)
@@ -376,7 +386,7 @@ print_insn_powerpc (bfd_vma memaddr,
 
       if ((insn & opcode->mask) != opcode->opcode
          || (opcode->flags & dialect) == 0
-         || (opcode->deprecated & dialect) != 0)
+         || (opcode->deprecated & dialect_orig) != 0)
        continue;
 
       /* Make two passes over the operands.  First see if any of them
@@ -447,16 +457,14 @@ print_insn_powerpc (bfd_vma memaddr,
            (*info->print_address_func) (memaddr + value, info);
          else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
            (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
-         else if ((operand->flags & PPC_OPERAND_CR) == 0
-                  || (dialect & PPC_OPCODE_PPC) == 0)
-           (*info->fprintf_func) (info->stream, "%ld", value);
          else if ((operand->flags & PPC_OPERAND_FSL) != 0) 
            (*info->fprintf_func) (info->stream, "fsl%ld", value);
          else if ((operand->flags & PPC_OPERAND_FCR) != 0)
            (*info->fprintf_func) (info->stream, "fcr%ld", value);
          else if ((operand->flags & PPC_OPERAND_UDI) != 0)
            (*info->fprintf_func) (info->stream, "%ld", value);
-         else
+         else if ((operand->flags & PPC_OPERAND_CR) != 0
+                  && (dialect & PPC_OPCODE_PPC) != 0)
            {
              if (operand->bitm == 7)
                (*info->fprintf_func) (info->stream, "cr%ld", value);
@@ -473,6 +481,8 @@ print_insn_powerpc (bfd_vma memaddr,
                  (*info->fprintf_func) (info->stream, "%s", cbnames[cc]);
                }
            }
+         else
+           (*info->fprintf_func) (info->stream, "%ld", value);
 
          if (need_paren)
            {
@@ -495,7 +505,7 @@ print_insn_powerpc (bfd_vma memaddr,
 
   if ((dialect & PPC_OPCODE_ANY) != 0)
     {
-      dialect = ~PPC_OPCODE_ANY;
+      dialect = ~(ppc_cpu_t) PPC_OPCODE_ANY;
       goto again;
     }
 
This page took 0.074554 seconds and 4 git commands to generate.