powerpc __tls_get_addr call optimization

Alan Modra amodra@bigpond.net.au
Mon Mar 30 07:50:00 GMT 2009


This patch is the ld support for a PowerPC TLS optimization, inspired
by Alexandre Oliva's TLS optimization for other processors,
http://www.lsd.ic.unicamp.br/~oliva/writeups/TLS/RFC-TLSDESC-x86.txt
I do not fully implement Alex's feature set.  Lazy resolution of TLS
descriptors is not supported, nor is a new __tls_get_addr calling
sequence that saves all (most) of the registers.  I think lazy
resolution on top of what is implemented here is overkill and quite
likely will slow down real applications.  The new calling sequence
makes more sense;  I may implement that later.

So, what is this all about?  Don't gcc and ld already optimize TLS
sequences?  Well, yes, if given the right options, gcc will emit
local exec or initial exec TLS sequences for any TLS access in the
main executable, and ld will optimize any local or general dynamic
calls to __tls_get_addr in the main executable if the ideal options
are not passed to gcc.  That doesn't help dynamic libraries though,
since they may be dlopen'd and thus the address of their TLS variables
cannot be known until runtime.  (However, if you know your dynamic
library will never be dlopen'd then it may be compiled with
-mtls-model=initial-exec and so use optimal TLS sequences.)  This
optimization then, targets the __tls_get_addr calls in dynamic
libraries.  If glibc can be persuaded to allocate space for TLS
variables in the static TLS area, then their offsets from the thread
pointer are the same for all threads.  With a means to pass the
constant offset back to the library at runtime, some time can be saved
compared to calling __tls_get_addr.  Alex did this by hijacking the
TLS descriptor (two words, module id, offset pair) and using it as a
function pointer, arg pair.  If the TLS variable was allocated static
TLS space, then the function pointer is set to the address of a
function that just returns the arg word (plus thread pointer on some
architectures).  This is a little quicker than a __tls_get_addr call
simply because the function is doing less work.  I take the idea one
step further and dispense with the indirect function call, saving a
few more instructions on the fast path.  Instead, glibc will set the
module id in the descriptor to zero when the variable is allocated in
static TLS space, and the __tls_get_addr plt call stub is modified to
check for a zero modid.  On my G5 this results in a fast path
execution time of less than 55% of a __tls_get_addr call for ppc32,
and less than 50% for ppc64.  (I say less than because my timing
included some loop overhead.)  There is some impact on the slow path,
ie. when glibc ld.so could not allocate a variable in static TLS.
Slow path timing for pp32 is 108%, and ppc64 146%.  The larger ppc64
cost reflects the much larger stub, and also illustrates that
__tls_get_addr is quite fast to start with.

Another nice feature of this approach is that no compiler changes are
necessary, and we don't need to update binutils and glibc in
lockstep.  An older glibc will work fine with objects created by a new
ld, and vice versa.

I don't intend to commit this immediately as the patch isn't useful
until glibc support is available.

include/elf/
	* ppc.h (DT_PPC_TLSOPT): Define.
	* ppc64.h (DT_PPC64_TLSOPT): Define.
bfd/
	* elf32-ppc.c (TLS_GET_ADDR_GLINK_SIZE): Define.
	(ADD_3_12_2, BEQLR, CMPWI_11_0, LWZ_11_3, LWZ_12_3): Define.
	(MR_0_3, MR_3_0): Define.
	(struct ppc_elf_link_hash_table): Add no_tls_get_addr_opt.
	(ppc_elf_tls_setup): Add no_tls_get_addr_opt param and save to hash
	table.
	(allocate_dynrelocs): Increase glink entry size for __tls_get_addr.
	(ppc_elf_size_dynamic_sections): Add DT_PPC_TLS_OPT tag.
	(ppc_elf_finish_dynamic_symbol): Emit special glink call stub for
	__tls_get_addr.
	* elf32-ppc.h (ppc_elf_tls_setup): Update prototype.
	* elf64-ppc.c (struct ppc_link_hash_table): Add no_tls_get_addr_opt.
	(ppc64_elf_tls_setup): Add no_tls_get_addr_opt param and save to hash
	table.
	(ppc64_elf_size_dynamic_sections): Add DT_PPC64_TLS_OPT tag.
	(LD_R11_0R3, LD_R12_0R3, MR_R0_R3, CMPDI_R11_0, ADD_R3_R12_R13,
	BEQLR, MR_R3_R0, MFLR_R11, STD_R11_0R1, BCTRL, LD_R11_0R1,
	LD_R2_0R1, MTLR_R11): Define.
	(build_tls_get_addr_stub): New function.
	(ppc_build_one_stub): Call it.
	(ppc_size_one_stub): Add extra size for __tls_get_addr stub.
	(ppc64_elf_relocate_section): Don't change nop to ld 2,40(1) for
	__tls_get_addr plt call.
	* elf64-ppc.h (ppc64_elf_tls_setup): Update prototype.
ld/
	* emultempl/ppc32elf.em (no_tls_get_addr_opt): New var.
	(ppc_before_allocation): Pass to ppc_elf_tls_setup.
	(OPTION_NO_TLS_GET_ADDR_OPT): Define.  Redefine other options in
	terms of previous option.
	(PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS): Add
	--no-tls-get-addr-optimize.
	(PARSE_AND_LIST_ARGS_CASES): Handle it.
	* emultempl/ppc64elf.em (no_tls_get_addr_opt): New var.
	(ppc_before_allocation): Pass to ppc64_elf_tls_setup.
	(OPTION_NO_TLS_GET_ADDR_OPT): Define.
	(PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS): Add
	--no-tls-get-addr-optimize.
	(PARSE_AND_LIST_ARGS_CASES): Handle it.
ld/testsuite/
	* ld-powerpc/tlsexe.d: Update for new __tls_get_addr stub.
	* ld-powerpc/tlsexe.g, * ld-powerpc/tlsexe.r, * ld-powerpc/tlsexetoc.d,
	* ld-powerpc/tlsexetoc.g, * ld-powerpc/tlsexetoc.r,
	* ld-powerpc/tlsso.d, * ld-powerpc/tlsso.g, * ld-powerpc/tlsso.r,
	* ld-powerpc/tlstocso.d, * ld-powerpc/tlstocso.g: Likewise.

