[binutils-gdb] PowerPC: ignore sticky options for .machine

Alan Modra amodra@sourceware.org
Wed Jul 28 02:16:42 GMT 2021


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b25f942e18d6ecd7ec3e2d2e9930eb4f996c258a

commit b25f942e18d6ecd7ec3e2d2e9930eb4f996c258a
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Jul 22 21:53:26 2021 +0930

    PowerPC: ignore sticky options for .machine
    
    PowerPC gas and objdump for a long time have allowed certain -m/-M
    options that extend a base cpu with extra functional units to be
    specified before the base cpu.  For example, "-maltivec -mpower4" is
    the same as "-mpower4 -maltivec".  See
    https://sourceware.org/pipermail/binutils/2008-January/054935.html
    
    It doesn't make as much sense that .machine keep any of these
    "sticky" flags when handling a new base cpu.  See gcc PR101393.  I
    think that instead .machine ought to override the command line.
    That's what this patch does.  It is still possible to extend cpu
    functionality with .machine.  For example the following can be
    assembled when selecting a basic -mppc on the command line:
            .machine power5
            .machine altivec
            frin 1,2
            lvsr 3,4,5
    Here, ".machine altivec" extends the ".machine power5" so that both
    the power5 "frin" instruction and the altivec "lvsr" instruction are
    enabled.  Swapping the two ".machine" directives would result in
    failure to assemble "lvsr".
    
    This change will expose some assembly errors, such as the one in
    glibc/sysdeps/powerpc/powerpc64/tst-ucontext-ppc64-vscr.c, a file
    compiled with -maltivec but containing
      asm volatile (".machine push;\n"
                    ".machine \"power5\";\n"
                    "vspltisb %0,0;\n"
                    "vspltisb %1,-1;\n"
                    "vpkuwus %0,%0,%1;\n"
                    "mfvscr %0;\n"
                    "stvx %0,0,%2;\n"
                    ".machine pop;"
                    : "=v" (v0), "=v" (v1)
                    : "r" (vscr_ptr)
                    : "memory");
    It's just wrong to choose power5 for a bunch of altivec instructions
    and in fact all of those .machine directives are unnecessary.
    
            * config/tc-ppc.c (ppc_machine): Don't use command line
            sticky options.

Diff:
---
 gas/config/tc-ppc.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 3eaeb892387..6eeb98c5744 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -5680,7 +5680,6 @@ ppc_machine (int ignore ATTRIBUTE_UNUSED)
   if (cpu_string != NULL)
     {
       ppc_cpu_t old_cpu = ppc_cpu;
-      ppc_cpu_t new_cpu;
       char *p;
 
       for (p = cpu_string; *p != 0; p++)
@@ -5703,10 +5702,23 @@ ppc_machine (int ignore ATTRIBUTE_UNUSED)
 	  else
 	    ppc_cpu = cpu_history[--curr_hist];
 	}
-      else if ((new_cpu = ppc_parse_cpu (ppc_cpu, &sticky, cpu_string)) != 0)
-	ppc_cpu = new_cpu;
       else
-	as_bad (_("invalid machine `%s'"), cpu_string);
+	{
+	  ppc_cpu_t new_cpu;
+	  /* Not using the global "sticky" variable here results in
+	     none of the extra functional unit command line options,
+	     -many, -maltivec, -mspe, -mspe2, -mvle, -mvsx, being in
+	     force after selecting a new cpu with .machine.
+	     ".machine altivec" and other extra functional unit
+	     options do not count as a new machine, instead they add
+	     to currently selected opcodes.  */
+	  ppc_cpu_t machine_sticky = 0;
+	  new_cpu = ppc_parse_cpu (ppc_cpu, &machine_sticky, cpu_string);
+	  if (new_cpu != 0)
+	    ppc_cpu = new_cpu;
+	  else
+	    as_bad (_("invalid machine `%s'"), cpu_string);
+	}
 
       if (ppc_cpu != old_cpu)
 	ppc_setup_opcodes ();


More information about the Binutils-cvs mailing list