This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Add PowerPC .gnu_attribute for the vector ABI


On Tue, Aug 07, 2007 at 12:00:11PM -0400, Daniel Jacobowitz wrote:
> This patch adds merging support for a .gnu_attribute which describes
> the vector ABI: "generic", AltiVec, SPE, or don't-care.  I think this
> is the most sensible arrangement, since the AltiVec and SPE
> alternatives can not coexist.

> 2007-08-07  Daniel Jacobowitz  <dan@codesourcery.com>
> 
> 	* elf32-ppc.c (ppc_elf_merge_obj_attributes): Add support for
> 	Tag_GNU_Power_ABI_Vector.
> 
> 	* readelf.c (display_power_gnu_attribute): Add support for
> 	Tag_GNU_Power_ABI_Vector.
> 
> 	* ppc.h (Tag_GNU_Power_ABI_Vector): New.
> 
> 	* ld-powerpc/attr-gnu-8-1.s, ld-powerpc/attr-gnu-8-11.d,
> 	ld-powerpc/attr-gnu-8-3.s, ld-powerpc/attr-gnu-8-31.d: New.

There were three problems with this patch.  The first is that I didn't
add the tests to powerpc.exp, so they were never run.  The second is
that they failed once run.  The more serious problem is that the
vector ABI warning is not terribly useful.

In theory, it is no different from the FP warning.  If no floating
point arguments are passed to library functions, the soft float ABI
is sufficiently compatible with the hard float ABI that everything
just works.  More often this indicates an accident at link time
which selected the wrong libraries.

The vector ABI attribute marks two things: sufficient stack alignment
and the use of vector registers for arguments.  My understanding when
I wrote the patch was that most PowerPC 32-bit targets did not have a
sufficiently aligned stack for AltiVec loads and stores; I was wrong.
powerpc-eabi does not, but powerpc-linux always does.  And most
code does not take vector arguments.  So using -mabi=altivec on
powerpc-linux systems is a sufficiently reasonable thing to do that
I shouldn't make ld scold people for it.

So I tested and committed this version instead, which is more forgiving.

-- 
Daniel Jacobowitz
CodeSourcery

2007-10-25  Daniel Jacobowitz  <dan@codesourcery.com>

	* elf32-ppc.c (ppc_elf_merge_obj_attributes): Add support for
	Tag_GNU_Power_ABI_Vector.

2007-10-25  Daniel Jacobowitz  <dan@codesourcery.com>

	* readelf.c (display_power_gnu_attribute): Add support for
	Tag_GNU_Power_ABI_Vector.

2007-10-25  Daniel Jacobowitz  <dan@codesourcery.com>

	* ppc.h (Tag_GNU_Power_ABI_Vector): New.