Index: include/elf/ppc.h
===================================================================
RCS file: /cvs/src/src/include/elf/ppc.h,v
retrieving revision 1.23
diff -u -p -r1.23 ppc.h
--- include/elf/ppc.h	4 Mar 2009 05:50:48 -0000	1.23
+++ include/elf/ppc.h	24 Mar 2009 03:06:22 -0000
@@ -148,7 +148,10 @@ END_RELOC_NUMBERS (R_PPC_max)
   ((R) >= R_PPC_TLS && (R) <= R_PPC_GOT_DTPREL16_HA)
 
 /* Specify the value of _GLOBAL_OFFSET_TABLE_.  */
-#define DT_PPC_GOT		DT_LOPROC
+#define DT_PPC_GOT		(DT_LOPROC)
+
+/* Specify that tls descriptors should be optimized.  */
+#define DT_PPC_TLSOPT		(DT_LOPROC + 1)
 
 /* Processor specific flags for the ELF header e_flags field.  */
 
Index: include/elf/ppc64.h
===================================================================
RCS file: /cvs/src/src/include/elf/ppc64.h,v
retrieving revision 1.5
diff -u -p -r1.5 ppc64.h
--- include/elf/ppc64.h	4 Mar 2009 05:50:48 -0000	1.5
+++ include/elf/ppc64.h	24 Mar 2009 03:06:22 -0000
@@ -155,4 +155,7 @@ END_RELOC_NUMBERS (R_PPC64_max)
 #define DT_PPC64_OPD		(DT_LOPROC + 1)
 #define DT_PPC64_OPDSZ		(DT_LOPROC + 2)
 
+/* Specify that tls descriptors should be optimized.  */
+#define DT_PPC64_TLSOPT		(DT_LOPROC + 3)
+
 #endif /* _ELF_PPC64_H */
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.253
diff -u -p -r1.253 elf32-ppc.c
--- bfd/elf32-ppc.c	21 Mar 2009 02:35:27 -0000	1.253
+++ bfd/elf32-ppc.c	24 Mar 2009 03:05:37 -0000
@@ -61,6 +61,7 @@ static bfd_reloc_status_type ppc_elf_unh
 /* For new-style .glink and .plt.  */
 #define GLINK_PLTRESOLVE 16*4
 #define GLINK_ENTRY_SIZE 4*4
+#define TLS_GET_ADDR_GLINK_SIZE 12*4
 
 /* VxWorks uses its own plt layout, filled in by the static linker.  */
 
@@ -135,17 +136,24 @@ static const bfd_vma ppc_elf_vxworks_pic
 #define ADDIS_12_12	0x3d8c0000
 #define ADDI_11_11	0x396b0000
 #define ADD_0_11_11	0x7c0b5a14
+#define ADD_3_12_2	0x7c6c1214
 #define ADD_11_0_11	0x7d605a14
 #define B		0x48000000
 #define BCL_20_31	0x429f0005
 #define BCTR		0x4e800420
+#define BEQLR		0x4d820020
+#define CMPWI_11_0	0x2c0b0000
 #define LIS_11		0x3d600000
 #define LIS_12		0x3d800000
 #define LWZU_0_12	0x840c0000
 #define LWZ_0_12	0x800c0000
+#define LWZ_11_3	0x81630000
 #define LWZ_11_11	0x816b0000
 #define LWZ_11_30	0x817e0000
+#define LWZ_12_3	0x81830000
 #define LWZ_12_12	0x818c0000
+#define MR_0_3		0x7c601b78
+#define MR_3_0		0x7c030378
 #define MFLR_0		0x7c0802a6
 #define MFLR_12		0x7d8802a6
 #define MTCTR_0		0x7c0903a6
@@ -2725,6 +2733,9 @@ struct ppc_elf_link_hash_table
   /* Set if we should emit symbols for stubs.  */
   unsigned int emit_stub_syms:1;
 
+  /* Set if __tls_get_addr optimization should not be done.  */
+  unsigned int no_tls_get_addr_opt:1;
+
   /* True if the target system is VxWorks.  */
   unsigned int is_vxworks:1;
 
