aboutsummaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/ChangeLog21
-rw-r--r--opcodes/ppc-dis.c78
-rw-r--r--opcodes/ppc-opc.c48
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 } },