/* ppc-dis.c -- Disassemble PowerPC instructions
- Copyright 1994, 1995, 2000 Free Software Foundation, Inc.
+ Copyright 1994, 1995, 2000, 2001, 2002 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support
This file is part of GDB, GAS, and the GNU binutils.
static int powerpc_dialect PARAMS ((struct disassemble_info *));
/* Determine which set of machines to disassemble for. PPC403/601 or
- Motorola BookE. For convenience, also disassemble instructions
- supported by the AltiVec vector unit. */
+ BookE. For convenience, also disassemble instructions supported
+ by the AltiVec vector unit. */
int
powerpc_dialect(info)
{
int dialect = PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC;
- if (info->disassembler_options &&
- (strcmp(info->disassembler_options, "booke") == 0 ||
- strcmp(info->disassembler_options, "booke32") == 0 ||
- strcmp(info->disassembler_options, "booke64") == 0))
+ if (BFD_DEFAULT_TARGET_SIZE == 64)
+ 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))
dialect |= PPC_OPCODE_BOOKE | PPC_OPCODE_BOOKE64;
- else
- dialect |= PPC_OPCODE_403 | PPC_OPCODE_601;
+ 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
+ dialect |= (PPC_OPCODE_403 | PPC_OPCODE_601 | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_COMMON);
+
+ if (info->disassembler_options
+ && strcmp (info->disassembler_options, "power4") == 0)
+ dialect |= PPC_OPCODE_POWER4;
+
+ if (info->disassembler_options)
+ {
+ if (strstr (info->disassembler_options, "32") != NULL)
+ dialect &= ~PPC_OPCODE_64;
+ else if (strstr (info->disassembler_options, "64") != NULL)
+ dialect |= PPC_OPCODE_64;
+ }
+
return dialect;
}
|| (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. */
{
operand = powerpc_operands + *opindex;
if (operand->extract)
- (*operand->extract) (insn, &invalid);
+ (*operand->extract) (insn, dialect, &invalid);
}
if (invalid)
continue;
/* Extract the value from the instruction. */
if (operand->extract)
- value = (*operand->extract) (insn, (int *) NULL);
+ value = (*operand->extract) (insn, dialect, (int *) NULL);
else
{
value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
cr = value >> 2;
if (cr != 0)
- (*info->fprintf_func) (info->stream, "4*cr%d", cr);
+ (*info->fprintf_func) (info->stream, "4*cr%d+", cr);
cc = value & 3;
- if (cc != 0)
- {
- if (cr != 0)
- (*info->fprintf_func) (info->stream, "+");
- (*info->fprintf_func) (info->stream, "%s", cbnames[cc]);
- }
+ (*info->fprintf_func) (info->stream, "%s", cbnames[cc]);
}
}
return 4;
}
+
+void
+print_ppc_disassembler_options (FILE * stream)
+{
+ fprintf (stream, "\n\
+The following PPC specific disassembler options are supported for use with\n\
+the -M switch:\n");
+
+ fprintf (stream, " booke|booke32|booke64 Disassemble the BookE instructions\n");
+ fprintf (stream, " e500|e500x2 Disassemble the e500 instructions\n");
+ fprintf (stream, " efs Disassemble the EFS instructions\n");
+ fprintf (stream, " power4 Disassemble the Power4 instructions\n");
+ fprintf (stream, " 32 Do not disassemble 64-bit instructions\n");
+ fprintf (stream, " 64 Allow disassembly of 64-bit instructions\n");
+}