@@ -4362,11 +4373,14 @@ ppc_elf_gc_sweep_hook (bfd *abfd,
    generic ELF tls_setup function.  */
 
 asection *
-ppc_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
+ppc_elf_tls_setup (bfd *obfd,
+		   struct bfd_link_info *info,
+		   int no_tls_get_addr_opt)
 {
   struct ppc_elf_link_hash_table *htab;
 
   htab = ppc_elf_hash_table (info);
+  htab->no_tls_get_addr_opt = no_tls_get_addr_opt;
   if (htab->plt_type == PLT_NEW
       && htab->plt != NULL
       && htab->plt->output_section != NULL)
@@ -4959,6 +4973,9 @@ allocate_dynrelocs (struct elf_link_hash
 		      {
 			glink_offset = s->size;
 			s->size += GLINK_ENTRY_SIZE;
+			if (h == htab->tls_get_addr
+			    && !htab->no_tls_get_addr_opt)
+			  s->size += TLS_GET_ADDR_GLINK_SIZE - GLINK_ENTRY_SIZE;
 		      }
 		    if (!doneone
 			&& !info->shared
@@ -5561,6 +5578,11 @@ ppc_elf_size_dynamic_sections (bfd *outp
 	{
 	  if (!add_dynamic_entry (DT_PPC_GOT, 0))
 	    return FALSE;
+	  if (!htab->no_tls_get_addr_opt
+	      && htab->tls_get_addr != NULL
+	      && htab->tls_get_addr->plt.plist != NULL
+	      && !add_dynamic_entry (DT_PPC_TLSOPT, 0))
+	    return FALSE;
 	}
 
       if (relocs)
@@ -7698,6 +7720,26 @@ ppc_elf_finish_dynamic_symbol (bfd *outp
 		   + htab->plt->output_offset);
 	    p = (unsigned char *) htab->glink->contents + ent->glink_offset;
 
+	    if (h == htab->tls_get_addr && !htab->no_tls_get_addr_opt)
+	      {
+		bfd_put_32 (output_bfd, LWZ_11_3, p);
+		p += 4;
+		bfd_put_32 (output_bfd, LWZ_12_3 + 4, p);
+		p += 4;
+		bfd_put_32 (output_bfd, MR_0_3, p);
+		p += 4;
+		bfd_put_32 (output_bfd, CMPWI_11_0, p);
+		p += 4;
+		bfd_put_32 (output_bfd, ADD_3_12_2, p);
+		p += 4;
+		bfd_put_32 (output_bfd, BEQLR, p);
+		p += 4;
+		bfd_put_32 (output_bfd, MR_3_0, p);
+		p += 4;
+		bfd_put_32 (output_bfd, NOP, p);
+		p += 4;
+	      }
+
 	    if (info->shared || info->pie)
 	      {
 		bfd_vma got = 0;
Index: bfd/elf32-ppc.h
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.h,v
retrieving revision 1.11
diff -u -p -r1.11 elf32-ppc.h
--- bfd/elf32-ppc.h	3 Jul 2007 14:26:41 -0000	1.11
+++ bfd/elf32-ppc.h	24 Mar 2009 03:05:37 -0000
@@ -28,6 +28,6 @@ enum ppc_elf_plt_type
 
 int ppc_elf_select_plt_layout (bfd *, struct bfd_link_info *,
 			       enum ppc_elf_plt_type, int);
-asection *ppc_elf_tls_setup (bfd *, struct bfd_link_info *);
+asection *ppc_elf_tls_setup (bfd *, struct bfd_link_info *, int);
 bfd_boolean ppc_elf_tls_optimize (bfd *, struct bfd_link_info *);
 void ppc_elf_set_sdata_syms (bfd *, struct bfd_link_info *);
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.293
diff -u -p -r1.293 elf64-ppc.c
--- bfd/elf64-ppc.c	23 Mar 2009 13:35:46 -0000	1.293
+++ bfd/elf64-ppc.c	24 Mar 2009 03:05:45 -0000
@@ -3651,6 +3651,9 @@ struct ppc_link_hash_table
   /* Set if we should emit symbols for stubs.  */
   unsigned int emit_stub_syms:1;
 
+  /* Set if __tls_get_addr optimization should not be done.  */
+  unsigned int no_tls_get_addr_opt:1;
+
   /* Support for multiple toc sections.  */
   unsigned int no_multi_toc:1;
   unsigned int multi_toc_needed:1;
@@ -6932,11 +6935,14 @@ ppc64_elf_edit_opd (bfd *obfd, struct bf
 /* Set htab->tls_get_addr and call the generic ELF tls_setup function.  */
 
 asection *
-ppc64_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
+ppc64_elf_tls_setup (bfd *obfd,
+		     struct bfd_link_info *info,
+		     int no_tls_get_addr_opt)
 {
   struct ppc_link_hash_table *htab;
 
   htab = ppc_hash_table (info);
+  htab->no_tls_get_addr_opt = no_tls_get_addr_opt;
   htab->tls_get_addr = ((struct ppc_link_hash_entry *)
 			elf_link_hash_lookup (&htab->elf, ".__tls_get_addr",
 					      FALSE, FALSE, TRUE));
@@ -8342,6 +8348,12 @@ ppc64_elf_size_dynamic_sections (bfd *ou
 	    return FALSE;
 	}
 
+      if (!htab->no_tls_get_addr_opt
+	  && htab->tls_get_addr_fd != NULL
+	  && htab->tls_get_addr_fd->elf.plt.plist != NULL
+	  && !add_dynamic_entry (DT_PPC64_TLSOPT, 0))
+	return FALSE;
+
       if (relocs)
 	{
 	  if (!add_dynamic_entry (DT_RELA, 0)
@@ -8517,6 +8529,49 @@ build_plt_stub (bfd *obfd, bfd_byte *p, 
   return p;
 }
 
+/* Build a special .plt call stub for __tls_get_addr.  */
+
+#define LD_R11_0R3	0xe9630000
+#define LD_R12_0R3	0xe9830000
+#define MR_R0_R3	0x7c601b78
+#define CMPDI_R11_0	0x2c2b0000
+#define ADD_R3_R12_R13	0x7c6c6a14
+#define BEQLR		0x4d820020
+#define MR_R3_R0	0x7c030378
+#define MFLR_R11	0x7d6802a6
+#define STD_R11_0R1	0xf9610000
+#define BCTRL		0x4e800421
+#define LD_R11_0R1	0xe9610000
+#define LD_R2_0R1	0xe8410000
+#define MTLR_R11	0x7d6803a6
+
+static inline bfd_byte *
+build_tls_get_addr_stub (bfd *obfd, bfd_byte *p, int offset,
+			 Elf_Internal_Rela *r)
+{
+  bfd_put_32 (obfd, LD_R11_0R3 + 0, p),		p += 4;
+  bfd_put_32 (obfd, LD_R12_0R3 + 8, p),		p += 4;
+  bfd_put_32 (obfd, MR_R0_R3, p),		p += 4;
+  bfd_put_32 (obfd, CMPDI_R11_0, p),		p += 4;
+  bfd_put_32 (obfd, ADD_R3_R12_R13, p),		p += 4;
+  bfd_put_32 (obfd, BEQLR, p),			p += 4;
+  bfd_put_32 (obfd, MR_R3_R0, p),		p += 4;
+  bfd_put_32 (obfd, MFLR_R11, p),		p += 4;
+  bfd_put_32 (obfd, STD_R11_0R1 + 32, p),	p += 4;
+
+  if (r != NULL)
+    r[0].r_offset += 9 * 4;
+  p = build_plt_stub (obfd, p, offset, r);
+  bfd_put_32 (obfd, BCTRL, p - 4);
+
+  bfd_put_32 (obfd, LD_R11_0R1 + 32, p),	p += 4;
+  bfd_put_32 (obfd, LD_R2_0R1 + 40, p),		p += 4;
+  bfd_put_32 (obfd, MTLR_R11, p),		p += 4;
+  bfd_put_32 (obfd, BLR, p),			p += 4;
+
+  return p;
+}
+
 static Elf_Internal_Rela *
 get_relocs (asection *sec, int count)
 {
@@ -8867,7 +8922,12 @@ ppc_build_one_stub (struct bfd_hash_entr
 	    r[0].r_offset += 2;
 	  r[0].r_addend = dest;
 	}
-      p = build_plt_stub (htab->stub_bfd, loc, off, r);
+      if ((stub_entry->h == htab->tls_get_addr_fd
+	   || stub_entry->h == htab->tls_get_addr)
+	  && !htab->no_tls_get_addr_opt)
+	p = build_tls_get_addr_stub (htab->stub_bfd, loc, off, r);
+      else
+	p = build_plt_stub (htab->stub_bfd, loc, off, r);
       size = p - loc;
       break;
 
@@ -8957,6 +9017,10 @@ ppc_size_one_stub (struct bfd_hash_entry
 	size -= 4;
       if (PPC_HA (off + 16) != PPC_HA (off))
 	size += 4;
+      if ((stub_entry->h == htab->tls_get_addr_fd
+	   || stub_entry->h == htab->tls_get_addr)
+	  && !htab->no_tls_get_addr_opt)
+	size += 13 * 4;
       if (info->emitrelocations)
 	{
 	  stub_entry->stub_sec->reloc_count
@@ -10875,8 +10939,15 @@ ppc64_elf_relocate_section (bfd *output_
 		  if (nop == NOP
 		      || nop == CROR_151515 || nop == CROR_313131)
 		    {
-		      bfd_put_32 (input_bfd, LD_R2_40R1,
-				  contents + rel->r_offset + 4);
+		      if ((h == htab->tls_get_addr_fd
+			   || h == htab->tls_get_addr)
+			  && !htab->no_tls_get_addr_opt)
+			{
+			  /* Special stub used, leave nop alone.  */
+			}
+		      else
+			bfd_put_32 (input_bfd, LD_R2_40R1,
+				    contents + rel->r_offset + 4);
 		      can_plt_call = TRUE;
 		    }
 		}
Index: bfd/elf64-ppc.h
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.h,v
retrieving revision 1.25
diff -u -p -r1.25 elf64-ppc.h
--- bfd/elf64-ppc.h	15 Jan 2008 07:25:49 -0000	1.25
+++ bfd/elf64-ppc.h	24 Mar 2009 03:05:45 -0000
@@ -24,7 +24,7 @@ void ppc64_elf_init_stub_bfd
 bfd_boolean ppc64_elf_edit_opd
   (bfd *, struct bfd_link_info *, bfd_boolean);
 asection *ppc64_elf_tls_setup
-  (bfd *, struct bfd_link_info *);
+(bfd *, struct bfd_link_info *, int);
 bfd_boolean ppc64_elf_tls_optimize
   (bfd *, struct bfd_link_info *);
 bfd_boolean ppc64_elf_edit_toc
Index: ld/emultempl/ppc32elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/ppc32elf.em,v
retrieving revision 1.18
diff -u -p -r1.18 ppc32elf.em
--- ld/emultempl/ppc32elf.em	15 Feb 2008 09:03:02 -0000	1.18
+++ ld/emultempl/ppc32elf.em	24 Mar 2009 03:06:23 -0000
@@ -33,6 +33,7 @@ fragment <<EOF
 
 /* Whether to run tls optimization.  */
 static int notlsopt = 0;
+static int no_tls_get_addr_opt = 0;
 
 /* Whether to emit symbols for stubs.  */
 static int emit_stub_syms = 0;
@@ -103,7 +104,9 @@ ppc_before_allocation (void)
 {
   if (is_ppc_elf (link_info.output_bfd))
     {
-      if (ppc_elf_tls_setup (link_info.output_bfd, &link_info) && !notlsopt)
+      if (ppc_elf_tls_setup (link_info.output_bfd, &link_info,
+			     no_tls_get_addr_opt)
+	  && !notlsopt)
 	{
 	  if (!ppc_elf_tls_optimize (link_info.output_bfd, &link_info))
 	    {
@@ -141,15 +144,17 @@ fi
 #
 PARSE_AND_LIST_PROLOGUE='
 #define OPTION_NO_TLS_OPT		301
-#define OPTION_NEW_PLT			302
-#define OPTION_OLD_PLT			303
-#define OPTION_OLD_GOT			304
-#define OPTION_STUBSYMS			305
+#define OPTION_NO_TLS_GET_ADDR_OPT	(OPTION_NO_TLS_OPT + 1)
+#define OPTION_NEW_PLT			(OPTION_NO_TLS_GET_ADDR_OPT + 1)
+#define OPTION_OLD_PLT			(OPTION_NEW_PLT + 1)
+#define OPTION_OLD_GOT			(OPTION_OLD_PLT + 1)
+#define OPTION_STUBSYMS			(OPTION_OLD_GOT + 1)
 '
 
 PARSE_AND_LIST_LONGOPTS='
   { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
   { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
+  { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },
   { "secure-plt", no_argument, NULL, OPTION_NEW_PLT },
   { "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
   { "sdata-got", no_argument, NULL, OPTION_OLD_GOT },
@@ -159,6 +164,7 @@ PARSE_AND_LIST_OPTIONS='
   fprintf (file, _("\
   --emit-stub-syms            Label linker stubs with a symbol.\n\
   --no-tls-optimize           Don'\''t try to optimize TLS accesses.\n\
+  --no-tls-get-addr-optimize  Don'\''t use a special __tls_get_addr call.\n\
   --secure-plt                Use new-style PLT if possible.\n\
   --bss-plt                   Force old-style BSS PLT.\n\
   --sdata-got                 Force GOT location just before .sdata.\n"
@@ -174,6 +180,10 @@ PARSE_AND_LIST_ARGS_CASES='
       notlsopt = 1;
       break;
 
+    case OPTION_NO_TLS_GET_ADDR_OPT:
+      no_tls_get_addr_opt = 1;
+      break;
+
     case OPTION_NEW_PLT:
       plt_style = PLT_NEW;
       break;
Index: ld/emultempl/ppc64elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/ppc64elf.em,v
retrieving revision 1.61
diff -u -p -r1.61 ppc64elf.em
--- ld/emultempl/ppc64elf.em	26 Nov 2008 01:04:17 -0000	1.61
+++ ld/emultempl/ppc64elf.em	24 Mar 2009 03:06:24 -0000
@@ -47,6 +47,7 @@ static int dotsyms = 1;
 
 /* Whether to run tls optimization.  */
 static int no_tls_opt = 0;
+static int no_tls_get_addr_opt = 0;
 
 /* Whether to run opd optimization.  */
 static int no_opd_opt = 0;
@@ -106,7 +107,8 @@ ppc_before_allocation (void)
 				  non_overlapping_opd))
 	einfo ("%X%P: can not edit %s %E\n", "opd");
 
-      if (ppc64_elf_tls_setup (link_info.output_bfd, &link_info)
+      if (ppc64_elf_tls_setup (link_info.output_bfd, &link_info,
+			       no_tls_get_addr_opt)
 	  && !no_tls_opt)
 	{
 	  /* Size the sections.  This is premature, but we want to know the
@@ -481,7 +483,8 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_DOTSYMS			(OPTION_STUBSYMS + 1)
 #define OPTION_NO_DOTSYMS		(OPTION_DOTSYMS + 1)
 #define OPTION_NO_TLS_OPT		(OPTION_NO_DOTSYMS + 1)
-#define OPTION_NO_OPD_OPT		(OPTION_NO_TLS_OPT + 1)
+#define OPTION_NO_TLS_GET_ADDR_OPT	(OPTION_NO_TLS_OPT + 1)
+#define OPTION_NO_OPD_OPT		(OPTION_NO_TLS_GET_ADDR_OPT + 1)
 #define OPTION_NO_TOC_OPT		(OPTION_NO_OPD_OPT + 1)
 #define OPTION_NO_MULTI_TOC		(OPTION_NO_TOC_OPT + 1)
 #define OPTION_NON_OVERLAPPING_OPD	(OPTION_NO_MULTI_TOC + 1)
@@ -493,6 +496,7 @@ PARSE_AND_LIST_LONGOPTS='
   { "dotsyms", no_argument, NULL, OPTION_DOTSYMS },
   { "no-dotsyms", no_argument, NULL, OPTION_NO_DOTSYMS },
   { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
+  { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },
   { "no-opd-optimize", no_argument, NULL, OPTION_NO_OPD_OPT },
   { "no-toc-optimize", no_argument, NULL, OPTION_NO_TOC_OPT },
   { "no-multi-toc", no_argument, NULL, OPTION_NO_MULTI_TOC },
@@ -526,6 +530,9 @@ PARSE_AND_LIST_OPTIONS='
   --no-tls-optimize           Don'\''t try to optimize TLS accesses.\n"
 		   ));
   fprintf (file, _("\
+  --no-tls-get-addr-optimize  Don'\''t use a special __tls_get_addr call.\n"
+		   ));
+  fprintf (file, _("\
   --no-opd-optimize           Don'\''t optimize the OPD section.\n"
 		   ));
   fprintf (file, _("\
@@ -566,6 +573,10 @@ PARSE_AND_LIST_ARGS_CASES='
       no_tls_opt = 1;
       break;
 
+    case OPTION_NO_TLS_GET_ADDR_OPT:
+      no_tls_get_addr_opt = 1;
+      break;
+
     case OPTION_NO_OPD_OPT:
       no_opd_opt = 1;
       break;
Index: ld/testsuite/ld-powerpc/tlsexe.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe.d,v
retrieving revision 1.7
diff -u -p -r1.7 tlsexe.d
--- ld/testsuite/ld-powerpc/tlsexe.d	13 Aug 2007 00:20:59 -0000	1.7
+++ ld/testsuite/ld-powerpc/tlsexe.d	24 Mar 2009 03:06:26 -0000
@@ -8,21 +8,34 @@
 
 Disassembly of section \.text:
 
-.* <_start-0x18>:
+.* <_start-0x4c>:
+.*	e9 63 00 00 	ld      r11,0\(r3\)
+.*	e9 83 00 08 	ld      r12,8\(r3\)
+.*	7c 60 1b 78 	mr      r0,r3
+.*	2c 2b 00 00 	cmpdi   r11,0
+.*	7c 6c 6a 14 	add     r3,r12,r13
+.*	4d 82 00 20 	beqlr   
+.*	7c 03 03 78 	mr      r3,r0
+.*	7d 68 02 a6 	mflr    r11
+.*	f9 61 00 20 	std     r11,32\(r1\)
 .*	f8 41 00 28 	std     r2,40\(r1\)
 .*	e9 62 80 48 	ld      r11,-32696\(r2\)
 .*	7d 69 03 a6 	mtctr   r11
 .*	e9 62 80 58 	ld      r11,-32680\(r2\)
 .*	e8 42 80 50 	ld      r2,-32688\(r2\)
-.*	4e 80 04 20 	bctr
+.*	4e 80 04 21 	bctrl
+.*	e9 61 00 20 	ld      r11,32\(r1\)
+.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	7d 68 03 a6 	mtlr    r11
+.*	4e 80 00 20 	blr
 
 .* <_start>:
 .*	e8 62 80 10 	ld      r3,-32752\(r2\)
 .*	60 00 00 00 	nop
 .*	7c 63 6a 14 	add     r3,r3,r13
 .*	38 62 80 18 	addi    r3,r2,-32744
-.*	4b ff ff d9 	bl      .*
-.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	4b ff ff a5 	bl      .*
+.*	60 00 00 00 	nop
 .*	3c 6d 00 00 	addis   r3,r13,0
 .*	60 00 00 00 	nop
 .*	38 63 90 38 	addi    r3,r3,-28616
@@ -55,8 +68,9 @@ Disassembly of section \.text:
 .*	e9 4d 90 2a 	lwa     r10,-28632\(r13\)
 .*	3d 2d 00 00 	addis   r9,r13,0
 .*	a9 49 90 30 	lha     r10,-28624\(r9\)
+.*	60 00 00 00 	nop
 .*	00 00 00 00 .*
-.*	00 01 01 f0 .*
+.*	00 01 02 00 .*
 .*	7d 88 02 a6 	mflr    r12
 .*	42 9f 00 05 	bcl-    20,4\*cr7\+so,.*
 .*	7d 68 02 a6 	mflr    r11
Index: ld/testsuite/ld-powerpc/tlsexe.g
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe.g,v
retrieving revision 1.7
diff -u -p -r1.7 tlsexe.g
--- ld/testsuite/ld-powerpc/tlsexe.g	13 Aug 2007 00:20:59 -0000	1.7
+++ ld/testsuite/ld-powerpc/tlsexe.g	24 Mar 2009 03:06:26 -0000
@@ -7,6 +7,6 @@
 .*: +file format elf64-powerpc
 
 Contents of section \.got:
-.* 00000000 100185c8 ffffffff ffff8018  .*
+.* 00000000 10018610 ffffffff ffff8018  .*
 .* 00000000 00000000 00000000 00000000  .*
 .* 00000000 00000000 00000000 00000000  .*
Index: ld/testsuite/ld-powerpc/tlsexe.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe.r,v
retrieving revision 1.21
diff -u -p -r1.21 tlsexe.r
--- ld/testsuite/ld-powerpc/tlsexe.r	30 Sep 2007 01:33:15 -0000	1.21
+++ ld/testsuite/ld-powerpc/tlsexe.r	24 Mar 2009 03:06:26 -0000
@@ -16,10 +16,10 @@ Section Headers:
  +\[[ 0-9]+\] \.dynstr +.*
  +\[[ 0-9]+\] \.rela\.dyn +.*
  +\[[ 0-9]+\] \.rela\.plt +.*
- +\[[ 0-9]+\] \.text +PROGBITS .* 0+f8 0+ +AX +0 +0 +8
+ +\[[ 0-9]+\] \.text +PROGBITS .* 0+130 0+ +AX +0 +0 +8
  +\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
  +\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
- +\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+150 10 +WA +4 +0 +8
+ +\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+160 10 +WA +4 +0 +8
  +\[[ 0-9]+\] \.branch_lt + PROGBITS .* 0+ 0+ +WA +0 +0 +8
  +\[[ 0-9]+\] \.got +PROGBITS .* 0+30 08 +WA +0 +0 +8
  +\[[ 0-9]+\] \.plt +.*
Index: ld/testsuite/ld-powerpc/tlsexetoc.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexetoc.d,v
retrieving revision 1.8
diff -u -p -r1.8 tlsexetoc.d
--- ld/testsuite/ld-powerpc/tlsexetoc.d	13 Aug 2007 00:20:59 -0000	1.8
+++ ld/testsuite/ld-powerpc/tlsexetoc.d	24 Mar 2009 03:06:26 -0000
@@ -8,21 +8,34 @@
 
 Disassembly of section \.text:
 
-.* <_start-0x18>:
+.* <_start-0x4c>:
+.*	e9 63 00 00 	ld      r11,0\(r3\)
+.*	e9 83 00 08 	ld      r12,8\(r3\)
+.*	7c 60 1b 78 	mr      r0,r3
+.*	2c 2b 00 00 	cmpdi   r11,0
+.*	7c 6c 6a 14 	add     r3,r12,r13
+.*	4d 82 00 20 	beqlr   
+.*	7c 03 03 78 	mr      r3,r0
+.*	7d 68 02 a6 	mflr    r11
+.*	f9 61 00 20 	std     r11,32\(r1\)
 .*	f8 41 00 28 	std     r2,40\(r1\)
 .*	e9 62 80 70 	ld      r11,-32656\(r2\)
 .*	7d 69 03 a6 	mtctr   r11
 .*	e9 62 80 80 	ld      r11,-32640\(r2\)
 .*	e8 42 80 78 	ld      r2,-32648\(r2\)
-.*	4e 80 04 20 	bctr
+.*	4e 80 04 21 	bctrl
+.*	e9 61 00 20 	ld      r11,32\(r1\)
+.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	7d 68 03 a6 	mtlr    r11
+.*	4e 80 00 20 	blr
 
 .* <_start>:
 .*	38 62 80 08 	addi    r3,r2,-32760
-.*	4b ff ff e5 	bl      .*
-.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	4b ff ff b1 	bl      .*
+.*	60 00 00 00 	nop
 .*	38 62 80 18 	addi    r3,r2,-32744
-.*	4b ff ff d9 	bl      .*
-.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	4b ff ff a5 	bl      .*
+.*	60 00 00 00 	nop
 .*	3c 6d 00 00 	addis   r3,r13,0
 .*	60 00 00 00 	nop
 .*	38 63 90 38 	addi    r3,r3,-28616
@@ -39,8 +52,9 @@ Disassembly of section \.text:
 .*	89 4d 90 60 	lbz     r10,-28576\(r13\)
 .*	3d 2d 00 00 	addis   r9,r13,0
 .*	99 49 90 68 	stb     r10,-28568\(r9\)
+.*	60 00 00 00 	nop
 .*	00 00 00 00 .*
-.*	00 01 02 18 .*
+.*	00 01 02 28 .*
 .*	7d 88 02 a6 	mflr    r12
 .*	42 9f 00 05 	bcl-    20,4\*cr7\+so,.*
 .*	7d 68 02 a6 	mflr    r11
Index: ld/testsuite/ld-powerpc/tlsexetoc.g
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexetoc.g,v
retrieving revision 1.7
diff -u -p -r1.7 tlsexetoc.g
--- ld/testsuite/ld-powerpc/tlsexetoc.g	13 Aug 2007 00:20:59 -0000	1.7
+++ ld/testsuite/ld-powerpc/tlsexetoc.g	24 Mar 2009 03:06:26 -0000
@@ -7,7 +7,7 @@
 .*: +file format elf64-powerpc
 
 Contents of section \.got:
-.* 00000000 10018568 00000000 00000000  .*
+.* 00000000 100185b0 00000000 00000000  .*
 .* 00000000 00000000 00000000 00000000  .*
 .* 00000000 00000000 00000000 00000001  .*
 .* 00000000 00000000 00000000 00000001  .*
Index: ld/testsuite/ld-powerpc/tlsexetoc.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexetoc.r,v
retrieving revision 1.22
diff -u -p -r1.22 tlsexetoc.r
--- ld/testsuite/ld-powerpc/tlsexetoc.r	30 Sep 2007 01:33:15 -0000	1.22
+++ ld/testsuite/ld-powerpc/tlsexetoc.r	24 Mar 2009 03:06:26 -0000
@@ -16,10 +16,10 @@ Section Headers:
  +\[[ 0-9]+\] \.dynstr +.*
  +\[[ 0-9]+\] \.rela\.dyn +.*
  +\[[ 0-9]+\] \.rela\.plt +.*
- +\[[ 0-9]+\] \.text +PROGBITS .* 0+b8 0+ +AX +0 +0 +8
+ +\[[ 0-9]+\] \.text +PROGBITS .* 0+f0 0+ +AX +0 +0 +8
  +\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
  +\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
- +\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+150 10 +WA +4 +0 +8
+ +\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+160 10 +WA +4 +0 +8
  +\[[ 0-9]+\] \.branch_lt +PROGBITS .* 0+ 0+ +WA +0 +0 +8
  +\[[ 0-9]+\] \.got +PROGBITS .* 0+58 08 +WA +0 +0 +8
  +\[[ 0-9]+\] \.plt +.*
Index: ld/testsuite/ld-powerpc/tlsso.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsso.d,v
retrieving revision 1.7
diff -u -p -r1.7 tlsso.d
--- ld/testsuite/ld-powerpc/tlsso.d	6 Nov 2007 13:49:19 -0000	1.7
+++ ld/testsuite/ld-powerpc/tlsso.d	24 Mar 2009 03:06:26 -0000
@@ -9,26 +9,39 @@
 Disassembly of section \.text:
 
 .* <\.__tls_get_addr>:
+.*	e9 63 00 00 	ld      r11,0\(r3\)
+.*	e9 83 00 08 	ld      r12,8\(r3\)
+.*	7c 60 1b 78 	mr      r0,r3
+.*	2c 2b 00 00 	cmpdi   r11,0
+.*	7c 6c 6a 14 	add     r3,r12,r13
+.*	4d 82 00 20 	beqlr   
+.*	7c 03 03 78 	mr      r3,r0
+.*	7d 68 02 a6 	mflr    r11
+.*	f9 61 00 20 	std     r11,32\(r1\)
 .*	f8 41 00 28 	std     r2,40\(r1\)
 .*	e9 62 80 78 	ld      r11,-32648\(r2\)
 .*	7d 69 03 a6 	mtctr   r11
 .*	e9 62 80 88 	ld      r11,-32632\(r2\)
 .*	e8 42 80 80 	ld      r2,-32640\(r2\)
-.*	4e 80 04 20 	bctr
+.*	4e 80 04 21 	bctrl
+.*	e9 61 00 20 	ld      r11,32\(r1\)
+.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	7d 68 03 a6 	mtlr    r11
+.*	4e 80 00 20 	blr
 
 .* <_start>:
 .*	38 62 80 20 	addi    r3,r2,-32736
-.*	4b ff ff e5 	bl      .* <\.__tls_get_addr>
-.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	4b ff ff b1 	bl      .* <\.__tls_get_addr>
+.*	60 00 00 00 	nop
 .*	38 62 80 50 	addi    r3,r2,-32688
-.*	4b ff ff d9 	bl      .* <\.__tls_get_addr>
-.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	4b ff ff a5 	bl      .* <\.__tls_get_addr>
+.*	60 00 00 00 	nop
 .*	38 62 80 38 	addi    r3,r2,-32712
-.*	4b ff ff cd 	bl      .* <\.__tls_get_addr>
-.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	4b ff ff 99 	bl      .* <\.__tls_get_addr>
+.*	60 00 00 00 	nop
 .*	38 62 80 50 	addi    r3,r2,-32688
-.*	4b ff ff c1 	bl      .* <\.__tls_get_addr>
-.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	4b ff ff 8d 	bl      .* <\.__tls_get_addr>
+.*	60 00 00 00 	nop
 .*	39 23 80 40 	addi    r9,r3,-32704
 .*	3d 23 00 00 	addis   r9,r3,0
 .*	81 49 80 48 	lwz     r10,-32696\(r9\)
@@ -40,11 +53,11 @@ Disassembly of section \.text:
 .*	3d 2d 00 00 	addis   r9,r13,0
 .*	99 49 00 00 	stb     r10,0\(r9\)
 .*	38 62 80 08 	addi    r3,r2,-32760
-.*	4b ff ff 8d 	bl      .* <\.__tls_get_addr>
-.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	4b ff ff 59 	bl      .* <\.__tls_get_addr>
+.*	60 00 00 00 	nop
 .*	38 62 80 50 	addi    r3,r2,-32688
-.*	4b ff ff 81 	bl      .* <\.__tls_get_addr>
-.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	4b ff ff 4d 	bl      .* <\.__tls_get_addr>
+.*	60 00 00 00 	nop
 .*	f9 43 80 08 	std     r10,-32760\(r3\)
 .*	3d 23 00 00 	addis   r9,r3,0
 .*	91 49 80 10 	stw     r10,-32752\(r9\)
@@ -55,8 +68,9 @@ Disassembly of section \.text:
 .*	e9 4d 00 02 	lwa     r10,0\(r13\)
 .*	3d 2d 00 00 	addis   r9,r13,0
 .*	a9 49 00 00 	lha     r10,0\(r9\)
+.*	60 00 00 00 	nop
 .*	00 00 00 00 .*
-.*	00 01 02 20 .*
+.*	00 01 02 30 .*
 .*	7d 88 02 a6 	mflr    r12
 .*	42 9f 00 05 	bcl-    20,4\*cr7\+so,.*
 .*	7d 68 02 a6 	mflr    r11
Index: ld/testsuite/ld-powerpc/tlsso.g
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsso.g,v
retrieving revision 1.8
diff -u -p -r1.8 tlsso.g
--- ld/testsuite/ld-powerpc/tlsso.g	13 Aug 2007 00:20:59 -0000	1.8
+++ ld/testsuite/ld-powerpc/tlsso.g	24 Mar 2009 03:06:26 -0000
@@ -7,7 +7,7 @@
 .*: +file format elf64-powerpc
 
 Contents of section \.got:
-.* 00000000 00018778 00000000 00000000  .*
+.* 00000000 000187c0 00000000 00000000  .*
 .* 00000000 00000000 00000000 00000000  .*
 .* 00000000 00000000 00000000 00000000  .*
 .* 00000000 00000000 00000000 00000000  .*
Index: ld/testsuite/ld-powerpc/tlsso.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsso.r,v
retrieving revision 1.22
diff -u -p -r1.22 tlsso.r
--- ld/testsuite/ld-powerpc/tlsso.r	6 Nov 2007 13:49:19 -0000	1.22
+++ ld/testsuite/ld-powerpc/tlsso.r	24 Mar 2009 03:06:26 -0000
@@ -49,9 +49,9 @@ Relocation section '\.rela\.dyn' at offs
 [0-9a-f ]+R_PPC64_TPREL16 +0+60 le0 \+ 0
 [0-9a-f ]+R_PPC64_TPREL16_HA +0+68 le1 \+ 0
 [0-9a-f ]+R_PPC64_TPREL16_LO +0+68 le1 \+ 0
-[0-9a-f ]+R_PPC64_TPREL16_DS +0+105f0 \.tdata \+ 28
-[0-9a-f ]+R_PPC64_TPREL16_HA +0+105f0 \.tdata \+ 30
-[0-9a-f ]+R_PPC64_TPREL16_LO +0+105f0 \.tdata \+ 30
+[0-9a-f ]+R_PPC64_TPREL16_DS +0+10628 \.tdata \+ 28
+[0-9a-f ]+R_PPC64_TPREL16_HA +0+10628 \.tdata \+ 30
+[0-9a-f ]+R_PPC64_TPREL16_LO +0+10628 \.tdata \+ 30
 [0-9a-f ]+R_PPC64_DTPMOD64 +0+
 [0-9a-f ]+R_PPC64_DTPREL64 +0+
 [0-9a-f ]+R_PPC64_DTPREL64 +0+18
Index: ld/testsuite/ld-powerpc/tlstocso.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlstocso.d,v
retrieving revision 1.6
diff -u -p -r1.6 tlstocso.d
--- ld/testsuite/ld-powerpc/tlstocso.d	13 Aug 2007 00:20:59 -0000	1.6
+++ ld/testsuite/ld-powerpc/tlstocso.d	24 Mar 2009 03:06:26 -0000
@@ -9,26 +9,39 @@
 Disassembly of section \.text:
 
 .* <\.__tls_get_addr>:
+.*	e9 63 00 00 	ld      r11,0\(r3\)
+.*	e9 83 00 08 	ld      r12,8\(r3\)
+.*	7c 60 1b 78 	mr      r0,r3
+.*	2c 2b 00 00 	cmpdi   r11,0
+.*	7c 6c 6a 14 	add     r3,r12,r13
+.*	4d 82 00 20 	beqlr   
+.*	7c 03 03 78 	mr      r3,r0
+.*	7d 68 02 a6 	mflr    r11
+.*	f9 61 00 20 	std     r11,32\(r1\)
 .*	f8 41 00 28 	std     r2,40\(r1\)
 .*	e9 62 80 70 	ld      r11,-32656\(r2\)
 .*	7d 69 03 a6 	mtctr   r11
 .*	e9 62 80 80 	ld      r11,-32640\(r2\)
 .*	e8 42 80 78 	ld      r2,-32648\(r2\)
-.*	4e 80 04 20 	bctr
+.*	4e 80 04 21 	bctrl
+.*	e9 61 00 20 	ld      r11,32\(r1\)
+.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	7d 68 03 a6 	mtlr    r11
+.*	4e 80 00 20 	blr
 
 .* <_start>:
 .*	38 62 80 08 	addi    r3,r2,-32760
-.*	4b ff ff e5 	bl      .* <\.__tls_get_addr>
-.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	4b ff ff b1 	bl      .* <\.__tls_get_addr>
+.*	60 00 00 00 	nop
 .*	38 62 80 18 	addi    r3,r2,-32744
-.*	4b ff ff d9 	bl      .* <\.__tls_get_addr>
-.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	4b ff ff a5 	bl      .* <\.__tls_get_addr>
+.*	60 00 00 00 	nop
 .*	38 62 80 28 	addi    r3,r2,-32728
-.*	4b ff ff cd 	bl      .* <\.__tls_get_addr>
-.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	4b ff ff 99 	bl      .* <\.__tls_get_addr>
+.*	60 00 00 00 	nop
 .*	38 62 80 38 	addi    r3,r2,-32712
-.*	4b ff ff c1 	bl      .* <\.__tls_get_addr>
-.*	e8 41 00 28 	ld      r2,40\(r1\)
+.*	4b ff ff 8d 	bl      .* <\.__tls_get_addr>
+.*	60 00 00 00 	nop
 .*	39 23 80 40 	addi    r9,r3,-32704
 .*	3d 23 00 00 	addis   r9,r3,0
 .*	81 49 80 48 	lwz     r10,-32696\(r9\)
@@ -39,8 +52,9 @@ Disassembly of section \.text:
 .*	89 4d 00 00 	lbz     r10,0\(r13\)
 .*	3d 2d 00 00 	addis   r9,r13,0
 .*	99 49 00 00 	stb     r10,0\(r9\)
+.*	60 00 00 00 	nop
 .*	00 00 00 00 .*
-.*	00 01 02 18 .*
+.*	00 01 02 28 .*
 .*	7d 88 02 a6 	mflr    r12
 .*	42 9f 00 05 	bcl-    20,4\*cr7\+so,.*
 .*	7d 68 02 a6 	mflr    r11
Index: ld/testsuite/ld-powerpc/tlstocso.g
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlstocso.g,v
retrieving revision 1.9
diff -u -p -r1.9 tlstocso.g
--- ld/testsuite/ld-powerpc/tlstocso.g	13 Aug 2007 00:20:59 -0000	1.9
+++ ld/testsuite/ld-powerpc/tlstocso.g	24 Mar 2009 03:06:26 -0000
@@ -7,7 +7,7 @@
 .*: +file format elf64-powerpc
 
 Contents of section \.got:
-.* 00000000 000186c0 00000000 00000000  .*
+.* 00000000 00018708 00000000 00000000  .*
 .* 00000000 00000000 00000000 00000000  .*
 .* 00000000 00000000 00000000 00000000  .*
 .* 00000000 00000000 00000000 00000000  .*

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list