diff options
author | Alan Modra <amodra@gmail.com> | 2017-03-29 13:43:06 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-03-29 22:55:18 +1030 |
commit | 52be03fd13a26ecda4f27c451a434f19eded0ca6 (patch) | |
tree | 236169364ac9f5d4c80e21ddeadeff1bf9ea6084 /opcodes/ppc-dis.c | |
parent | e643cb45bf85fa5c8c49a89ff177de246af4212e (diff) | |
download | gdb-52be03fd13a26ecda4f27c451a434f19eded0ca6.zip gdb-52be03fd13a26ecda4f27c451a434f19eded0ca6.tar.gz gdb-52be03fd13a26ecda4f27c451a434f19eded0ca6.tar.bz2 |
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.
Diffstat (limited to 'opcodes/ppc-dis.c')
-rw-r--r-- | opcodes/ppc-dis.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c index f3db062..ee8016a 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) { |