This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

x86 descriptor-based TLS local dynamic fix


I've noticed the other day that either I made a mistake when
forward-porting the TLS descriptor code from an earlier release on
which I first wrote it, or combine changed in such a way that the code
I put in was ineffective.

Whatever the reason, this patch fixes it, such that we generate code
as expected, namely, when there is access to a single local dynamic
variable, we revert to general dynamic, and we don't fail to use
segment register-based addressing modes to access such varables when
possible.

I'm checking this in as obvious.  It does not affect code in the
default TLS access models, only when compiling with -mtls-dialect=gnu2

for  gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* config/i386/i386.c (legitimate_tls_address)
	<TARGET_GNU2_TLS>: Add tp after DTPOFF.
	* config/i386/i386.md (*tls_dynamic_gnu2_combine_32): Adjust.
	(*tls_dynamic_gnu2_combine_64): Likewise.

Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c.orig	2006-06-11 17:41:13.000000000 -0300
+++ gcc/config/i386/i386.c	2006-06-11 20:25:09.000000000 -0300
@@ -6750,15 +6750,22 @@ legitimize_tls_address (rtx x, enum tls_
 	{
 	  rtx x = ix86_tls_module_base ();
 
-	  base = force_reg (Pmode, gen_rtx_PLUS (Pmode, tp, base));
-
-	  set_unique_reg_note (get_last_insn (), REG_EQUIV, x);
+	  set_unique_reg_note (get_last_insn (), REG_EQUIV,
+			       gen_rtx_MINUS (Pmode, x, tp));
 	}
 
       off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
       off = gen_rtx_CONST (Pmode, off);
 
       dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, off));
+
+      if (TARGET_GNU2_TLS)
+	{
+	  dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, dest, tp));
+
+	  set_unique_reg_note (get_last_insn (), REG_EQUIV, x);
+	}
+
       break;
 
     case TLS_MODEL_INITIAL_EXEC:
Index: gcc/config/i386/i386.md
===================================================================
--- gcc/config/i386/i386.md	(revision 114548)
+++ gcc/config/i386/i386.md	(working copy)
@@ -14434,12 +14434,11 @@
 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
   [(set (match_operand:SI 0 "register_operand" "=&a")
 	(plus:SI
-	 (plus:SI (match_operand:SI 3 "tp_or_register_operand" "ir")
-		  (unspec:SI [(match_operand:SI 4 "tls_modbase_operand" "")
-			      (match_operand:SI 5 "" "")
-			      (match_operand:SI 2 "register_operand" "b")
-			      (reg:SI SP_REG)]
-			     UNSPEC_TLSDESC))
+	 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
+		     (match_operand:SI 4 "" "")
+		     (match_operand:SI 2 "register_operand" "b")
+		     (reg:SI SP_REG)]
+		    UNSPEC_TLSDESC)
 	 (const:SI (unspec:SI
 		    [(match_operand:SI 1 "tls_symbolic_operand" "")]
 		    UNSPEC_DTPOFF))))
@@ -14447,11 +14446,7 @@
   "!TARGET_64BIT && TARGET_GNU2_TLS"
   "#"
   ""
-  [(parallel
-    [(set (match_dup 0)
-	  (plus:SI (match_dup 3)
-		   (match_dup 5)))
-     (clobber (reg:CC FLAGS_REG))])]
+  [(set (match_dup 0) (match_dup 5))]
 {
   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
@@ -14499,11 +14494,10 @@
 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
   [(set (match_operand:DI 0 "register_operand" "=&a")
 	(plus:DI
-	 (plus:DI (match_operand:DI 2 "tp_or_register_operand" "ir")
-		  (unspec:DI [(match_operand:DI 3 "tls_modbase_operand" "")
-			      (match_operand:DI 4 "" "")
-			      (reg:DI SP_REG)]
-			      UNSPEC_TLSDESC))
+	 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
+		     (match_operand:DI 3 "" "")
+		     (reg:DI SP_REG)]
+		    UNSPEC_TLSDESC)
 	 (const:DI (unspec:DI
 		    [(match_operand:DI 1 "tls_symbolic_operand" "")]
 		    UNSPEC_DTPOFF))))
@@ -14511,11 +14505,7 @@
   "TARGET_64BIT && TARGET_GNU2_TLS"
   "#"
   ""
-  [(parallel
-    [(set (match_dup 0)
-	  (plus:DI (match_dup 2)
-		   (match_dup 4)))
-     (clobber (reg:CC FLAGS_REG))])]
+  [(set (match_dup 0) (match_dup 4))]
 {
   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
Secretary for FSF Latin America        http://www.fsfla.org/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

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