229 lines
8.5 KiB
Diff
229 lines
8.5 KiB
Diff
|
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;
|
||
|
}
|