diff options
-rw-r--r-- | opcodes/ChangeLog | 21 | ||||
-rw-r--r-- | opcodes/ppc-dis.c | 78 | ||||
-rw-r--r-- | opcodes/ppc-opc.c | 48 |
3 files changed, 88 insertions, 59 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index bde6e50..2fb406d 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,18 @@ +2003-09-04 Alan Modra <amodra@bigpond.net.au> + + * ppc-dis.c (struct dis_private): New. + (powerpc_dialect): Make static. Accept -Many in addition to existing + options. Save dialect in dis_private. + (print_insn_big_powerpc): Retrieve dialect from dis_private. + (print_insn_little_powerpc): Likewise. + (print_insn_powerpc): Call powpc_dialect here. Remove unnecessary + efs/altivec check. Try harder to disassemble if given -Many. + * ppc-opc.c (insert_fxm): Expand comment. + (PPC, PPCCOM, PPC32, PPC64, PPCVEC): Remove PPC_OPCODE_ANY. + (POWER, POWER2, PPCPWR2, POWER32, COM, COM32, M601, PWRCOM): Likewise. + (POWER4): Remove PPCCOM. + (PPCONLY): Don't define. Update all occurrences to PPC. + 2003-09-03 Andrew Cagney <cagney@redhat.com> * dis-init.c (init_disassemble_info): New file and function. @@ -171,7 +186,7 @@ 2003-07-30 Jason Eckhardt <jle@rice.edu> - * i860-dis.c: Convert to ISO C90. Remove superflous prototypes. + * i860-dis.c: Convert to ISO C90. Remove superflous prototypes. 2003-07-30 Nick Clifton <nickc@redhat.com> @@ -189,8 +204,8 @@ * arm-dis.c (parse_arm_disassembler_option): Do not expect option string to be NUL terminated. - (parse_disassembler_options): Allow options to be space or - comma separated. + (parse_disassembler_options): Allow options to be space or + comma separated. 2003-07-17 Nick Clifton <nickc@redhat.com> diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c index 21efa84..76af4e7 100644 --- a/opcodes/ppc-dis.c +++ b/opcodes/ppc-dis.c @@ -32,11 +32,16 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * static int print_insn_powerpc (bfd_vma, struct disassemble_info *, int, int); +struct dis_private { + /* Stash the result of parsing disassembler_options here. */ + int dialect; +}; + /* Determine which set of machines to disassemble for. PPC403/601 or BookE. For convenience, also disassemble instructions supported by the AltiVec vector unit. */ -int +static int powerpc_dialect (struct disassemble_info *info) { int dialect = PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC; @@ -45,40 +50,39 @@ powerpc_dialect (struct disassemble_info *info) dialect |= PPC_OPCODE_64; if (info->disassembler_options - && (strcmp (info->disassembler_options, "booke") == 0 - || strcmp (info->disassembler_options, "booke32") == 0 - || strcmp (info->disassembler_options, "booke64") == 0)) + && strstr (info->disassembler_options, "booke") != NULL) dialect |= PPC_OPCODE_BOOKE | PPC_OPCODE_BOOKE64; - else - if ((info->mach == bfd_mach_ppc_e500) - || (info->disassembler_options - && ( strcmp (info->disassembler_options, "e500") == 0 - || strcmp (info->disassembler_options, "e500x2") == 0))) - { - dialect |= PPC_OPCODE_BOOKE - | PPC_OPCODE_SPE | PPC_OPCODE_ISEL - | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK - | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK - | PPC_OPCODE_RFMCI; - /* efs* and AltiVec conflict. */ - dialect &= ~PPC_OPCODE_ALTIVEC; - } - else - if (info->disassembler_options - && (strcmp (info->disassembler_options, "efs") == 0)) - { - dialect |= PPC_OPCODE_EFS; - /* efs* and AltiVec conflict. */ - dialect &= ~PPC_OPCODE_ALTIVEC; - } + else if ((info->mach == bfd_mach_ppc_e500) + || (info->disassembler_options + && strstr (info->disassembler_options, "e500") != NULL)) + { + dialect |= PPC_OPCODE_BOOKE + | PPC_OPCODE_SPE | PPC_OPCODE_ISEL + | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK + | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK + | PPC_OPCODE_RFMCI; + /* efs* and AltiVec conflict. */ + dialect &= ~PPC_OPCODE_ALTIVEC; + } + else if (info->disassembler_options + && strstr (info->disassembler_options, "efs") != NULL) + { + dialect |= PPC_OPCODE_EFS; + /* efs* and AltiVec conflict. */ + dialect &= ~PPC_OPCODE_ALTIVEC; + } else dialect |= (PPC_OPCODE_403 | PPC_OPCODE_601 | PPC_OPCODE_CLASSIC | PPC_OPCODE_COMMON); if (info->disassembler_options - && strcmp (info->disassembler_options, "power4") == 0) + && strstr (info->disassembler_options, "power4") != NULL) dialect |= PPC_OPCODE_POWER4; + if (info->disassembler_options + && strstr (info->disassembler_options, "any") != NULL) + dialect |= PPC_OPCODE_ANY; + if (info->disassembler_options) { if (strstr (info->disassembler_options, "32") != NULL) @@ -87,6 +91,7 @@ powerpc_dialect (struct disassemble_info *info) dialect |= PPC_OPCODE_64; } + ((struct dis_private *) &info->private_data)->dialect = dialect; return dialect; } @@ -95,7 +100,8 @@ powerpc_dialect (struct disassemble_info *info) int print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info) { - return print_insn_powerpc (memaddr, info, 1, powerpc_dialect(info)); + int dialect = ((struct dis_private *) &info->private_data)->dialect; + return print_insn_powerpc (memaddr, info, 1, dialect); } /* Print a little endian PowerPC instruction. */ @@ -103,7 +109,8 @@ print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info) int print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info) { - return print_insn_powerpc (memaddr, info, 0, powerpc_dialect(info)); + int dialect = ((struct dis_private *) &info->private_data)->dialect; + return print_insn_powerpc (memaddr, info, 0, dialect); } /* Print a POWER (RS/6000) instruction. */ @@ -129,6 +136,9 @@ print_insn_powerpc (bfd_vma memaddr, const struct powerpc_opcode *opcode_end; unsigned long op; + if (dialect == 0) + dialect = powerpc_dialect (info); + status = (*info->read_memory_func) (memaddr, buffer, 4, info); if (status != 0) { @@ -147,6 +157,7 @@ print_insn_powerpc (bfd_vma memaddr, /* Find the first match in the opcode table. We could speed this up a bit by doing a binary search on the major opcode. */ opcode_end = powerpc_opcodes + powerpc_num_opcodes; + again: for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++) { unsigned long table_op; @@ -166,9 +177,6 @@ print_insn_powerpc (bfd_vma memaddr, || (opcode->flags & dialect) == 0) continue; - if ((dialect & PPC_OPCODE_EFS) && (opcode->flags & PPC_OPCODE_ALTIVEC)) - continue; - /* Make two passes over the operands. First see if any of them have extraction functions, and, if they do, make sure the instruction is valid. */ @@ -277,6 +285,12 @@ print_insn_powerpc (bfd_vma memaddr, return 4; } + if ((dialect & PPC_OPCODE_ANY) != 0) + { + dialect = ~PPC_OPCODE_ANY; + goto again; + } + /* We could not find a match. */ (*info->fprintf_func) (info->stream, ".long 0x%lx", insn); diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c index 061d389..c37943b 100644 --- a/opcodes/ppc-opc.c +++ b/opcodes/ppc-opc.c @@ -1001,7 +1001,8 @@ insert_fxm (unsigned long insn, ; /* If only one bit of the FXM field is set, we can use the new form - of the instruction, which is faster. */ + of the instruction, which is faster. Unlike the Power4 branch hint + encoding, this is not backward compatible. */ else if ((dialect & PPC_OPCODE_POWER4) != 0 && (value & -value) == value) insn |= 1 << 20; @@ -1762,27 +1763,26 @@ extract_tbr (unsigned long insn, /* Smaller names for the flags so each entry in the opcodes table will fit on a single line. */ #undef PPC -#define PPC PPC_OPCODE_PPC | PPC_OPCODE_ANY -#define PPCCOM PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_ANY +#define PPC PPC_OPCODE_PPC +#define PPCCOM PPC_OPCODE_PPC | PPC_OPCODE_COMMON #define NOPOWER4 PPC_OPCODE_NOPOWER4 | PPCCOM -#define POWER4 PPC_OPCODE_POWER4 | PPCCOM -#define PPC32 PPC_OPCODE_32 | PPC_OPCODE_PPC | PPC_OPCODE_ANY -#define PPC64 PPC_OPCODE_64 | PPC_OPCODE_PPC | PPC_OPCODE_ANY -#define PPCONLY PPC_OPCODE_PPC +#define POWER4 PPC_OPCODE_POWER4 +#define PPC32 PPC_OPCODE_32 | PPC_OPCODE_PPC +#define PPC64 PPC_OPCODE_64 | PPC_OPCODE_PPC #define PPC403 PPC_OPCODE_403 #define PPC405 PPC403 #define PPC440 PPC_OPCODE_440 #define PPC750 PPC #define PPC860 PPC -#define PPCVEC PPC_OPCODE_ALTIVEC | PPC_OPCODE_ANY | PPC_OPCODE_PPC -#define POWER PPC_OPCODE_POWER | PPC_OPCODE_ANY -#define POWER2 PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_ANY -#define PPCPWR2 PPC_OPCODE_PPC | PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_ANY -#define POWER32 PPC_OPCODE_POWER | PPC_OPCODE_ANY | PPC_OPCODE_32 -#define COM PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_ANY -#define COM32 PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_ANY | PPC_OPCODE_32 -#define M601 PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_ANY -#define PWRCOM PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_COMMON | PPC_OPCODE_ANY +#define PPCVEC PPC_OPCODE_ALTIVEC | PPC_OPCODE_PPC +#define POWER PPC_OPCODE_POWER +#define POWER2 PPC_OPCODE_POWER | PPC_OPCODE_POWER2 +#define PPCPWR2 PPC_OPCODE_PPC | PPC_OPCODE_POWER | PPC_OPCODE_POWER2 +#define POWER32 PPC_OPCODE_POWER | PPC_OPCODE_32 +#define COM PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON +#define COM32 PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_32 +#define M601 PPC_OPCODE_POWER | PPC_OPCODE_601 +#define PWRCOM PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_COMMON #define MFDEC1 PPC_OPCODE_POWER #define MFDEC2 PPC_OPCODE_PPC | PPC_OPCODE_601 | PPC_OPCODE_BOOKE #define BOOKE PPC_OPCODE_BOOKE @@ -2369,12 +2369,12 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "cmplwi", OPL(10,0), OPL_MASK, PPCCOM, { OBF, RA, UI } }, { "cmpldi", OPL(10,1), OPL_MASK, PPC64, { OBF, RA, UI } }, -{ "cmpli", OP(10), OP_MASK, PPCONLY, { BF, L, RA, UI } }, +{ "cmpli", OP(10), OP_MASK, PPC, { BF, L, RA, UI } }, { "cmpli", OP(10), OP_MASK, PWRCOM, { BF, RA, UI } }, { "cmpwi", OPL(11,0), OPL_MASK, PPCCOM, { OBF, RA, SI } }, { "cmpdi", OPL(11,1), OPL_MASK, PPC64, { OBF, RA, SI } }, -{ "cmpi", OP(11), OP_MASK, PPCONLY, { BF, L, RA, SI } }, +{ "cmpi", OP(11), OP_MASK, PPC, { BF, L, RA, SI } }, { "cmpi", OP(11), OP_MASK, PWRCOM, { BF, RA, SI } }, { "addic", OP(12), OP_MASK, PPCCOM, { RT, RA, SI } }, @@ -3158,7 +3158,7 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "cmpw", XCMPL(31,0,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } }, { "cmpd", XCMPL(31,0,1), XCMPL_MASK, PPC64, { OBF, RA, RB } }, -{ "cmp", X(31,0), XCMP_MASK, PPCONLY, { BF, L, RA, RB } }, +{ "cmp", X(31,0), XCMP_MASK, PPC, { BF, L, RA, RB } }, { "cmp", X(31,0), XCMPL_MASK, PWRCOM, { BF, RA, RB } }, { "twlgt", XTO(31,4,TOLGT), XTO_MASK, PPCCOM, { RA, RB } }, @@ -3264,7 +3264,7 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "cmplw", XCMPL(31,32,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } }, { "cmpld", XCMPL(31,32,1), XCMPL_MASK, PPC64, { OBF, RA, RB } }, -{ "cmpl", X(31,32), XCMP_MASK, PPCONLY, { BF, L, RA, RB } }, +{ "cmpl", X(31,32), XCMP_MASK, PPC, { BF, L, RA, RB } }, { "cmpl", X(31,32), XCMPL_MASK, PWRCOM, { BF, RA, RB } }, { "subf", XO(31,40,0,0), XO_MASK, PPC, { RT, RA, RB } }, @@ -3636,12 +3636,12 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mfsprg5", XSPR(31,339,261), XSPR_MASK, PPC405, { RT } }, { "mfsprg6", XSPR(31,339,262), XSPR_MASK, PPC405, { RT } }, { "mfsprg7", XSPR(31,339,263), XSPR_MASK, PPC405, { RT } }, -{ "mftb", XSPR(31,339,268), XSPR_MASK, BOOKE, { RT } }, { "mftb", X(31,371), X_MASK, CLASSIC, { RT, TBR } }, -{ "mftbl", XSPR(31,339,268), XSPR_MASK, BOOKE, { RT } }, +{ "mftb", XSPR(31,339,268), XSPR_MASK, BOOKE, { RT } }, { "mftbl", XSPR(31,371,268), XSPR_MASK, CLASSIC, { RT } }, -{ "mftbu", XSPR(31,339,269), XSPR_MASK, BOOKE, { RT } }, +{ "mftbl", XSPR(31,339,268), XSPR_MASK, BOOKE, { RT } }, { "mftbu", XSPR(31,371,269), XSPR_MASK, CLASSIC, { RT } }, +{ "mftbu", XSPR(31,339,269), XSPR_MASK, BOOKE, { RT } }, { "mfsprg", XSPR(31,339,272), XSPRG_MASK, PPC, { RT, SPRG } }, { "mfsprg0", XSPR(31,339,272), XSPR_MASK, PPC, { RT } }, { "mfsprg1", XSPR(31,339,273), XSPR_MASK, PPC, { RT } }, @@ -4137,7 +4137,7 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "lswi", X(31,597), X_MASK, PPCCOM, { RT, RA, NB } }, { "lsi", X(31,597), X_MASK, PWRCOM, { RT, RA, NB } }, -{ "lwsync", XSYNC(31,598,1), 0xffffffff, PPCONLY, { 0 } }, +{ "lwsync", XSYNC(31,598,1), 0xffffffff, PPC, { 0 } }, { "ptesync", XSYNC(31,598,2), 0xffffffff, PPC64, { 0 } }, { "msync", X(31,598), 0xffffffff, BOOKE, { 0 } }, { "sync", X(31,598), XSYNC_MASK, PPCCOM, { LS } }, |