aboutsummaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/ChangeLog8
-rw-r--r--opcodes/ppc-dis.c92
2 files changed, 76 insertions, 24 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index ed74935..8a4634d 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,11 @@
+2012-11-23 Alan Modra <amodra@gmail.com>
+
+ * ppc-dis.c (ppc_parse_cpu): Add "sticky" param. Track bits
+ set from ppc_opts.sticky in it. Delete "retain_mask".
+ (powerpc_init_dialect): Choose default dialect from info->mach
+ before parsing -M options. Handle more bfd_mach_ppc variants.
+ Update common default to power7.
+
2012-11-21 David Holsgrove <david.holsgrove@xilinx.com>
* microblaze-opc.h (op_code_struct): Add swapb, swaph Increase MAX_OPCODES.
diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c
index 03b3160..41dce27 100644
--- a/opcodes/ppc-dis.c
+++ b/opcodes/ppc-dis.c
@@ -211,13 +211,8 @@ get_powerpc_dialect (struct disassemble_info *info)
/* Handle -m and -M options that set cpu type, and .machine arg. */
ppc_cpu_t
-ppc_parse_cpu (ppc_cpu_t ppc_cpu, const char *arg)
+ppc_parse_cpu (ppc_cpu_t ppc_cpu, ppc_cpu_t *sticky, const char *arg)
{
- const ppc_cpu_t retain_mask = (PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX
- | PPC_OPCODE_SPE | PPC_OPCODE_ANY
- | PPC_OPCODE_VLE | PPC_OPCODE_PMR);
- /* Sticky bits. */
- ppc_cpu_t retain_flags = ppc_cpu & retain_mask;
unsigned int i;
for (i = 0; i < sizeof (ppc_opts) / sizeof (ppc_opts[0]); i++)
@@ -225,8 +220,8 @@ ppc_parse_cpu (ppc_cpu_t ppc_cpu, const char *arg)
{
if (ppc_opts[i].sticky)
{
- retain_flags |= ppc_opts[i].sticky;
- if ((ppc_cpu & ~retain_mask) != 0)
+ *sticky |= ppc_opts[i].sticky;
+ if ((ppc_cpu & ~*sticky) != 0)
break;
}
ppc_cpu = ppc_opts[i].cpu;
@@ -235,7 +230,7 @@ ppc_parse_cpu (ppc_cpu_t ppc_cpu, const char *arg)
if (i >= sizeof (ppc_opts) / sizeof (ppc_opts[0]))
return 0;
- ppc_cpu |= retain_flags;
+ ppc_cpu |= *sticky;
return ppc_cpu;
}
@@ -245,12 +240,75 @@ static void
powerpc_init_dialect (struct disassemble_info *info)
{
ppc_cpu_t dialect = 0;
+ ppc_cpu_t sticky = 0;
char *arg;
struct dis_private *priv = calloc (sizeof (*priv), 1);
if (priv == NULL)
priv = &private;
+ switch (info->mach)
+ {
+ case bfd_mach_ppc_403:
+ case bfd_mach_ppc_403gc:
+ dialect = (PPC_OPCODE_PPC | PPC_OPCODE_403);
+ break;
+ case bfd_mach_ppc_405:
+ dialect = (PPC_OPCODE_PPC | PPC_OPCODE_403 | PPC_OPCODE_405);
+ break;
+ case bfd_mach_ppc_601:
+ dialect = (PPC_OPCODE_PPC | PPC_OPCODE_601);
+ break;
+ case bfd_mach_ppc_a35:
+ case bfd_mach_ppc_rs64ii:
+ case bfd_mach_ppc_rs64iii:
+ dialect = (PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_64);
+ break;
+ case bfd_mach_ppc_e500:
+ dialect = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
+ | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
+ | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+ | PPC_OPCODE_E500);
+ break;
+ case bfd_mach_ppc_e500mc:
+ dialect = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
+ | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+ | PPC_OPCODE_E500MC);
+ break;
+ case bfd_mach_ppc_e500mc64:
+ dialect = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
+ | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+ | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER5
+ | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7);
+ break;
+ case bfd_mach_ppc_e5500:
+ dialect = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
+ | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+ | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
+ | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
+ | PPC_OPCODE_POWER7);
+ break;
+ case bfd_mach_ppc_e6500:
+ dialect = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
+ | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+ | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_ALTIVEC
+ | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_E6500 | PPC_OPCODE_POWER4
+ | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7);
+ break;
+ case bfd_mach_ppc_titan:
+ dialect = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_PMR
+ | PPC_OPCODE_RFMCI | PPC_OPCODE_TITAN);
+ break;
+ case bfd_mach_ppc_vle:
+ dialect = (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_VLE);
+ break;
+ default:
+ dialect = (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
+ | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
+ | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX
+ | PPC_OPCODE_ANY);
+ }
+
arg = info->disassembler_options;
while (arg != NULL)
{
@@ -260,7 +318,7 @@ powerpc_init_dialect (struct disassemble_info *info)
if (end != NULL)
*end = 0;
- if ((new_cpu = ppc_parse_cpu (dialect, arg)) != 0)
+ if ((new_cpu = ppc_parse_cpu (dialect, &sticky, arg)) != 0)
dialect = new_cpu;
else if (strcmp (arg, "32") == 0)
dialect &= ~(ppc_cpu_t) PPC_OPCODE_64;
@@ -274,20 +332,6 @@ powerpc_init_dialect (struct disassemble_info *info)
arg = end;
}
- if ((dialect & ~(ppc_cpu_t) PPC_OPCODE_64) == 0)
- {
- if (info->mach == bfd_mach_ppc64)
- dialect |= PPC_OPCODE_64;
- else
- dialect &= ~(ppc_cpu_t) PPC_OPCODE_64;
- if (info->mach == bfd_mach_ppc_vle)
- dialect |= PPC_OPCODE_PPC | PPC_OPCODE_VLE;
- else
- /* Choose a reasonable default. */
- dialect |= (PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_601
- | PPC_OPCODE_ALTIVEC);
- }
-
info->private_data = priv;
POWERPC_DIALECT(info) = dialect;
}