gdb/gdb-rhbz890900-ppc-dis-1of2.patch

229 lines
8.5 KiB
Diff
Raw Normal View History

http://sourceware.org/ml/binutils/2012-11/msg00352.html
Subject: Re: [PATCH] Fix gdb disassemble for power6/power7 instructions
On Wed, Nov 14, 2012 at 10:16:38AM +1030, Alan Modra wrote:
> What I think should happen is that the default handling, ie. the block
> that starts with
> if ((dialect & ~(ppc_cpu_t) PPC_OPCODE_64) == 0)
> should be deleted and a switch on info->mach setting up dialect added
> before we parse disassembler_options. That way -m32 and -m64 can
> override the default as they are supposed to. See bfd/archures.c for
> values of bfd_mach_ppc_*.
Well that idea didn't turn out to be simple. If we want to bring the
default up to something more up-to-date than the current ppc601, then
you run into difficulty with "retain_mask" in ppc_parse_cpu. Choosing
any of the bits in that mask as a default, eg. PPC_OPCODE_VSX, results
in not being able to get rid of those bits.
Now the idea of "retain_mask" was to cover cases where people pass
something like -mppc -maltivec (or even -maltivec -mppc) to the
assembler. Historically that has resulted in both PPC_OPCODE_PPC and
PPC_OPCODE_ALTIVEC being set; Some options accumulate. So I've
redone code handling these sticky options to just keep track of the
bits selected by ppc_opts.sticky. Any default selection won't make
these bits sticky, you'll only get that effect from -maltivec, -many,
-mspe, -mvle and -mvsx on the command line or in .machine directives
(and similarly for the corresponding -M disassembler options). I'm
not sure why PPC_OPCODE_PMR was ever in "retain_mask". People
interested in VLE might need to investigate that.
One of the effects of updating to a power7 default is that conditional
branch hints are displayed for "at" style hints rather than the older
"y" hints. When using "y" hints the disassembler always showed the
hint, eg. "bne-" or "bne+". Now you'll see "bne" most times. This
meant updating the testsuite. I made one gas test disassemble for
plain ppc just to ensure the older "y" hints continue to be available.
Committed.
include/opcode/
* ppc.h (ppc_parse_cpu): Update prototype.
opcodes/
* 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.
gas/
* config/tc-ppc.c (sticky): New var.
(md_parse_option, ppc_machine): Update ppc_parse_cpu calls.
gas/testsuite/
* gas/ppc/astest2.d: Pass -Mppc to objdump.
ld/testsuite/
* ld-powerpc/plt1.d: Update for default "at" branch hints.
* ld-powerpc/tlsexe.d: Likewise.
* ld-powerpc/tlsexetoc.d: Likewise.
* ld-powerpc/tlsopt1.d: Likewise.
* ld-powerpc/tlsopt1_32.d: Likewise.
* ld-powerpc/tlsopt2.d: Likewise.
* ld-powerpc/tlsopt2_32.d: Likewise.
* ld-powerpc/tlsopt4.d: Likewise.
* ld-powerpc/tlsopt4_32.d: Likewise.
* ld-powerpc/tlsso.d: Likewise.
* ld-powerpc/tlstocso.d: Likewise.
Index: include/opcode/ppc.h
===================================================================
RCS file: /cvs/src/src/include/opcode/ppc.h,v
retrieving revision 1.44
diff -u -p -r1.44 ppc.h
--- ./include/opcode/ppc.h 14 May 2012 19:45:27 -0000 1.44
+++ ./include/opcode/ppc.h 22 Nov 2012 22:45:18 -0000
@@ -400,6 +400,6 @@ struct powerpc_macro
extern const struct powerpc_macro powerpc_macros[];
extern const int powerpc_num_macros;
-extern ppc_cpu_t ppc_parse_cpu (ppc_cpu_t, const char *);
+extern ppc_cpu_t ppc_parse_cpu (ppc_cpu_t, ppc_cpu_t *, const char *);
#endif /* PPC_H */
Index: opcodes/ppc-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-dis.c,v
retrieving revision 1.60
diff -u -p -r1.60 ppc-dis.c
--- ./opcodes/ppc-dis.c 5 Oct 2012 14:06:20 -0000 1.60
+++ ./opcodes/ppc-dis.c 22 Nov 2012 22:45:19 -0000
@@ -211,13 +211,8 @@ get_powerpc_dialect (struct disassemble_
/* 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
{
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
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
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
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;
}