forked from Imagelibrary/binutils-gdb
* 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:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user