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]

[Committed] S/390: Support basr in the TLS code optimization


Hi,

I recently made tls work on s390 without using -fpic:
http://gcc.gnu.org/ml/gcc-patches/2011-10/msg00583.html

This makes the ld tls code optimizer to encounter a different branch
instruction when invoking __tls_get_offset. Instead of a bas now a
basr can be used since the GOT pointer does not need to be added
anymore.  I've committed the attached patch in order to cover basr as
well in the GD->LE and the LD->LE tls optimizations.

This fixes the run-gd and run-ld testcases in the GCC testsuite on
s390 ESA.

Committed to mainline.

Bye,

-Andreas-

2012-02-17  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	* elf32-s390.c (elf_s390_relocate_section): Support basr in the
	GD->LE and LD->LE optimizations.

---
 bfd/elf32-s390.c |   32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

Index: bfd/elf32-s390.c
===================================================================
--- bfd/elf32-s390.c.orig
+++ bfd/elf32-s390.c
@@ -2919,11 +2919,18 @@ elf_s390_relocate_section (output_bfd, i
 
 	      insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
 	      if ((insn & 0xff000fff) != 0x4d000000 &&
-		  (insn & 0xffff0000) != 0xc0e50000)
+		  (insn & 0xffff0000) != 0xc0e50000 &&
+		  (insn & 0xff000000) != 0x0d000000)
 		invalid_tls_insn (input_bfd, input_section, rel);
 	      if (!info->shared && (h == NULL || h->dynindx == -1))
 		{
-		  if ((insn & 0xff000000) == 0x4d000000)
+		  if ((insn & 0xff000000) == 0x0d000000)
+		    {
+		      /* GD->LE transition.
+			 basr rx, ry -> nopr r7 */
+		      insn = 0x07070000 | (insn & 0xffff);
+		    }
+		  else if ((insn & 0xff000000) == 0x4d000000)
 		    {
 		      /* GD->LE transition.
 			 bas %r14,0(%rx,%r13) -> bc 0,0  */
@@ -2932,7 +2939,7 @@ elf_s390_relocate_section (output_bfd, i
 		  else
 		    {
 		      /* GD->LE transition.
-			 brasl %r14,_tls_get_addr@plt -> brcl 0,.  */
+			 brasl %r14,_tls_get_offset@plt -> brcl 0,.  */
 		      insn = 0xc0040000;
 		      bfd_put_16 (output_bfd, 0x0000,
 				  contents + rel->r_offset + 4);
@@ -2940,6 +2947,11 @@ elf_s390_relocate_section (output_bfd, i
 		}
 	      else
 		{
+		  /* If basr is used in the pic case to invoke
+		     _tls_get_offset, something went wrong before.  */
+		  if ((insn & 0xff000000) == 0x0d000000)
+		    invalid_tls_insn (input_bfd, input_section, rel);
+
 		  if ((insn & 0xff000000) == 0x4d000000)
 		    {
 		      /* GD->IE transition.
@@ -2966,9 +2978,17 @@ elf_s390_relocate_section (output_bfd, i
 
 		  insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
 		  if ((insn & 0xff000fff) != 0x4d000000 &&
-		      (insn & 0xffff0000) != 0xc0e50000)
+		      (insn & 0xffff0000) != 0xc0e50000 &&
+		      (insn & 0xff000000) != 0x0d000000)
 		    invalid_tls_insn (input_bfd, input_section, rel);
-		  if ((insn & 0xff000000) == 0x4d000000)
+
+		  if ((insn & 0xff000000) == 0x0d000000)
+		    {
+		      /* LD->LE transition.
+			 basr rx, ry -> nopr r7 */
+		      insn = 0x07070000 | (insn & 0xffff);
+		    }
+		  else if ((insn & 0xff000000) == 0x4d000000)
 		    {
 		      /* LD->LE transition.
 			 bas %r14,0(%rx,%r13) -> bc 0,0  */
@@ -2977,7 +2997,7 @@ elf_s390_relocate_section (output_bfd, i
 		  else
 		    {
 		      /* LD->LE transition.
-			 brasl %r14,__tls_get_addr@plt -> brcl 0,. */
+			 brasl %r14,__tls_get_offset@plt -> brcl 0,. */
 		      insn = 0xc0040000;
 		      bfd_put_16 (output_bfd, 0x0000,
 				  contents + rel->r_offset + 4);


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