summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-03-29 13:43:06 +1030
committerAlan Modra <amodra@gmail.com>2017-03-29 22:55:18 +1030
commit52be03fd13a26ecda4f27c451a434f19eded0ca6 (patch)
tree236169364ac9f5d4c80e21ddeadeff1bf9ea6084
parente643cb45bf85fa5c8c49a89ff177de246af4212e (diff)
PowerPC -Mraw disassembly
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.
-rw-r--r--binutils/ChangeLog4
-rw-r--r--binutils/doc/binutils.texi34
-rw-r--r--gas/ChangeLog4
-rw-r--r--gas/config/tc-ppc.c3
-rw-r--r--include/ChangeLog5
-rw-r--r--include/opcode/ppc.h80
-rw-r--r--opcodes/ChangeLog9
-rw-r--r--opcodes/ppc-dis.c27
8 files changed, 112 insertions, 54 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 5ee8073f05..95595876be 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -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.
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index ffa7dfd909..da4ed52dc4 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -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
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 1ec3708f61..f24e821c7c 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 05e2c73083..47cc875690 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -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)
diff --git a/include/ChangeLog b/include/ChangeLog
index daaad17d73..76957741ae 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -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.
diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h
index 34cf27ed42..c4de834012 100644
--- a/include/opcode/ppc.h
+++ b/include/opcode/ppc.h
@@ -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)
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index b6a2a5a1f8..fe6f27be7c 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -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
diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c
index f3db062095..ee8016a784 100644
--- a/opcodes/ppc-dis.c
+++ b/opcodes/ppc-dis.c
@@ -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)
{