binutils-gdb/opcodes/ppc-dis.c

534 lines
16 KiB
C
Raw Normal View History

1999-05-03 09:29:11 +02:00
/* ppc-dis.c -- Disassemble PowerPC instructions
Copyright 1994, 1995, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
2008, 2009 Free Software Foundation, Inc.
1999-05-03 09:29:11 +02:00
Written by Ian Lance Taylor, Cygnus Support
2007-07-05 11:49:03 +02:00
This file is part of the GNU opcodes library.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this file; see the file COPYING. If not, write to the
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
1999-05-03 09:29:11 +02:00
#include <stdio.h>
#include "sysdep.h"
#include "dis-asm.h"
#include "opintl.h"
1999-05-03 09:29:11 +02:00
#include "opcode/ppc.h"
/* This file provides several disassembler functions, all of which use
the disassembler interface defined in dis-asm.h. Several functions
are provided because this file handles disassembly for the PowerPC
in both big and little endian mode and also for the POWER (RS/6000)
chip. */
2008-06-13 22:16:00 +02:00
static int print_insn_powerpc (bfd_vma, struct disassemble_info *, int,
ppc_cpu_t);
1999-05-03 09:29:11 +02:00
2008-06-13 22:16:00 +02:00
struct dis_private
{
/* Stash the result of parsing disassembler_options here. */
ppc_cpu_t dialect;
};
#define POWERPC_DIALECT(INFO) \
(((struct dis_private *) ((INFO)->private_data))->dialect)
[gas/ChangeLog] * config/tc-ppc.c (md_parse_option): New -m7410, -m7450 and -m7455 flags, equivalent to -m7400. New -maltivec to enable AltiVec instructions. New -mbook64 and -mbooke/-mbooke32 flags to enable 64-bit and 32-bit BookE support, respectively. Change -m403 and -m405 to set PPC403 option. (md_show_usage): Adjust for new options. * doc/all.texi: Set PPC. * doc/as.texinfo: Add PPC support and pull in c-ppc.texi. * doc/c-ppc.texi: New file. * doc/Makefile.am (CPU_DOCS): Add c-ppc.texi. * doc/Makefile.in: Regenerate. [gas/testsuite/ChangeLog] * gas/ppc/booke.s: New test for Motorola BookE. * gas/ppc/booke.d: New file. * gas/ppc/ppc.exp: Test booke.s. [include/opcode/ChangeLog] * ppc.h (PPC_OPCODE_BOOKE, PPC_OPCODE_403): New opcode flags for BookE and PowerPC403 instructions. [opcodes/ChangeLog] * ppc-opc.c (insert_de, extract_de, insert_des, extract_des): New instruction field instruction/extraction functions for new BookE DE form instructions. (CT): New macro for CT field in an X form instruction. (DE, DES, DEO, DE_MASK): New macros for DE/DES fields in DE form instructions. (PPC64): Don't include PPC_OPCODE_PPC. (403): New opcode macro for PPC403 processors. (BOOKE): New opcode macro for BookE processors. (bce, bcel, bcea, bcela, bclre, bclrel: New BookE instructions. (bcctre, bcctrel, be, bel, bea, bela, icbt, icbte, lwzxe): Likewise. (dcbste, lwzuxe, luxe, dcbfe, lbzxe, lwarxe, lbzuxe): Likewise. (stwcxe, stwxe, stxe, stwuxe, stuxe, stbxe, dcbtste, stbuxe): Likewise. (mfapidi, dcbte, lhzxe, lhzuxe, lhaxe, lhauxe, subfe64): Likewise. (subfeo64, adde64, addeo64, sthxe, sthuxe, subfze64): Likewise. (subfzeo64, addze64, addzeo64, dcbie, subfme64, subfmeo64): Likewise. (addme64, addmeo64, stdcxe., mcrxr64, lwbrxe, lfsxe, lfsuxe): Likewise. (lfdxe, lfduxe, stwbrxe, stfsxe, stfsuxe, stfdxe, dcbae): Likewise. (stfduxe, tlbivax, tlbivaxe, lhbrxe, ldxe, lduxe, tlbsx): Likewise. (tlbsxe, sthbrxe, stdxe, stduxe, icbie, stfiwxe, dcbze, lbze): Likewise. (lbzue, ldue, lhze, lhzue, lhae, lhaue, lwze, lwzue): Likewise. (stbe, stbue, sthe, sthue, stwe, stwue, lfse, lfsue, lfde): Likewise. (lfdue, stde, stdue, stfse, stfsue, stfde, stfdue): Likewise. * ppc-dis.c (print_insn_big_powerpc, print_insn_little_powerpc): Look for a disassembler option of `booke', `booke32' or `booke64' to enable BookE support in the disassembler.
2001-10-13 03:59:09 +02:00
struct ppc_mopt {
const char *opt;
ppc_cpu_t cpu;
ppc_cpu_t sticky;
};
struct ppc_mopt ppc_opts[] = {
{ "403", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_403
| PPC_OPCODE_32),
0 },
{ "405", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_403
| PPC_OPCODE_405 | PPC_OPCODE_32),
0 },
{ "440", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32
| PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
0 },
{ "464", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32
| PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
0 },
{ "476", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ISEL
| PPC_OPCODE_440 | PPC_OPCODE_476 | PPC_OPCODE_POWER4
| PPC_OPCODE_POWER5),
0 },
{ "601", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_601
| PPC_OPCODE_32),
0 },
{ "603", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32),
0 },
{ "604", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32),
0 },
{ "620", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64),
0 },
{ "7400", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC
| PPC_OPCODE_32),
0 },
{ "7410", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC
| PPC_OPCODE_32),
0 },
{ "7450", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC
| PPC_OPCODE_32),
0 },
{ "7455", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC
| PPC_OPCODE_32),
0 },
{ "750cl", (PPC_OPCODE_PPC | PPC_OPCODE_PPCPS)
, 0 },
{ "altivec", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC),
PPC_OPCODE_ALTIVEC },
{ "any", 0,
PPC_OPCODE_ANY },
{ "booke", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32),
0 },
{ "booke32", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32),
0 },
{ "cell", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64
| PPC_OPCODE_POWER4 | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC),
0 },
{ "com", (PPC_OPCODE_COMMON | PPC_OPCODE_32),
0 },
{ "e300", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32
| PPC_OPCODE_E300),
0 },
{ "e500", (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_E500MC),
0 },
{ "e500mc", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
| PPC_OPCODE_E500MC),
0 },
{ "e500x2", (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_E500MC),
0 },
{ "efs", (PPC_OPCODE_PPC | PPC_OPCODE_EFS),
0 },
{ "power4", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64
| PPC_OPCODE_POWER4),
0 },
{ "power5", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64
| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5),
0 },
{ "power6", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64
| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
| PPC_OPCODE_ALTIVEC),
0 },
{ "power7", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ISEL
| PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5
| PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC
| PPC_OPCODE_VSX),
0 },
{ "ppc", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32),
0 },
{ "ppc32", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32),
0 },
{ "ppc64", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64),
0 },
{ "ppc64bridge", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64_BRIDGE
| PPC_OPCODE_64),
0 },
{ "a2", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ISEL
| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_CACHELCK
| PPC_OPCODE_64 | PPC_OPCODE_A2),
0 },
{ "ppcps", (PPC_OPCODE_PPC | PPC_OPCODE_PPCPS),
0 },
{ "pwr", (PPC_OPCODE_POWER | PPC_OPCODE_32),
0 },
{ "pwr2", (PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_32),
0 },
{ "pwrx", (PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_32),
0 },
{ "spe", (PPC_OPCODE_PPC | PPC_OPCODE_EFS),
PPC_OPCODE_SPE },
{ "vsx", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC),
PPC_OPCODE_VSX },
};
/* 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)
{
/* Sticky bits. */
ppc_cpu_t retain_flags = ppc_cpu & (PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX
| PPC_OPCODE_SPE | PPC_OPCODE_ANY);
unsigned int i;
for (i = 0; i < sizeof (ppc_opts) / sizeof (ppc_opts[0]); i++)
if (strcmp (ppc_opts[i].opt, arg) == 0)
{
if (ppc_opts[i].sticky)
{
retain_flags |= ppc_opts[i].sticky;
if ((ppc_cpu & ~(PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX
| PPC_OPCODE_SPE | PPC_OPCODE_ANY)) != 0)
break;
}
ppc_cpu = ppc_opts[i].cpu;
break;
}
if (i >= sizeof (ppc_opts) / sizeof (ppc_opts[0]))
return 0;
ppc_cpu |= retain_flags;
return ppc_cpu;
}
/* Determine which set of machines to disassemble for. */
[gas/ChangeLog] * config/tc-ppc.c (md_parse_option): New -m7410, -m7450 and -m7455 flags, equivalent to -m7400. New -maltivec to enable AltiVec instructions. New -mbook64 and -mbooke/-mbooke32 flags to enable 64-bit and 32-bit BookE support, respectively. Change -m403 and -m405 to set PPC403 option. (md_show_usage): Adjust for new options. * doc/all.texi: Set PPC. * doc/as.texinfo: Add PPC support and pull in c-ppc.texi. * doc/c-ppc.texi: New file. * doc/Makefile.am (CPU_DOCS): Add c-ppc.texi. * doc/Makefile.in: Regenerate. [gas/testsuite/ChangeLog] * gas/ppc/booke.s: New test for Motorola BookE. * gas/ppc/booke.d: New file. * gas/ppc/ppc.exp: Test booke.s. [include/opcode/ChangeLog] * ppc.h (PPC_OPCODE_BOOKE, PPC_OPCODE_403): New opcode flags for BookE and PowerPC403 instructions. [opcodes/ChangeLog] * ppc-opc.c (insert_de, extract_de, insert_des, extract_des): New instruction field instruction/extraction functions for new BookE DE form instructions. (CT): New macro for CT field in an X form instruction. (DE, DES, DEO, DE_MASK): New macros for DE/DES fields in DE form instructions. (PPC64): Don't include PPC_OPCODE_PPC. (403): New opcode macro for PPC403 processors. (BOOKE): New opcode macro for BookE processors. (bce, bcel, bcea, bcela, bclre, bclrel: New BookE instructions. (bcctre, bcctrel, be, bel, bea, bela, icbt, icbte, lwzxe): Likewise. (dcbste, lwzuxe, luxe, dcbfe, lbzxe, lwarxe, lbzuxe): Likewise. (stwcxe, stwxe, stxe, stwuxe, stuxe, stbxe, dcbtste, stbuxe): Likewise. (mfapidi, dcbte, lhzxe, lhzuxe, lhaxe, lhauxe, subfe64): Likewise. (subfeo64, adde64, addeo64, sthxe, sthuxe, subfze64): Likewise. (subfzeo64, addze64, addzeo64, dcbie, subfme64, subfmeo64): Likewise. (addme64, addmeo64, stdcxe., mcrxr64, lwbrxe, lfsxe, lfsuxe): Likewise. (lfdxe, lfduxe, stwbrxe, stfsxe, stfsuxe, stfdxe, dcbae): Likewise. (stfduxe, tlbivax, tlbivaxe, lhbrxe, ldxe, lduxe, tlbsx): Likewise. (tlbsxe, sthbrxe, stdxe, stduxe, icbie, stfiwxe, dcbze, lbze): Likewise. (lbzue, ldue, lhze, lhzue, lhae, lhaue, lwze, lwzue): Likewise. (stbe, stbue, sthe, sthue, stwe, stwue, lfse, lfsue, lfde): Likewise. (lfdue, stde, stdue, stfse, stfsue, stfde, stfdue): Likewise. * ppc-dis.c (print_insn_big_powerpc, print_insn_little_powerpc): Look for a disassembler option of `booke', `booke32' or `booke64' to enable BookE support in the disassembler.
2001-10-13 03:59:09 +02:00
static int
2008-06-13 22:16:00 +02:00
powerpc_init_dialect (struct disassemble_info *info)
[gas/ChangeLog] * config/tc-ppc.c (md_parse_option): New -m7410, -m7450 and -m7455 flags, equivalent to -m7400. New -maltivec to enable AltiVec instructions. New -mbook64 and -mbooke/-mbooke32 flags to enable 64-bit and 32-bit BookE support, respectively. Change -m403 and -m405 to set PPC403 option. (md_show_usage): Adjust for new options. * doc/all.texi: Set PPC. * doc/as.texinfo: Add PPC support and pull in c-ppc.texi. * doc/c-ppc.texi: New file. * doc/Makefile.am (CPU_DOCS): Add c-ppc.texi. * doc/Makefile.in: Regenerate. [gas/testsuite/ChangeLog] * gas/ppc/booke.s: New test for Motorola BookE. * gas/ppc/booke.d: New file. * gas/ppc/ppc.exp: Test booke.s. [include/opcode/ChangeLog] * ppc.h (PPC_OPCODE_BOOKE, PPC_OPCODE_403): New opcode flags for BookE and PowerPC403 instructions. [opcodes/ChangeLog] * ppc-opc.c (insert_de, extract_de, insert_des, extract_des): New instruction field instruction/extraction functions for new BookE DE form instructions. (CT): New macro for CT field in an X form instruction. (DE, DES, DEO, DE_MASK): New macros for DE/DES fields in DE form instructions. (PPC64): Don't include PPC_OPCODE_PPC. (403): New opcode macro for PPC403 processors. (BOOKE): New opcode macro for BookE processors. (bce, bcel, bcea, bcela, bclre, bclrel: New BookE instructions. (bcctre, bcctrel, be, bel, bea, bela, icbt, icbte, lwzxe): Likewise. (dcbste, lwzuxe, luxe, dcbfe, lbzxe, lwarxe, lbzuxe): Likewise. (stwcxe, stwxe, stxe, stwuxe, stuxe, stbxe, dcbtste, stbuxe): Likewise. (mfapidi, dcbte, lhzxe, lhzuxe, lhaxe, lhauxe, subfe64): Likewise. (subfeo64, adde64, addeo64, sthxe, sthuxe, subfze64): Likewise. (subfzeo64, addze64, addzeo64, dcbie, subfme64, subfmeo64): Likewise. (addme64, addmeo64, stdcxe., mcrxr64, lwbrxe, lfsxe, lfsuxe): Likewise. (lfdxe, lfduxe, stwbrxe, stfsxe, stfsuxe, stfdxe, dcbae): Likewise. (stfduxe, tlbivax, tlbivaxe, lhbrxe, ldxe, lduxe, tlbsx): Likewise. (tlbsxe, sthbrxe, stdxe, stduxe, icbie, stfiwxe, dcbze, lbze): Likewise. (lbzue, ldue, lhze, lhzue, lhae, lhaue, lwze, lwzue): Likewise. (stbe, stbue, sthe, sthue, stwe, stwue, lfse, lfsue, lfde): Likewise. (lfdue, stde, stdue, stfse, stfsue, stfde, stfdue): Likewise. * ppc-dis.c (print_insn_big_powerpc, print_insn_little_powerpc): Look for a disassembler option of `booke', `booke32' or `booke64' to enable BookE support in the disassembler.
2001-10-13 03:59:09 +02:00
{
ppc_cpu_t dialect = 0;
char *arg;
2008-06-13 22:16:00 +02:00
struct dis_private *priv = calloc (sizeof (*priv), 1);
if (priv == NULL)
return FALSE;
[gas/ChangeLog] * config/tc-ppc.c (md_parse_option): New -m7410, -m7450 and -m7455 flags, equivalent to -m7400. New -maltivec to enable AltiVec instructions. New -mbook64 and -mbooke/-mbooke32 flags to enable 64-bit and 32-bit BookE support, respectively. Change -m403 and -m405 to set PPC403 option. (md_show_usage): Adjust for new options. * doc/all.texi: Set PPC. * doc/as.texinfo: Add PPC support and pull in c-ppc.texi. * doc/c-ppc.texi: New file. * doc/Makefile.am (CPU_DOCS): Add c-ppc.texi. * doc/Makefile.in: Regenerate. [gas/testsuite/ChangeLog] * gas/ppc/booke.s: New test for Motorola BookE. * gas/ppc/booke.d: New file. * gas/ppc/ppc.exp: Test booke.s. [include/opcode/ChangeLog] * ppc.h (PPC_OPCODE_BOOKE, PPC_OPCODE_403): New opcode flags for BookE and PowerPC403 instructions. [opcodes/ChangeLog] * ppc-opc.c (insert_de, extract_de, insert_des, extract_des): New instruction field instruction/extraction functions for new BookE DE form instructions. (CT): New macro for CT field in an X form instruction. (DE, DES, DEO, DE_MASK): New macros for DE/DES fields in DE form instructions. (PPC64): Don't include PPC_OPCODE_PPC. (403): New opcode macro for PPC403 processors. (BOOKE): New opcode macro for BookE processors. (bce, bcel, bcea, bcela, bclre, bclrel: New BookE instructions. (bcctre, bcctrel, be, bel, bea, bela, icbt, icbte, lwzxe): Likewise. (dcbste, lwzuxe, luxe, dcbfe, lbzxe, lwarxe, lbzuxe): Likewise. (stwcxe, stwxe, stxe, stwuxe, stuxe, stbxe, dcbtste, stbuxe): Likewise. (mfapidi, dcbte, lhzxe, lhzuxe, lhaxe, lhauxe, subfe64): Likewise. (subfeo64, adde64, addeo64, sthxe, sthuxe, subfze64): Likewise. (subfzeo64, addze64, addzeo64, dcbie, subfme64, subfmeo64): Likewise. (addme64, addmeo64, stdcxe., mcrxr64, lwbrxe, lfsxe, lfsuxe): Likewise. (lfdxe, lfduxe, stwbrxe, stfsxe, stfsuxe, stfdxe, dcbae): Likewise. (stfduxe, tlbivax, tlbivaxe, lhbrxe, ldxe, lduxe, tlbsx): Likewise. (tlbsxe, sthbrxe, stdxe, stduxe, icbie, stfiwxe, dcbze, lbze): Likewise. (lbzue, ldue, lhze, lhzue, lhae, lhaue, lwze, lwzue): Likewise. (stbe, stbue, sthe, sthue, stwe, stwue, lfse, lfsue, lfde): Likewise. (lfdue, stde, stdue, stfse, stfsue, stfde, stfdue): Likewise. * ppc-dis.c (print_insn_big_powerpc, print_insn_little_powerpc): Look for a disassembler option of `booke', `booke32' or `booke64' to enable BookE support in the disassembler.
2001-10-13 03:59:09 +02:00
arg = info->disassembler_options;
while (arg != NULL)
{
ppc_cpu_t new_cpu = 0;
char *end = strchr (arg, ',');
if (end != NULL)
*end = 0;
if ((new_cpu = ppc_parse_cpu (dialect, arg)) != 0)
dialect = new_cpu;
else if (strcmp (arg, "32") == 0)
{
dialect &= ~PPC_OPCODE_64;
dialect |= PPC_OPCODE_32;
}
else if (strcmp (arg, "64") == 0)
{
dialect |= PPC_OPCODE_64;
dialect &= ~PPC_OPCODE_32;
}
else
fprintf (stderr, _("warning: ignoring unknown -M%s option\n"), arg);
if (end != NULL)
*end++ = ',';
arg = end;
}
if ((dialect & ~(PPC_OPCODE_32 | PPC_OPCODE_64)) == 0)
binutils/ChangeLog * doc/binutils.texi (objdump): Document ppc -M options. gas/ChangeLog * config/tc-ppc.c (ppc_insert_operand): Pass (ppc_cpu | ppc_size) to operand->insert. (md_assemble): Likewise. gas/testsuite/ChangeLog * gas/ppc/booke.d: Modify reloc and target matches for powerpc64. include/opcode/ChangeLog * ppc.h (struct powerpc_operand <insert, extract>): Add dialect param. opcodes/ChangeLog * ppc-opc.c (PPC64): Revert 2001-10-12. Do include PPC_OPCODE_PPC. (insert_bat, extract_bat, insert_bba, extract_bba, insert_bd, extract_bd, insert_bdm, extract_bdm, insert_bdp, extract_bdp, valid_bo, insert_bo, extract_bo, insert_boe, extract_boe, insert_ds, extract_ds, insert_de, extract_de, insert_des, extract_des, insert_li, extract_li, insert_mbe, extract_mbe, insert_mb6, extract_mb6, insert_nb, extract_nb, insert_nsi, extract_nsi, insert_ral, insert_ram, insert_ras, insert_rbs, extract_rbs, insert_sh6, extract_sh6, insert_spr, extract_spr, insert_tbr, extract_tbr): Add dialect param. (extract_bd, extract_bdm, extract_bdp, extract_ds, extract_des, extract_li, extract_nsi): Implement sign extension without conditional. (insert_bdm, extract_bdm, insert_bdp, extract_bdp, valid_bo): Handle 64 bit branch hints. (extract_bdm, extract_bdp): Correct 32 bit validation. (AT1_MASK, AT2_MASK): Define. (BBOAT_MASK): Define. (BBOATCB_MASK, BBOAT2CB_MASK, BBOATBI_MASK): Define. (BOFM64, BOFP64, BOTM64, BOTP64): Define. (BODNZM64, BODNZP64, BODZM64, BODZP64): Define. (PPCCOM32, PPCCOM64): Define. (powerpc_opcodes): Modify existing 32 bit insns with branch hints and add new patterns to implement 64 bit branches with hints. Move booke instructions so they match before ppc64. * ppc-dis.c (powerpc_dialect): Set PPC_OPCODE_64 in dialect for 64 bit default targets, and parse "32" and "64" in options. Formatting fixes. (print_insn_powerpc): Pass dialect to operand->extract.
2001-11-15 02:08:53 +01:00
{
if (info->mach == bfd_mach_ppc64)
dialect |= PPC_OPCODE_64;
else
dialect |= PPC_OPCODE_32;
/* Choose a reasonable default. */
dialect |= (PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_CLASSIC
| PPC_OPCODE_601 | PPC_OPCODE_ALTIVEC);
binutils/ChangeLog * doc/binutils.texi (objdump): Document ppc -M options. gas/ChangeLog * config/tc-ppc.c (ppc_insert_operand): Pass (ppc_cpu | ppc_size) to operand->insert. (md_assemble): Likewise. gas/testsuite/ChangeLog * gas/ppc/booke.d: Modify reloc and target matches for powerpc64. include/opcode/ChangeLog * ppc.h (struct powerpc_operand <insert, extract>): Add dialect param. opcodes/ChangeLog * ppc-opc.c (PPC64): Revert 2001-10-12. Do include PPC_OPCODE_PPC. (insert_bat, extract_bat, insert_bba, extract_bba, insert_bd, extract_bd, insert_bdm, extract_bdm, insert_bdp, extract_bdp, valid_bo, insert_bo, extract_bo, insert_boe, extract_boe, insert_ds, extract_ds, insert_de, extract_de, insert_des, extract_des, insert_li, extract_li, insert_mbe, extract_mbe, insert_mb6, extract_mb6, insert_nb, extract_nb, insert_nsi, extract_nsi, insert_ral, insert_ram, insert_ras, insert_rbs, extract_rbs, insert_sh6, extract_sh6, insert_spr, extract_spr, insert_tbr, extract_tbr): Add dialect param. (extract_bd, extract_bdm, extract_bdp, extract_ds, extract_des, extract_li, extract_nsi): Implement sign extension without conditional. (insert_bdm, extract_bdm, insert_bdp, extract_bdp, valid_bo): Handle 64 bit branch hints. (extract_bdm, extract_bdp): Correct 32 bit validation. (AT1_MASK, AT2_MASK): Define. (BBOAT_MASK): Define. (BBOATCB_MASK, BBOAT2CB_MASK, BBOATBI_MASK): Define. (BOFM64, BOFP64, BOTM64, BOTP64): Define. (BODNZM64, BODNZP64, BODZM64, BODZP64): Define. (PPCCOM32, PPCCOM64): Define. (powerpc_opcodes): Modify existing 32 bit insns with branch hints and add new patterns to implement 64 bit branches with hints. Move booke instructions so they match before ppc64. * ppc-dis.c (powerpc_dialect): Set PPC_OPCODE_64 in dialect for 64 bit default targets, and parse "32" and "64" in options. Formatting fixes. (print_insn_powerpc): Pass dialect to operand->extract.
2001-11-15 02:08:53 +01:00
}
2008-06-13 22:16:00 +02:00
info->private_data = priv;
POWERPC_DIALECT(info) = dialect;
return TRUE;
[gas/ChangeLog] * config/tc-ppc.c (md_parse_option): New -m7410, -m7450 and -m7455 flags, equivalent to -m7400. New -maltivec to enable AltiVec instructions. New -mbook64 and -mbooke/-mbooke32 flags to enable 64-bit and 32-bit BookE support, respectively. Change -m403 and -m405 to set PPC403 option. (md_show_usage): Adjust for new options. * doc/all.texi: Set PPC. * doc/as.texinfo: Add PPC support and pull in c-ppc.texi. * doc/c-ppc.texi: New file. * doc/Makefile.am (CPU_DOCS): Add c-ppc.texi. * doc/Makefile.in: Regenerate. [gas/testsuite/ChangeLog] * gas/ppc/booke.s: New test for Motorola BookE. * gas/ppc/booke.d: New file. * gas/ppc/ppc.exp: Test booke.s. [include/opcode/ChangeLog] * ppc.h (PPC_OPCODE_BOOKE, PPC_OPCODE_403): New opcode flags for BookE and PowerPC403 instructions. [opcodes/ChangeLog] * ppc-opc.c (insert_de, extract_de, insert_des, extract_des): New instruction field instruction/extraction functions for new BookE DE form instructions. (CT): New macro for CT field in an X form instruction. (DE, DES, DEO, DE_MASK): New macros for DE/DES fields in DE form instructions. (PPC64): Don't include PPC_OPCODE_PPC. (403): New opcode macro for PPC403 processors. (BOOKE): New opcode macro for BookE processors. (bce, bcel, bcea, bcela, bclre, bclrel: New BookE instructions. (bcctre, bcctrel, be, bel, bea, bela, icbt, icbte, lwzxe): Likewise. (dcbste, lwzuxe, luxe, dcbfe, lbzxe, lwarxe, lbzuxe): Likewise. (stwcxe, stwxe, stxe, stwuxe, stuxe, stbxe, dcbtste, stbuxe): Likewise. (mfapidi, dcbte, lhzxe, lhzuxe, lhaxe, lhauxe, subfe64): Likewise. (subfeo64, adde64, addeo64, sthxe, sthuxe, subfze64): Likewise. (subfzeo64, addze64, addzeo64, dcbie, subfme64, subfmeo64): Likewise. (addme64, addmeo64, stdcxe., mcrxr64, lwbrxe, lfsxe, lfsuxe): Likewise. (lfdxe, lfduxe, stwbrxe, stfsxe, stfsuxe, stfdxe, dcbae): Likewise. (stfduxe, tlbivax, tlbivaxe, lhbrxe, ldxe, lduxe, tlbsx): Likewise. (tlbsxe, sthbrxe, stdxe, stduxe, icbie, stfiwxe, dcbze, lbze): Likewise. (lbzue, ldue, lhze, lhzue, lhae, lhaue, lwze, lwzue): Likewise. (stbe, stbue, sthe, sthue, stwe, stwue, lfse, lfsue, lfde): Likewise. (lfdue, stde, stdue, stfse, stfsue, stfde, stfdue): Likewise. * ppc-dis.c (print_insn_big_powerpc, print_insn_little_powerpc): Look for a disassembler option of `booke', `booke32' or `booke64' to enable BookE support in the disassembler.
2001-10-13 03:59:09 +02:00
}
/* Print a big endian PowerPC instruction. */
1999-05-03 09:29:11 +02:00
int
print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info)
1999-05-03 09:29:11 +02:00
{
2008-06-13 22:16:00 +02:00
if (info->private_data == NULL && !powerpc_init_dialect (info))
return -1;
return print_insn_powerpc (memaddr, info, 1, POWERPC_DIALECT(info));
1999-05-03 09:29:11 +02:00
}
[gas/ChangeLog] * config/tc-ppc.c (md_parse_option): New -m7410, -m7450 and -m7455 flags, equivalent to -m7400. New -maltivec to enable AltiVec instructions. New -mbook64 and -mbooke/-mbooke32 flags to enable 64-bit and 32-bit BookE support, respectively. Change -m403 and -m405 to set PPC403 option. (md_show_usage): Adjust for new options. * doc/all.texi: Set PPC. * doc/as.texinfo: Add PPC support and pull in c-ppc.texi. * doc/c-ppc.texi: New file. * doc/Makefile.am (CPU_DOCS): Add c-ppc.texi. * doc/Makefile.in: Regenerate. [gas/testsuite/ChangeLog] * gas/ppc/booke.s: New test for Motorola BookE. * gas/ppc/booke.d: New file. * gas/ppc/ppc.exp: Test booke.s. [include/opcode/ChangeLog] * ppc.h (PPC_OPCODE_BOOKE, PPC_OPCODE_403): New opcode flags for BookE and PowerPC403 instructions. [opcodes/ChangeLog] * ppc-opc.c (insert_de, extract_de, insert_des, extract_des): New instruction field instruction/extraction functions for new BookE DE form instructions. (CT): New macro for CT field in an X form instruction. (DE, DES, DEO, DE_MASK): New macros for DE/DES fields in DE form instructions. (PPC64): Don't include PPC_OPCODE_PPC. (403): New opcode macro for PPC403 processors. (BOOKE): New opcode macro for BookE processors. (bce, bcel, bcea, bcela, bclre, bclrel: New BookE instructions. (bcctre, bcctrel, be, bel, bea, bela, icbt, icbte, lwzxe): Likewise. (dcbste, lwzuxe, luxe, dcbfe, lbzxe, lwarxe, lbzuxe): Likewise. (stwcxe, stwxe, stxe, stwuxe, stuxe, stbxe, dcbtste, stbuxe): Likewise. (mfapidi, dcbte, lhzxe, lhzuxe, lhaxe, lhauxe, subfe64): Likewise. (subfeo64, adde64, addeo64, sthxe, sthuxe, subfze64): Likewise. (subfzeo64, addze64, addzeo64, dcbie, subfme64, subfmeo64): Likewise. (addme64, addmeo64, stdcxe., mcrxr64, lwbrxe, lfsxe, lfsuxe): Likewise. (lfdxe, lfduxe, stwbrxe, stfsxe, stfsuxe, stfdxe, dcbae): Likewise. (stfduxe, tlbivax, tlbivaxe, lhbrxe, ldxe, lduxe, tlbsx): Likewise. (tlbsxe, sthbrxe, stdxe, stduxe, icbie, stfiwxe, dcbze, lbze): Likewise. (lbzue, ldue, lhze, lhzue, lhae, lhaue, lwze, lwzue): Likewise. (stbe, stbue, sthe, sthue, stwe, stwue, lfse, lfsue, lfde): Likewise. (lfdue, stde, stdue, stfse, stfsue, stfde, stfdue): Likewise. * ppc-dis.c (print_insn_big_powerpc, print_insn_little_powerpc): Look for a disassembler option of `booke', `booke32' or `booke64' to enable BookE support in the disassembler.
2001-10-13 03:59:09 +02:00
/* Print a little endian PowerPC instruction. */
1999-05-03 09:29:11 +02:00
int
print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info)
1999-05-03 09:29:11 +02:00
{
2008-06-13 22:16:00 +02:00
if (info->private_data == NULL && !powerpc_init_dialect (info))
return -1;
return print_insn_powerpc (memaddr, info, 0, POWERPC_DIALECT(info));
1999-05-03 09:29:11 +02:00
}
/* Print a POWER (RS/6000) instruction. */
int
print_insn_rs6000 (bfd_vma memaddr, struct disassemble_info *info)
1999-05-03 09:29:11 +02:00
{
return print_insn_powerpc (memaddr, info, 1, PPC_OPCODE_POWER);
}
/* Extract the operand value from the PowerPC or POWER instruction. */
static long
operand_value_powerpc (const struct powerpc_operand *operand,
2008-06-13 22:16:00 +02:00
unsigned long insn, ppc_cpu_t dialect)
{
long value;
int invalid;
/* Extract the value from the instruction. */
if (operand->extract)
value = (*operand->extract) (insn, dialect, &invalid);
else
{
value = (insn >> operand->shift) & operand->bitm;
if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
{
/* BITM is always some number of zeros followed by some
number of ones, followed by some numer of zeros. */
unsigned long top = operand->bitm;
/* top & -top gives the rightmost 1 bit, so this
fills in any trailing zeros. */
top |= (top & -top) - 1;
top &= ~(top >> 1);
value = (value ^ top) - top;
}
}
return value;
}
/* Determine whether the optional operand(s) should be printed. */
static int
skip_optional_operands (const unsigned char *opindex,
2008-06-13 22:16:00 +02:00
unsigned long insn, ppc_cpu_t dialect)
{
const struct powerpc_operand *operand;
for (; *opindex != 0; opindex++)
{
operand = &powerpc_operands[*opindex];
if ((operand->flags & PPC_OPERAND_NEXT) != 0
|| ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
&& operand_value_powerpc (operand, insn, dialect) != 0))
return 0;
}
return 1;
}
1999-05-03 09:29:11 +02:00
/* Print a PowerPC or POWER instruction. */
static int
print_insn_powerpc (bfd_vma memaddr,
struct disassemble_info *info,
int bigendian,
2008-06-13 22:16:00 +02:00
ppc_cpu_t dialect)
1999-05-03 09:29:11 +02:00
{
bfd_byte buffer[4];
int status;
unsigned long insn;
const struct powerpc_opcode *opcode;
const struct powerpc_opcode *opcode_end;
unsigned long op;
ppc_cpu_t dialect_orig = dialect;
1999-05-03 09:29:11 +02:00
status = (*info->read_memory_func) (memaddr, buffer, 4, info);
if (status != 0)
{
(*info->memory_error_func) (status, memaddr, info);
return -1;
}
if (bigendian)
insn = bfd_getb32 (buffer);
else
insn = bfd_getl32 (buffer);
/* Get the major opcode of the instruction. */
op = PPC_OP (insn);
/* 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:
1999-05-03 09:29:11 +02:00
for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++)
{
unsigned long table_op;
const unsigned char *opindex;
const struct powerpc_operand *operand;
int invalid;
int need_comma;
int need_paren;
int skip_optional;
1999-05-03 09:29:11 +02:00
table_op = PPC_OP (opcode->opcode);
if (op < table_op)
break;
if (op > table_op)
continue;
if ((insn & opcode->mask) != opcode->opcode
|| (opcode->flags & dialect) == 0
|| (opcode->deprecated & dialect_orig) != 0)
1999-05-03 09:29:11 +02:00
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. */
invalid = 0;
for (opindex = opcode->operands; *opindex != 0; opindex++)
{
operand = powerpc_operands + *opindex;
if (operand->extract)
binutils/ChangeLog * doc/binutils.texi (objdump): Document ppc -M options. gas/ChangeLog * config/tc-ppc.c (ppc_insert_operand): Pass (ppc_cpu | ppc_size) to operand->insert. (md_assemble): Likewise. gas/testsuite/ChangeLog * gas/ppc/booke.d: Modify reloc and target matches for powerpc64. include/opcode/ChangeLog * ppc.h (struct powerpc_operand <insert, extract>): Add dialect param. opcodes/ChangeLog * ppc-opc.c (PPC64): Revert 2001-10-12. Do include PPC_OPCODE_PPC. (insert_bat, extract_bat, insert_bba, extract_bba, insert_bd, extract_bd, insert_bdm, extract_bdm, insert_bdp, extract_bdp, valid_bo, insert_bo, extract_bo, insert_boe, extract_boe, insert_ds, extract_ds, insert_de, extract_de, insert_des, extract_des, insert_li, extract_li, insert_mbe, extract_mbe, insert_mb6, extract_mb6, insert_nb, extract_nb, insert_nsi, extract_nsi, insert_ral, insert_ram, insert_ras, insert_rbs, extract_rbs, insert_sh6, extract_sh6, insert_spr, extract_spr, insert_tbr, extract_tbr): Add dialect param. (extract_bd, extract_bdm, extract_bdp, extract_ds, extract_des, extract_li, extract_nsi): Implement sign extension without conditional. (insert_bdm, extract_bdm, insert_bdp, extract_bdp, valid_bo): Handle 64 bit branch hints. (extract_bdm, extract_bdp): Correct 32 bit validation. (AT1_MASK, AT2_MASK): Define. (BBOAT_MASK): Define. (BBOATCB_MASK, BBOAT2CB_MASK, BBOATBI_MASK): Define. (BOFM64, BOFP64, BOTM64, BOTP64): Define. (BODNZM64, BODNZP64, BODZM64, BODZP64): Define. (PPCCOM32, PPCCOM64): Define. (powerpc_opcodes): Modify existing 32 bit insns with branch hints and add new patterns to implement 64 bit branches with hints. Move booke instructions so they match before ppc64. * ppc-dis.c (powerpc_dialect): Set PPC_OPCODE_64 in dialect for 64 bit default targets, and parse "32" and "64" in options. Formatting fixes. (print_insn_powerpc): Pass dialect to operand->extract.
2001-11-15 02:08:53 +01:00
(*operand->extract) (insn, dialect, &invalid);
1999-05-03 09:29:11 +02:00
}
if (invalid)
continue;
/* The instruction is valid. */
if (opcode->operands[0] != 0)
(*info->fprintf_func) (info->stream, "%-7s ", opcode->name);
else
(*info->fprintf_func) (info->stream, "%s", opcode->name);
1999-05-03 09:29:11 +02:00
/* Now extract and print the operands. */
need_comma = 0;
need_paren = 0;
skip_optional = -1;
1999-05-03 09:29:11 +02:00
for (opindex = opcode->operands; *opindex != 0; opindex++)
{
long value;
operand = powerpc_operands + *opindex;
/* Operands that are marked FAKE are simply ignored. We
already made sure that the extract function considered
the instruction to be valid. */
if ((operand->flags & PPC_OPERAND_FAKE) != 0)
continue;
/* If all of the optional operands have the value zero,
then don't print any of them. */
if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
{
if (skip_optional < 0)
skip_optional = skip_optional_operands (opindex, insn,
dialect);
if (skip_optional)
continue;
}
1999-05-03 09:29:11 +02:00
value = operand_value_powerpc (operand, insn, dialect);
1999-05-03 09:29:11 +02:00
if (need_comma)
{
(*info->fprintf_func) (info->stream, ",");
need_comma = 0;
}
/* Print the operand as directed by the flags. */
if ((operand->flags & PPC_OPERAND_GPR) != 0
|| ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
1999-05-03 09:29:11 +02:00
(*info->fprintf_func) (info->stream, "r%ld", value);
else if ((operand->flags & PPC_OPERAND_FPR) != 0)
(*info->fprintf_func) (info->stream, "f%ld", value);
else if ((operand->flags & PPC_OPERAND_VR) != 0)
(*info->fprintf_func) (info->stream, "v%ld", value);
else if ((operand->flags & PPC_OPERAND_VSR) != 0)
(*info->fprintf_func) (info->stream, "vs%ld", value);
1999-05-03 09:29:11 +02:00
else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
(*info->print_address_func) (memaddr + value, info);
else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
(*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
else if ((operand->flags & PPC_OPERAND_FSL) != 0)
(*info->fprintf_func) (info->stream, "fsl%ld", value);
else if ((operand->flags & PPC_OPERAND_FCR) != 0)
(*info->fprintf_func) (info->stream, "fcr%ld", value);
else if ((operand->flags & PPC_OPERAND_UDI) != 0)
(*info->fprintf_func) (info->stream, "%ld", value);
else if ((operand->flags & PPC_OPERAND_CR) != 0
&& (dialect & PPC_OPCODE_PPC) != 0)
1999-05-03 09:29:11 +02:00
{
if (operand->bitm == 7)
(*info->fprintf_func) (info->stream, "cr%ld", value);
1999-05-03 09:29:11 +02:00
else
{
static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
int cr;
int cc;
cr = value >> 2;
if (cr != 0)
(*info->fprintf_func) (info->stream, "4*cr%d+", cr);
1999-05-03 09:29:11 +02:00
cc = value & 3;
(*info->fprintf_func) (info->stream, "%s", cbnames[cc]);
1999-05-03 09:29:11 +02:00
}
}
else
(*info->fprintf_func) (info->stream, "%ld", value);
1999-05-03 09:29:11 +02:00
if (need_paren)
{
(*info->fprintf_func) (info->stream, ")");
need_paren = 0;
}
if ((operand->flags & PPC_OPERAND_PARENS) == 0)
need_comma = 1;
else
{
(*info->fprintf_func) (info->stream, "(");
need_paren = 1;
}
}
/* We have found and printed an instruction; return. */
return 4;
}
if ((dialect & PPC_OPCODE_ANY) != 0)
{
dialect = ~PPC_OPCODE_ANY;
goto again;
}
1999-05-03 09:29:11 +02:00
/* We could not find a match. */
(*info->fprintf_func) (info->stream, ".long 0x%lx", insn);
return 4;
}
void
print_ppc_disassembler_options (FILE *stream)
{
unsigned int i, col;
fprintf (stream, _("\n\
The following PPC specific disassembler options are supported for use with\n\
the -M switch:\n"));
for (col = 0, i = 0; i < sizeof (ppc_opts) / sizeof (ppc_opts[0]); i++)
{
col += fprintf (stream, " %s,", ppc_opts[i].opt);
if (col > 66)
{
fprintf (stream, "\n");
col = 0;
}
}
fprintf (stream, " 32, 64\n");
}