2007-10-25  Daniel Jacobowitz  <dan@codesourcery.com>

	* ld-powerpc/attr-gnu-8-1.s, ld-powerpc/attr-gnu-8-11.d,
	ld-powerpc/attr-gnu-8-2.s, ld-powerpc/attr-gnu-8-23.d,
	ld-powerpc/attr-gnu-8-3.s, ld-powerpc/attr-gnu-8-31.d: New.
	* ld-powerpc/powerpc.exp: Run new tests.

Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.221
diff -u -p -r1.221 elf32-ppc.c
--- bfd/elf32-ppc.c	26 Sep 2007 13:45:32 -0000	1.221
+++ bfd/elf32-ppc.c	25 Oct 2007 15:15:36 -0000
@@ -3603,8 +3603,8 @@ ppc_elf_check_relocs (bfd *abfd,
 static bfd_boolean
 ppc_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
 {
-  obj_attribute *in_attr;
-  obj_attribute *out_attr;
+  obj_attribute *in_attr, *in_attrs;
+  obj_attribute *out_attr, *out_attrs;
 
   if (!elf_known_obj_attributes_proc (obfd)[0].i)
     {
@@ -3618,33 +3618,84 @@ ppc_elf_merge_obj_attributes (bfd *ibfd,
       return TRUE;
     }
 
+  in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
+  out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
+
   /* Check for conflicting Tag_GNU_Power_ABI_FP attributes and merge
      non-conflicting ones.  */
-  in_attr = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
-  out_attr = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
-  if (in_attr[Tag_GNU_Power_ABI_FP].i != out_attr[Tag_GNU_Power_ABI_FP].i)
-    {
-      out_attr[Tag_GNU_Power_ABI_FP].type = 1;
-      if (out_attr[Tag_GNU_Power_ABI_FP].i == 0)
-	out_attr[Tag_GNU_Power_ABI_FP].i = in_attr[Tag_GNU_Power_ABI_FP].i;
-      else if (in_attr[Tag_GNU_Power_ABI_FP].i == 0)
+  in_attr = &in_attrs[Tag_GNU_Power_ABI_FP];
+  out_attr = &out_attrs[Tag_GNU_Power_ABI_FP];
+  if (in_attr->i != out_attr->i)
+    {
+      out_attr->type = 1;
+      if (out_attr->i == 0)
+	out_attr->i = in_attr->i;
+      else if (in_attr->i == 0)
 	;
-      else if (out_attr[Tag_GNU_Power_ABI_FP].i == 1
-	       && in_attr[Tag_GNU_Power_ABI_FP].i == 2)
+      else if (out_attr->i == 1 && in_attr->i == 2)
 	_bfd_error_handler
 	  (_("Warning: %B uses hard float, %B uses soft float"), obfd, ibfd);
-      else if (out_attr[Tag_GNU_Power_ABI_FP].i == 2
-	       && in_attr[Tag_GNU_Power_ABI_FP].i == 1)
+      else if (out_attr->i == 2 && in_attr->i == 1)
 	_bfd_error_handler
 	  (_("Warning: %B uses hard float, %B uses soft float"), ibfd, obfd);
-      else if (in_attr[Tag_GNU_Power_ABI_FP].i > 2)
+      else if (in_attr->i > 2)
 	_bfd_error_handler
 	  (_("Warning: %B uses unknown floating point ABI %d"), ibfd,
-	   in_attr[Tag_GNU_Power_ABI_FP].i);
+	   in_attr->i);
       else
 	_bfd_error_handler
 	  (_("Warning: %B uses unknown floating point ABI %d"), obfd,
-	   out_attr[Tag_GNU_Power_ABI_FP].i);
+	   out_attr->i);
+    }
+
+  /* Check for conflicting Tag_GNU_Power_ABI_Vector attributes and
+     merge non-conflicting ones.  */
+  in_attr = &in_attrs[Tag_GNU_Power_ABI_Vector];
+  out_attr = &out_attrs[Tag_GNU_Power_ABI_Vector];
+  if (in_attr->i != out_attr->i)
+    {
+      const char *in_abi = NULL, *out_abi = NULL;
+
+      switch (in_attr->i)
+	{
+	case 1: in_abi = "generic"; break;
+	case 2: in_abi = "AltiVec"; break;
+	case 3: in_abi = "SPE"; break;
+	}
+
+      switch (out_attr->i)
+	{
+	case 1: out_abi = "generic"; break;
+	case 2: out_abi = "AltiVec"; break;
+	case 3: out_abi = "SPE"; break;
+	}
+
+      out_attr->type = 1;
+      if (out_attr->i == 0)
+	out_attr->i = in_attr->i;
+      else if (in_attr->i == 0)
+	;
+      /* For now, allow generic to transition to AltiVec or SPE
+	 without a warning.  If GCC marked files with their stack
+	 alignment and used don't-care markings for files which are
+	 not affected by the vector ABI, we could warn about this
+	 case too.  */
+      else if (out_attr->i == 1)
+	out_attr->i = in_attr->i;
+      else if (in_attr->i == 1)
+	;
+      else if (in_abi == NULL)
+	_bfd_error_handler
+	  (_("Warning: %B uses unknown vector ABI %d"), ibfd,
+	   in_attr->i);
+      else if (out_abi == NULL)
+	_bfd_error_handler
+	  (_("Warning: %B uses unknown vector ABI %d"), obfd,
+	   in_attr->i);
+      else
+	_bfd_error_handler
+	  (_("Warning: %B uses vector ABI \"%s\", %B uses \"%s\""),
+	   ibfd, obfd, in_abi, out_abi);
     }
 
   /* Merge Tag_compatibility attributes and any common GNU ones.  */
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.383
diff -u -p -r1.383 readelf.c
--- binutils/readelf.c	25 Oct 2007 00:41:16 -0000	1.383
+++ binutils/readelf.c	25 Oct 2007 15:15:36 -0000
@@ -8553,6 +8553,32 @@ display_power_gnu_attribute (unsigned ch
       return p;
    }
 
+  if (tag == Tag_GNU_Power_ABI_Vector)
+    {
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_GNU_Power_ABI_Vector: ");
+      switch (val)
+	{
+	case 0:
+	  printf ("Any\n");
+	  break;
+	case 1:
+	  printf ("Generic\n");
+	  break;
+	case 2:
+	  printf ("AltiVec\n");
+	  break;
+	case 3:
+	  printf ("SPE\n");
+	  break;
+	default:
+	  printf ("??? (%d)\n", val);
+	  break;
+	}
+      return p;
+   }
+
   if (tag & 1)
     type = 1; /* String.  */
   else
Index: include/elf/ppc.h
===================================================================
RCS file: /cvs/src/src/include/elf/ppc.h,v
retrieving revision 1.19
diff -u -p -r1.19 ppc.h
--- include/elf/ppc.h	30 Jun 2007 00:03:40 -0000	1.19
+++ include/elf/ppc.h	25 Oct 2007 15:15:37 -0000
@@ -180,6 +180,11 @@ enum
 			       soft-float; 0 for not tagged or not
 			       using any ABIs affected by the
 			       differences.  */
+
+  /* Value 1 for general purpose registers only, 2 for AltiVec
+     registers, 3 for SPE registers; 0 for not tagged or not using any
+     ABIs affected by the differences.  */
+  Tag_GNU_Power_ABI_Vector = 8,
 };
 
 #endif /* _ELF_PPC_H */
Index: ld/testsuite/ld-powerpc/attr-gnu-8-1.s
===================================================================
RCS file: ld/testsuite/ld-powerpc/attr-gnu-8-1.s
diff -N ld/testsuite/ld-powerpc/attr-gnu-8-1.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/attr-gnu-8-1.s	25 Oct 2007 15:15:37 -0000
@@ -0,0 +1 @@
+.gnu_attribute 8,1
Index: ld/testsuite/ld-powerpc/attr-gnu-8-11.d
===================================================================
RCS file: ld/testsuite/ld-powerpc/attr-gnu-8-11.d
diff -N ld/testsuite/ld-powerpc/attr-gnu-8-11.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/attr-gnu-8-11.d	25 Oct 2007 15:15:37 -0000
@@ -0,0 +1,10 @@
+#source: attr-gnu-8-1.s
+#source: attr-gnu-8-1.s
+#as: -a32
+#ld: -r -melf32ppc
+#readelf: -A
+#target: powerpc*-*-*
+
+Attribute Section: gnu
+File Attributes
+  Tag_GNU_Power_ABI_Vector: Generic
Index: ld/testsuite/ld-powerpc/attr-gnu-8-2.s
===================================================================
RCS file: ld/testsuite/ld-powerpc/attr-gnu-8-2.s
diff -N ld/testsuite/ld-powerpc/attr-gnu-8-2.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/attr-gnu-8-2.s	25 Oct 2007 15:15:37 -0000
@@ -0,0 +1 @@
+.gnu_attribute 8,2
Index: ld/testsuite/ld-powerpc/attr-gnu-8-23.d
===================================================================
RCS file: ld/testsuite/ld-powerpc/attr-gnu-8-23.d
diff -N ld/testsuite/ld-powerpc/attr-gnu-8-23.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/attr-gnu-8-23.d	25 Oct 2007 15:15:37 -0000
@@ -0,0 +1,6 @@
+#source: attr-gnu-8-2.s
+#source: attr-gnu-8-3.s
+#as: -a32
+#ld: -r -melf32ppc
+#warning: Warning: .* uses vector ABI "SPE", .* uses "AltiVec"
+#target: powerpc*-*-*
Index: ld/testsuite/ld-powerpc/attr-gnu-8-3.s
===================================================================
RCS file: ld/testsuite/ld-powerpc/attr-gnu-8-3.s
diff -N ld/testsuite/ld-powerpc/attr-gnu-8-3.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/attr-gnu-8-3.s	25 Oct 2007 15:15:37 -0000
@@ -0,0 +1 @@
+.gnu_attribute 8,3
Index: ld/testsuite/ld-powerpc/attr-gnu-8-31.d
===================================================================
RCS file: ld/testsuite/ld-powerpc/attr-gnu-8-31.d
diff -N ld/testsuite/ld-powerpc/attr-gnu-8-31.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/attr-gnu-8-31.d	25 Oct 2007 15:15:37 -0000
@@ -0,0 +1,10 @@
+#source: attr-gnu-8-3.s
+#source: attr-gnu-8-1.s
+#as: -a32
+#ld: -r -melf32ppc
+#readelf: -A
+#target: powerpc*-*-*
+
+Attribute Section: gnu
+File Attributes
+  Tag_GNU_Power_ABI_Vector: SPE
Index: ld/testsuite/ld-powerpc/powerpc.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/powerpc.exp,v
retrieving revision 1.20
diff -u -p -r1.20 powerpc.exp
--- ld/testsuite/ld-powerpc/powerpc.exp	6 Jul 2007 14:09:45 -0000	1.20
+++ ld/testsuite/ld-powerpc/powerpc.exp	25 Oct 2007 15:15:37 -0000
@@ -165,3 +165,7 @@ run_dump_test "attr-gnu-4-20"
 run_dump_test "attr-gnu-4-21"
 run_dump_test "attr-gnu-4-22"
 run_dump_test "attr-gnu-4-31"
+
+run_dump_test "attr-gnu-8-11"
+run_dump_test "attr-gnu-8-23"
+run_dump_test "attr-gnu-8-31"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]