Patchwork Fix 64-bit Solaris 2/x86 IE TLS code sequence (PR target/43309)

login
register
mail settings
Submitter Rainer Orth
Date Dec. 20, 2010, 12:02 p.m.
Message ID <yddlj3kac00.fsf@manam.CeBiTec.Uni-Bielefeld.DE>
Download mbox | patch
Permalink /patch/76198/
State New
Headers show

Comments

Rainer Orth - Dec. 20, 2010, 12:02 p.m.
I've finally managed to fix PR target/43309, where Sun ld cannot handle
the 64-bit TLS IE code sequence emitted by gcc.

The issue was discussed within the original patch submission

	PATCH: Fix 64-bit Solaris 2/x86 IE TLS code sequence
	http://gcc.gnu.org/ml/gcc-patches/2010-02/msg00993.html

and the PR.

While the Solaris linker maintainers have meanwhile agreed that their
literal interpretation of the AMD64 TLS IE code sequence is too strict
and intend to relax that to accomodate the code GCC emits, for the time
being it is still necessary to work around the issue in GCC as below.

Bootstrapped on i386-pc-solaris2.11 with Sun as and ld without
regressions, fixing all outstanding TLS IE testsuite failures.

Ok for mainline now and 4.4/4.5 backports (slightly modified since they
lack define_c_enum) later?

Thanks.
	Rainer


2010-03-06  Uros Bizjak <ubizjak@gmail.com>
	    Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	PR target/43309
	* config/i386/i386.c (legitimize_tls_address)
	<TLS_MODEL_INITIAL_EXEC>: Handle TARGET_64BIT && TARGET_SUN_TLS.
	* config/i386/i386.md (UNSPEC_TLS_IE_SUN): Declare.
	(*tls_initial_exec_64_sun): New pattern.
	(tls_initial_exec_64_sun): New expander.
Uros Bizjak - Dec. 20, 2010, 3:07 p.m.
On Mon, Dec 20, 2010 at 1:02 PM, Rainer Orth
<ro@cebitec.uni-bielefeld.de> wrote:
> I've finally managed to fix PR target/43309, where Sun ld cannot handle
> the 64-bit TLS IE code sequence emitted by gcc.
>
> The issue was discussed within the original patch submission
>
>        PATCH: Fix 64-bit Solaris 2/x86 IE TLS code sequence
>        http://gcc.gnu.org/ml/gcc-patches/2010-02/msg00993.html
>
> and the PR.
>
> While the Solaris linker maintainers have meanwhile agreed that their
> literal interpretation of the AMD64 TLS IE code sequence is too strict
> and intend to relax that to accomodate the code GCC emits, for the time
> being it is still necessary to work around the issue in GCC as below.
>
> Bootstrapped on i386-pc-solaris2.11 with Sun as and ld without
> regressions, fixing all outstanding TLS IE testsuite failures.
>
> Ok for mainline now and 4.4/4.5 backports (slightly modified since they
> lack define_c_enum) later?
>
> Thanks.
>        Rainer
>
>
> 2010-03-06  Uros Bizjak <ubizjak@gmail.com>
>            Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
>
>        PR target/43309
>        * config/i386/i386.c (legitimize_tls_address)
>        <TLS_MODEL_INITIAL_EXEC>: Handle TARGET_64BIT && TARGET_SUN_TLS.
>        * config/i386/i386.md (UNSPEC_TLS_IE_SUN): Declare.
>        (*tls_initial_exec_64_sun): New pattern.
>        (tls_initial_exec_64_sun): New expander.

This can be handled without expander, by declaring named pattern only.

Uros.

Patch

diff -r ab5cc4da7f14 gcc/config/i386/i386.c
--- a/gcc/config/i386/i386.c	Sat Dec 18 01:20:39 2010 +0100
+++ b/gcc/config/i386/i386.c	Mon Dec 20 08:33:50 2010 +0100
@@ -12524,7 +12524,17 @@ 
       break;
 
     case TLS_MODEL_INITIAL_EXEC:
-      if (TARGET_64BIT)
+      if (TARGET_64BIT && TARGET_SUN_TLS)
+	{
+	  rtx rax = gen_rtx_REG (Pmode, AX_REG);
+
+	  emit_insn (gen_tls_initial_exec_64_sun (rax, x));
+	  dest = gen_reg_rtx (Pmode);
+	  if (dest != rax)
+	    emit_move_insn (dest, rax);
+	  return dest;
+	}
+      else if (TARGET_64BIT)
 	{
 	  pic = NULL;
 	  type = UNSPEC_GOTNTPOFF;
diff -r ab5cc4da7f14 gcc/config/i386/i386.md
--- a/gcc/config/i386/i386.md	Sat Dec 18 01:20:39 2010 +0100
+++ b/gcc/config/i386/i386.md	Mon Dec 20 08:33:50 2010 +0100
@@ -93,6 +93,7 @@ 
   UNSPEC_TLS_GD
   UNSPEC_TLS_LD_BASE
   UNSPEC_TLSDESC
+  UNSPEC_TLS_IE_SUN
 
   ;; Other random patterns
   UNSPEC_SCAS
@@ -12686,6 +12687,29 @@ 
    (set_attr "memory" "load")
    (set_attr "imm_disp" "false")])
 
+;; The Sun linker took the AMD64 TLS spec literally and can only handle
+;; %rax as destination of the initial executable code sequence.
+(define_insn "*tls_initial_exec_64_sun"
+   [(set (match_operand:DI 0 "register_operand" "=a")
+	 (unspec:DI
+	  [(match_operand:DI 1 "tls_symbolic_operand" "")]
+	  UNSPEC_TLS_IE_SUN))
+   (clobber (reg:CC FLAGS_REG))]
+   "TARGET_64BIT && TARGET_SUN_TLS"
+   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
+   [(set_attr "type" "multi")
+    (set_attr "length" "16")])
+
+(define_expand "tls_initial_exec_64_sun"
+  [(parallel [(set (match_operand:DI 0 "register_operand" "")
+		   (unspec:DI
+		    [(match_operand:DI 1 "tls_symbolic_operand" "")]
+		    UNSPEC_TLS_IE_SUN))
+	     (clobber (reg:CC FLAGS_REG))])]
+  ""
+{
+})
+
 ;; GNU2 TLS patterns can be split.
 
 (define_expand "tls_dynamic_gnu2_32"