* 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.
This commit is contained in:
Alan Modra 2003-09-04 01:51:37 +00:00
parent f6c4061856
commit 661bd698e4
3 changed files with 88 additions and 59 deletions

View file

@ -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> 2003-09-03 Andrew Cagney <cagney@redhat.com>
* dis-init.c (init_disassemble_info): New file and function. * dis-init.c (init_disassemble_info): New file and function.

View file

@ -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); 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 /* Determine which set of machines to disassemble for. PPC403/601 or
BookE. For convenience, also disassemble instructions supported BookE. For convenience, also disassemble instructions supported
by the AltiVec vector unit. */ by the AltiVec vector unit. */
int static int
powerpc_dialect (struct disassemble_info *info) powerpc_dialect (struct disassemble_info *info)
{ {
int dialect = PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC; int dialect = PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC;
@ -45,15 +50,11 @@ powerpc_dialect (struct disassemble_info *info)
dialect |= PPC_OPCODE_64; dialect |= PPC_OPCODE_64;
if (info->disassembler_options if (info->disassembler_options
&& (strcmp (info->disassembler_options, "booke") == 0 && strstr (info->disassembler_options, "booke") != NULL)
|| strcmp (info->disassembler_options, "booke32") == 0
|| strcmp (info->disassembler_options, "booke64") == 0))
dialect |= PPC_OPCODE_BOOKE | PPC_OPCODE_BOOKE64; dialect |= PPC_OPCODE_BOOKE | PPC_OPCODE_BOOKE64;
else else if ((info->mach == bfd_mach_ppc_e500)
if ((info->mach == bfd_mach_ppc_e500)
|| (info->disassembler_options || (info->disassembler_options
&& ( strcmp (info->disassembler_options, "e500") == 0 && strstr (info->disassembler_options, "e500") != NULL))
|| strcmp (info->disassembler_options, "e500x2") == 0)))
{ {
dialect |= PPC_OPCODE_BOOKE dialect |= PPC_OPCODE_BOOKE
| PPC_OPCODE_SPE | PPC_OPCODE_ISEL | PPC_OPCODE_SPE | PPC_OPCODE_ISEL
@ -63,9 +64,8 @@ powerpc_dialect (struct disassemble_info *info)
/* efs* and AltiVec conflict. */ /* efs* and AltiVec conflict. */
dialect &= ~PPC_OPCODE_ALTIVEC; dialect &= ~PPC_OPCODE_ALTIVEC;
} }
else else if (info->disassembler_options
if (info->disassembler_options && strstr (info->disassembler_options, "efs") != NULL)
&& (strcmp (info->disassembler_options, "efs") == 0))
{ {
dialect |= PPC_OPCODE_EFS; dialect |= PPC_OPCODE_EFS;
/* efs* and AltiVec conflict. */ /* efs* and AltiVec conflict. */
@ -76,9 +76,13 @@ powerpc_dialect (struct disassemble_info *info)
| PPC_OPCODE_COMMON); | PPC_OPCODE_COMMON);
if (info->disassembler_options if (info->disassembler_options
&& strcmp (info->disassembler_options, "power4") == 0) && strstr (info->disassembler_options, "power4") != NULL)
dialect |= PPC_OPCODE_POWER4; dialect |= PPC_OPCODE_POWER4;
if (info->disassembler_options
&& strstr (info->disassembler_options, "any") != NULL)
dialect |= PPC_OPCODE_ANY;
if (info->disassembler_options) if (info->disassembler_options)
{ {
if (strstr (info->disassembler_options, "32") != NULL) if (strstr (info->disassembler_options, "32") != NULL)
@ -87,6 +91,7 @@ powerpc_dialect (struct disassemble_info *info)
dialect |= PPC_OPCODE_64; dialect |= PPC_OPCODE_64;
} }
((struct dis_private *) &info->private_data)->dialect = dialect;
return dialect; return dialect;
} }
@ -95,7 +100,8 @@ powerpc_dialect (struct disassemble_info *info)
int int
print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info) 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. */ /* Print a little endian PowerPC instruction. */
@ -103,7 +109,8 @@ print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info)
int int
print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info) 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. */ /* Print a POWER (RS/6000) instruction. */
@ -129,6 +136,9 @@ print_insn_powerpc (bfd_vma memaddr,
const struct powerpc_opcode *opcode_end; const struct powerpc_opcode *opcode_end;
unsigned long op; unsigned long op;
if (dialect == 0)
dialect = powerpc_dialect (info);
status = (*info->read_memory_func) (memaddr, buffer, 4, info); status = (*info->read_memory_func) (memaddr, buffer, 4, info);
if (status != 0) 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 /* Find the first match in the opcode table. We could speed this up
a bit by doing a binary search on the major opcode. */ a bit by doing a binary search on the major opcode. */
opcode_end = powerpc_opcodes + powerpc_num_opcodes; opcode_end = powerpc_opcodes + powerpc_num_opcodes;
again:
for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++) for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++)
{ {
unsigned long table_op; unsigned long table_op;
@ -166,9 +177,6 @@ print_insn_powerpc (bfd_vma memaddr,
|| (opcode->flags & dialect) == 0) || (opcode->flags & dialect) == 0)
continue; continue;
if ((dialect & PPC_OPCODE_EFS) && (opcode->flags & PPC_OPCODE_ALTIVEC))
continue;
/* Make two passes over the operands. First see if any of them /* Make two passes over the operands. First see if any of them
have extraction functions, and, if they do, make sure the have extraction functions, and, if they do, make sure the
instruction is valid. */ instruction is valid. */
@ -277,6 +285,12 @@ print_insn_powerpc (bfd_vma memaddr,
return 4; return 4;
} }
if ((dialect & PPC_OPCODE_ANY) != 0)
{
dialect = ~PPC_OPCODE_ANY;
goto again;
}
/* We could not find a match. */ /* We could not find a match. */
(*info->fprintf_func) (info->stream, ".long 0x%lx", insn); (*info->fprintf_func) (info->stream, ".long 0x%lx", insn);

