PowerPC: ignore sticky options for .machine

Alan Modra amodra@gmail.com
Fri Jul 23 11:23:31 GMT 2021


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".

	* config/tc-ppc.c (ppc_machine): Don't use command line
	sticky options.

I'll leave committing this for a while in case someone thinks this is
totally crazy..

The 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.

diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 3eaeb892387..6dbe0d05881 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,16 @@ 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;
+	  ppc_cpu_t no_sticky_options = 0;
+	  new_cpu = ppc_parse_cpu (ppc_cpu, &no_sticky_options, 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 ();

-- 
Alan Modra
Australia Development Lab, IBM


More information about the Binutils mailing list