diff options
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/ChangeLog | 9 | ||||
-rw-r--r-- | opcodes/ppc-dis.c | 27 |
2 files changed, 26 insertions, 10 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index b6a2a5a..fe6f27b 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 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) { |