View file

@ -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 /* 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) else if ((dialect & PPC_OPCODE_POWER4) != 0 && (value & -value) == value)
insn |= 1 << 20; 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 /* Smaller names for the flags so each entry in the opcodes table will
fit on a single line. */ fit on a single line. */
#undef PPC #undef PPC
#define PPC PPC_OPCODE_PPC | PPC_OPCODE_ANY #define PPC PPC_OPCODE_PPC
#define PPCCOM PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_ANY #define PPCCOM PPC_OPCODE_PPC | PPC_OPCODE_COMMON
#define NOPOWER4 PPC_OPCODE_NOPOWER4 | PPCCOM #define NOPOWER4 PPC_OPCODE_NOPOWER4 | PPCCOM
#define POWER4 PPC_OPCODE_POWER4 | PPCCOM #define POWER4 PPC_OPCODE_POWER4
#define PPC32 PPC_OPCODE_32 | PPC_OPCODE_PPC | PPC_OPCODE_ANY #define PPC32 PPC_OPCODE_32 | PPC_OPCODE_PPC
#define PPC64 PPC_OPCODE_64 | PPC_OPCODE_PPC | PPC_OPCODE_ANY #define PPC64 PPC_OPCODE_64 | PPC_OPCODE_PPC
#define PPCONLY PPC_OPCODE_PPC
#define PPC403 PPC_OPCODE_403 #define PPC403 PPC_OPCODE_403
#define PPC405 PPC403 #define PPC405 PPC403
#define PPC440 PPC_OPCODE_440 #define PPC440 PPC_OPCODE_440
#define PPC750 PPC #define PPC750 PPC
#define PPC860 PPC #define PPC860 PPC
#define PPCVEC PPC_OPCODE_ALTIVEC | PPC_OPCODE_ANY | PPC_OPCODE_PPC #define PPCVEC PPC_OPCODE_ALTIVEC | PPC_OPCODE_PPC
#define POWER PPC_OPCODE_POWER | PPC_OPCODE_ANY #define POWER PPC_OPCODE_POWER
#define POWER2 PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_ANY #define POWER2 PPC_OPCODE_POWER | PPC_OPCODE_POWER2
#define PPCPWR2 PPC_OPCODE_PPC | PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_ANY #define PPCPWR2 PPC_OPCODE_PPC | PPC_OPCODE_POWER | PPC_OPCODE_POWER2
#define POWER32 PPC_OPCODE_POWER | PPC_OPCODE_ANY | PPC_OPCODE_32 #define POWER32 PPC_OPCODE_POWER | PPC_OPCODE_32
#define COM PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_ANY #define COM PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON
#define COM32 PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_ANY | PPC_OPCODE_32 #define COM32 PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_32
#define M601 PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_ANY #define M601 PPC_OPCODE_POWER | PPC_OPCODE_601
#define PWRCOM PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_COMMON | PPC_OPCODE_ANY #define PWRCOM PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_COMMON
#define MFDEC1 PPC_OPCODE_POWER #define MFDEC1 PPC_OPCODE_POWER
#define MFDEC2 PPC_OPCODE_PPC | PPC_OPCODE_601 | PPC_OPCODE_BOOKE #define MFDEC2 PPC_OPCODE_PPC | PPC_OPCODE_601 | PPC_OPCODE_BOOKE
#define BOOKE 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 } }, { "cmplwi", OPL(10,0), OPL_MASK, PPCCOM, { OBF, RA, UI } },
{ "cmpldi", OPL(10,1), OPL_MASK, PPC64, { 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 } }, { "cmpli", OP(10), OP_MASK, PWRCOM, { BF, RA, UI } },
{ "cmpwi", OPL(11,0), OPL_MASK, PPCCOM, { OBF, RA, SI } }, { "cmpwi", OPL(11,0), OPL_MASK, PPCCOM, { OBF, RA, SI } },
{ "cmpdi", OPL(11,1), OPL_MASK, PPC64, { 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 } }, { "cmpi", OP(11), OP_MASK, PWRCOM, { BF, RA, SI } },
{ "addic", OP(12), OP_MASK, PPCCOM, { RT, 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 } }, { "cmpw", XCMPL(31,0,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } },
{ "cmpd", XCMPL(31,0,1), XCMPL_MASK, PPC64, { 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 } }, { "cmp", X(31,0), XCMPL_MASK, PWRCOM, { BF, RA, RB } },
{ "twlgt", XTO(31,4,TOLGT), XTO_MASK, PPCCOM, { 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 } }, { "cmplw", XCMPL(31,32,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } },
{ "cmpld", XCMPL(31,32,1), XCMPL_MASK, PPC64, { 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 } }, { "cmpl", X(31,32), XCMPL_MASK, PWRCOM, { BF, RA, RB } },
{ "subf", XO(31,40,0,0), XO_MASK, PPC, { RT, 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 } }, { "mfsprg5", XSPR(31,339,261), XSPR_MASK, PPC405, { RT } },
{ "mfsprg6", XSPR(31,339,262), XSPR_MASK, PPC405, { RT } }, { "mfsprg6", XSPR(31,339,262), XSPR_MASK, PPC405, { RT } },
{ "mfsprg7", XSPR(31,339,263), 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 } }, { "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 } }, { "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,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 } }, { "mfsprg", XSPR(31,339,272), XSPRG_MASK, PPC, { RT, SPRG } },
{ "mfsprg0", XSPR(31,339,272), XSPR_MASK, PPC, { RT } }, { "mfsprg0", XSPR(31,339,272), XSPR_MASK, PPC, { RT } },
{ "mfsprg1", XSPR(31,339,273), 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 } }, { "lswi", X(31,597), X_MASK, PPCCOM, { RT, RA, NB } },
{ "lsi", X(31,597), X_MASK, PWRCOM, { 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 } }, { "ptesync", XSYNC(31,598,2), 0xffffffff, PPC64, { 0 } },
{ "msync", X(31,598), 0xffffffff, BOOKE, { 0 } }, { "msync", X(31,598), 0xffffffff, BOOKE, { 0 } },
{ "sync", X(31,598), XSYNC_MASK, PPCCOM, { LS } }, { "sync", X(31,598), XSYNC_MASK, PPCCOM, { LS } },