aboutsummaryrefslogtreecommitdiff
path: root/opcodes/ppc-dis.c
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 /opcodes/ppc-dis.c
parente643cb45bf85fa5c8c49a89ff177de246af4212e (diff)
downloadgdb-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.c27
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)
{