PowerPC -Mraw disassembly
authorAlan Modra <amodra@gmail.com>
Wed, 29 Mar 2017 03:13:06 +0000 (13:43 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 29 Mar 2017 12:25:18 +0000 (22:55 +1030)
This adds -Mraw for PowerPC objdump, a disassembler option to display
the underlying machine instruction rather than aliases.  For example,
"rlwinm" always rather than "rotlwi" when the instruction is
performing a simple rotate.

binutils/
* doc/binutils.texi (objdump): Document PowerPC -M options.
gas/
* config/tc-ppc.c (md_parse_option): Reject -mraw.
include/
* opcode/ppc.h (PPC_OPCODE_RAW): Define.
(PPC_OPCODE_*): Make them all unsigned long long constants.
opcodes/
* ppc-dis.c (ppc_opts): Set PPC_OPCODE_PPC for "any" flags.  Add
"raw" option.
(lookup_powerpc): Don't special case -1 dialect.  Handle
PPC_OPCODE_RAW.
(print_insn_powerpc): Mask out PPC_OPCODE_ANY on first
lookup_powerpc call, pass it on second.

binutils/ChangeLog
binutils/doc/binutils.texi
gas/ChangeLog
gas/config/tc-ppc.c
include/ChangeLog
include/opcode/ppc.h
opcodes/ChangeLog
opcodes/ppc-dis.c

index 5ee8073f05797207c9ebc32c275461ace9c69566..95595876bef7720e0dbd5da24af2c3d091dd3921 100644 (file)
@@ -1,3 +1,7 @@
+2017-03-29  Alan Modra  <amodra@gmail.com>
+
+       * doc/binutils.texi (objdump): Document PowerPC -M options.
+
 2017-03-21  Andi Kleen  <ak@linux.intel.com>
 
        * objdump.c (unwind_inlines): Add.
index ffa7dfd9092cc1927436abf93fbd229c2f3e57ff..da4ed52dc46d491e8c2e17e7c37b23b58a612db8 100644 (file)
@@ -2369,12 +2369,34 @@ When in AT&T mode, instructs the disassembler to print a mnemonic
 suffix even when the suffix could be inferred by the operands.
 @end table
 
-For PowerPC, @option{booke} controls the disassembly of BookE
-instructions.  @option{32} and @option{64} select PowerPC and
-PowerPC64 disassembly, respectively.  @option{e300} selects
-disassembly for the e300 family.  @option{440} selects disassembly for
-the PowerPC 440.  @option{ppcps} selects disassembly for the paired
-single instructions of the PPC750CL.
+For PowerPC, the @option{-M} argument @option{raw} selects
+disasssembly of hardware insns rather than aliases.  For example, you
+will see @code{rlwinm} rather than @code{clrlwi}, and @code{addi}
+rather than @code{li}.  All of the @option{-m} arguments for
+@command{gas} that select a CPU are supported.  These are:
+@option{403}, @option{405}, @option{440}, @option{464}, @option{476},
+@option{601}, @option{603}, @option{604}, @option{620}, @option{7400},
+@option{7410}, @option{7450}, @option{7455}, @option{750cl},
+@option{821}, @option{850}, @option{860}, @option{a2}, @option{booke},
+@option{booke32}, @option{cell}, @option{com}, @option{e200z4},
+@option{e300}, @option{e500}, @option{e500mc}, @option{e500mc64},
+@option{e500x2}, @option{e5500}, @option{e6500}, @option{efs},
+@option{power4}, @option{power5}, @option{power6}, @option{power7},
+@option{power8}, @option{power9}, @option{ppc}, @option{ppc32},
+@option{ppc64}, @option{ppc64bridge}, @option{ppcps}, @option{pwr},
+@option{pwr2}, @option{pwr4}, @option{pwr5}, @option{pwr5x},
+@option{pwr6}, @option{pwr7}, @option{pwr8}, @option{pwr9},
+@option{pwrx}, @option{titan}, and @option{vle}.
+@option{32} and @option{64} modify the default or a prior CPU
+selection, disabling and enabling 64-bit insns respectively.  In
+addition, @option{altivec}, @option{any}, @option{htm}, @option{vsx},
+and @option{spe} add capabilities to a previous @emph{or later} CPU
+selection.  @option{any} will disassemble any opcode known to
+binutils, but in cases where an opcode has two different meanings or
+different arguments, you may not see the disassembly you expect.
+If you disassemble without giving a CPU selection, a default will be
+chosen from information gleaned by BFD from the object files headers,
+but the result again may not be as you expect.
 
 For MIPS, this option controls the printing of instruction mnemonic
 names and register names in disassembled instructions.  Multiple
index 1ec3708f614e9a9591f3abea12a247e815a73534..f24e821c7c3f6db474558afeda9cfaa5248c19a1 100644 (file)
@@ -1,3 +1,7 @@
+2017-03-29  Alan Modra  <amodra@gmail.com>
+
+       * config/tc-ppc.c (md_parse_option): Reject -mraw.
+
 2017-03-27  Alan Modra  <amodra@gmail.com>
 
        PR 21303
index 05e2c7308336366397321b98651c3bfc616cc454..47cc875690008f342c7b58c0de32943786fef715 100644 (file)
@@ -1193,7 +1193,8 @@ md_parse_option (int c, const char *arg)
 
     case 'm':
       new_cpu = ppc_parse_cpu (ppc_cpu, &sticky, arg);
-      if (new_cpu != 0)
+      /* "raw" is only valid for the disassembler.  */
+      if (new_cpu != 0 && (new_cpu & PPC_OPCODE_RAW) == 0)
        {
          ppc_cpu = new_cpu;
          if (strcmp (arg, "vle") == 0)
index daaad17d733df99ac96f22f6b386b5f9e7ed0a20..76957741ae44775c4dd1b6e948cef0e8e8e865a5 100644 (file)
@@ -1,3 +1,8 @@
+2017-03-29  Alan Modra  <amodra@gmail.com>
+
+       * opcode/ppc.h (PPC_OPCODE_RAW): Define.
+       (PPC_OPCODE_*): Make them all unsigned long long constants.
+
 2017-03-27  Pip Cet  <pipcet@gmail.com>
 
        * elf/wasm32.h: New file to support wasm32 architecture.
index 34cf27ed4241d7f5128d828f31afba4a7466437f..c4de83401250cb2740db034ffb3e73def518afd3 100644 (file)
@@ -74,107 +74,107 @@ extern const int vle_num_opcodes;
 /* Values defined for the flags field of a struct powerpc_opcode.  */
 
 /* Opcode is defined for the PowerPC architecture.  */
-#define PPC_OPCODE_PPC                  1
+#define PPC_OPCODE_PPC                0x1ull
 
 /* Opcode is defined for the POWER (RS/6000) architecture.  */
-#define PPC_OPCODE_POWER                2
+#define PPC_OPCODE_POWER              0x2ull
 
 /* Opcode is defined for the POWER2 (Rios 2) architecture.  */
-#define PPC_OPCODE_POWER2               4
+#define PPC_OPCODE_POWER2             0x4ull
 
 /* Opcode is supported by the Motorola PowerPC 601 processor.  The 601
    is assumed to support all PowerPC (PPC_OPCODE_PPC) instructions,
    but it also supports many additional POWER instructions.  */
-#define PPC_OPCODE_601                  8
+#define PPC_OPCODE_601                0x8ull
 
 /* Opcode is supported in both the Power and PowerPC architectures
    (ie, compiler's -mcpu=common or assembler's -mcom).  More than just
    the intersection of PPC_OPCODE_PPC with the union of PPC_OPCODE_POWER
    and PPC_OPCODE_POWER2 because many instructions changed mnemonics
    between POWER and POWERPC.  */
-#define PPC_OPCODE_COMMON            0x10
+#define PPC_OPCODE_COMMON            0x10ull
 
 /* Opcode is supported for any Power or PowerPC platform (this is
    for the assembler's -many option, and it eliminates duplicates).  */
-#define PPC_OPCODE_ANY               0x20
+#define PPC_OPCODE_ANY               0x20ull
 
 /* Opcode is only defined on 64 bit architectures.  */
-#define PPC_OPCODE_64                0x40
+#define PPC_OPCODE_64                0x40ull
 
 /* Opcode is supported as part of the 64-bit bridge.  */
-#define PPC_OPCODE_64_BRIDGE         0x80
+#define PPC_OPCODE_64_BRIDGE         0x80ull
 
 /* Opcode is supported by Altivec Vector Unit */
-#define PPC_OPCODE_ALTIVEC          0x100
+#define PPC_OPCODE_ALTIVEC          0x100ull
 
 /* Opcode is supported by PowerPC 403 processor.  */
-#define PPC_OPCODE_403              0x200
+#define PPC_OPCODE_403              0x200ull
 
 /* Opcode is supported by PowerPC BookE processor.  */
-#define PPC_OPCODE_BOOKE            0x400
+#define PPC_OPCODE_BOOKE            0x400ull
 
 /* Opcode is supported by PowerPC 440 processor.  */
-#define PPC_OPCODE_440              0x800
+#define PPC_OPCODE_440              0x800ull
 
 /* Opcode is only supported by Power4 architecture.  */
-#define PPC_OPCODE_POWER4          0x1000
+#define PPC_OPCODE_POWER4          0x1000ull
 
 /* Opcode is only supported by Power7 architecture.  */
-#define PPC_OPCODE_POWER7          0x2000
+#define PPC_OPCODE_POWER7          0x2000ull
 
 /* Opcode is only supported by e500x2 Core.  */
-#define PPC_OPCODE_SPE             0x4000
+#define PPC_OPCODE_SPE             0x4000ull
 
 /* Opcode is supported by e500x2 Integer select APU.  */
-#define PPC_OPCODE_ISEL                    0x8000
+#define PPC_OPCODE_ISEL                    0x8000ull
 
 /* Opcode is an e500 SPE floating point instruction.  */
-#define PPC_OPCODE_EFS            0x10000
+#define PPC_OPCODE_EFS            0x10000ull
 
 /* Opcode is supported by branch locking APU.  */
-#define PPC_OPCODE_BRLOCK         0x20000
+#define PPC_OPCODE_BRLOCK         0x20000ull
 
 /* Opcode is supported by performance monitor APU.  */
-#define PPC_OPCODE_PMR            0x40000
+#define PPC_OPCODE_PMR            0x40000ull
 
 /* Opcode is supported by cache locking APU.  */
-#define PPC_OPCODE_CACHELCK       0x80000
+#define PPC_OPCODE_CACHELCK       0x80000ull
 
 /* Opcode is supported by machine check APU.  */
-#define PPC_OPCODE_RFMCI         0x100000
+#define PPC_OPCODE_RFMCI         0x100000ull
 
 /* Opcode is only supported by Power5 architecture.  */
-#define PPC_OPCODE_POWER5        0x200000
+#define PPC_OPCODE_POWER5        0x200000ull
 
 /* Opcode is supported by PowerPC e300 family.  */
-#define PPC_OPCODE_E300           0x400000
+#define PPC_OPCODE_E300           0x400000ull
 
 /* Opcode is only supported by Power6 architecture.  */
-#define PPC_OPCODE_POWER6        0x800000
+#define PPC_OPCODE_POWER6        0x800000ull
 
 /* Opcode is only supported by PowerPC Cell family.  */
-#define PPC_OPCODE_CELL                 0x1000000
+#define PPC_OPCODE_CELL                 0x1000000ull
 
 /* Opcode is supported by CPUs with paired singles support.  */
-#define PPC_OPCODE_PPCPS        0x2000000
+#define PPC_OPCODE_PPCPS        0x2000000ull
 
 /* Opcode is supported by Power E500MC */
-#define PPC_OPCODE_E500MC        0x4000000
+#define PPC_OPCODE_E500MC        0x4000000ull
 
 /* Opcode is supported by PowerPC 405 processor.  */
-#define PPC_OPCODE_405          0x8000000
+#define PPC_OPCODE_405          0x8000000ull
 
 /* Opcode is supported by Vector-Scalar (VSX) Unit */
-#define PPC_OPCODE_VSX         0x10000000
+#define PPC_OPCODE_VSX         0x10000000ull
 
 /* Opcode is supported by A2.  */
-#define PPC_OPCODE_A2          0x20000000
+#define PPC_OPCODE_A2          0x20000000ull
 
 /* Opcode is supported by PowerPC 476 processor.  */
-#define PPC_OPCODE_476         0x40000000
+#define PPC_OPCODE_476         0x40000000ull
 
 /* Opcode is supported by AppliedMicro Titan core */
-#define PPC_OPCODE_TITAN        0x80000000
+#define PPC_OPCODE_TITAN        0x80000000ull
 
 /* Opcode which is supported by the e500 family */
 #define PPC_OPCODE_E500               0x100000000ull
@@ -206,16 +206,22 @@ extern const int vle_num_opcodes;
 #define PPC_OPCODE_7450              0x8000000000ull
 
 /* Opcode is supported by ppc821/850/860.  */
-#define PPC_OPCODE_860       0x10000000000ull
+#define PPC_OPCODE_860      0x10000000000ull
 
 /* Opcode is only supported by Power9 architecture.  */
-#define PPC_OPCODE_POWER9     0x20000000000ull
+#define PPC_OPCODE_POWER9    0x20000000000ull
 
 /* Opcode is supported by Vector-Scalar (VSX) Unit from ISA 2.08.  */
-#define PPC_OPCODE_VSX3       0x40000000000ull
+#define PPC_OPCODE_VSX3      0x40000000000ull
 
-  /* Opcode is supported by e200z4.  */
-#define PPC_OPCODE_E200Z4     0x80000000000ull
+/* Opcode is supported by e200z4.  */
+#define PPC_OPCODE_E200Z4    0x80000000000ull
+
+/* Disassemble to instructions matching later in the opcode table
+   with fewer "mask" bits set rather than the earlist match.  Fewer
+   "mask" bits set imply a more general form of the opcode, in fact
+   the underlying machine instruction.  */
+#define PPC_OPCODE_RAW     0x100000000000ull
 
 /* A macro to extract the major opcode from an instruction.  */
 #define PPC_OP(i) (((i) >> 26) & 0x3f)
index b6a2a5a1f89abbdeb42d9e1d4f74e9f42d98bccc..fe6f27be7c2d71ee8550a8d4c5baa342f46da516 100644 (file)
@@ -1,3 +1,12 @@
+2017-03-29  Alan Modra  <amodra@gmail.com>
+
+       * ppc-dis.c (ppc_opts): Set PPC_OPCODE_PPC for "any" flags.  Add
+       "raw" option.
+       (lookup_powerpc): Don't special case -1 dialect.  Handle
+       PPC_OPCODE_RAW.
+       (print_insn_powerpc): Mask out PPC_OPCODE_ANY on first
+       lookup_powerpc call, pass it on second.
+
 2017-03-27  Alan Modra  <amodra@gmail.com>
 
        PR 21303
index f3db0620956224f751179af35549b421c9443042..ee8016a7842abd5128161d9fae62e8cb5184c10e 100644 (file)
@@ -106,7 +106,7 @@ struct ppc_mopt ppc_opts[] = {
     0 },
   { "altivec", PPC_OPCODE_PPC,
     PPC_OPCODE_ALTIVEC },
-  { "any",     0,
+  { "any",     PPC_OPCODE_PPC,
     PPC_OPCODE_ANY },
   { "booke",   PPC_OPCODE_PPC | PPC_OPCODE_BOOKE,
     0 },
@@ -226,6 +226,8 @@ struct ppc_mopt ppc_opts[] = {
     0 },
   { "pwrx",    PPC_OPCODE_POWER | PPC_OPCODE_POWER2,
     0 },
+  { "raw",     PPC_OPCODE_PPC,
+    PPC_OPCODE_RAW },
   { "spe",     PPC_OPCODE_PPC | PPC_OPCODE_EFS,
     PPC_OPCODE_SPE },
   { "titan",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_PMR
@@ -494,14 +496,12 @@ skip_optional_operands (const unsigned char *opindex,
   return 1;
 }
 
-/* Find a match for INSN in the opcode table, given machine DIALECT.
-   A DIALECT of -1 is special, matching all machine opcode variations.  */
+/* Find a match for INSN in the opcode table, given machine DIALECT.  */
 
 static const struct powerpc_opcode *
 lookup_powerpc (unsigned long insn, ppc_cpu_t dialect)
 {
-  const struct powerpc_opcode *opcode;
-  const struct powerpc_opcode *opcode_end;
+  const struct powerpc_opcode *opcode, *opcode_end, *last;
   unsigned long op;
 
   /* Get the major opcode of the instruction.  */
@@ -509,6 +509,7 @@ lookup_powerpc (unsigned long insn, ppc_cpu_t dialect)
 
   /* Find the first match in the opcode table for this major opcode.  */
   opcode_end = powerpc_opcodes + powerpc_opcd_indices[op + 1];
+  last = NULL;
   for (opcode = powerpc_opcodes + powerpc_opcd_indices[op];
        opcode < opcode_end;
        ++opcode)
@@ -518,7 +519,7 @@ lookup_powerpc (unsigned long insn, ppc_cpu_t dialect)
       int invalid;
 
       if ((insn & opcode->mask) != opcode->opcode
-         || (dialect != (ppc_cpu_t) -1
+         || ((dialect & PPC_OPCODE_ANY) == 0
              && ((opcode->flags & dialect) == 0
                  || (opcode->deprecated & dialect) != 0)))
        continue;
@@ -534,10 +535,16 @@ lookup_powerpc (unsigned long insn, ppc_cpu_t dialect)
       if (invalid)
        continue;
 
-      return opcode;
+      if ((dialect & PPC_OPCODE_RAW) == 0)
+       return opcode;
+
+      /* The raw machine insn is one that is not a specialization.  */
+      if (last == NULL
+         || (last->mask & ~opcode->mask) != 0)
+       last = opcode;
     }
 
-  return NULL;
+  return last;
 }
 
 /* Find a match for INSN in the VLE opcode table.  */
@@ -645,9 +652,9 @@ print_insn_powerpc (bfd_vma memaddr,
        insn_is_short = PPC_OP_SE_VLE(opcode->mask);
     }
   if (opcode == NULL)
-    opcode = lookup_powerpc (insn, dialect);
+    opcode = lookup_powerpc (insn, dialect & ~PPC_OPCODE_ANY);
   if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
-    opcode = lookup_powerpc (insn, (ppc_cpu_t) -1);
+    opcode = lookup_powerpc (insn, dialect);
 
   if (opcode != NULL)
     {