Patchwork [z32] PATCH: PR target/47715: [x32] TLS doesn't work

login
register
mail settings
Submitter H.J. Lu
Date Feb. 25, 2011, 9:27 p.m.
Message ID <20110225212733.GA24182@intel.com>
Download mbox | patch
Permalink /patch/84573/
State New
Headers show

Comments

H.J. Lu - Feb. 25, 2011, 9:27 p.m.
Hi,

Thread pointer is 32bit in x32 mode.  I checked in this patch to
properly load thread pointer in x32 mode.


H.J.
---

Patch

diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32
index b1e6753..a7547677 100644
--- a/gcc/ChangeLog.x32
+++ b/gcc/ChangeLog.x32
@@ -1,3 +1,14 @@ 
+2011-02-25  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR target/47715
+	* config/i386/i386.c (get_thread_pointer): Use ptr_mode
+	instead of Pmode with UNSPEC_TP.
+
+	* config/i386/i386.md (tp_seg): Removed.
+	(*load_tp_<mode>): Replace :P with :PTR.
+	(*add_tp_<mode>): Likewise.
+	(*load_tp_x32): New.
+
 2011-02-21  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* config.gcc: Support --enable-ia32 for x86 Linux targets.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index af9f2cd..7b42577 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -12711,7 +12711,9 @@  get_thread_pointer (int to_reg)
 {
   rtx tp, reg, insn;
 
-  tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
+  tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
+  if (ptr_mode != Pmode)
+    tp = convert_to_mode (Pmode, tp, 1);
   if (!to_reg)
     return tp;
 
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 97986c4..509ee82 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -12720,15 +12720,28 @@ 
 	      (clobber (match_dup 5))
 	      (clobber (reg:CC FLAGS_REG))])])
 
-;; Segment register for the thread base ptr load
-(define_mode_attr tp_seg [(SI "gs") (DI "fs")])
-
-;; Load and add the thread base pointer from %gs:0.
+;; Load and add the thread base pointer from %gs:0 or %fs:0.
 (define_insn "*load_tp_<mode>"
-  [(set (match_operand:P 0 "register_operand" "=r")
-	(unspec:P [(const_int 0)] UNSPEC_TP))]
+  [(set (match_operand:PTR 0 "register_operand" "=r")
+	(unspec:PTR [(const_int 0)] UNSPEC_TP))]
   ""
-  "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
+{
+  if (TARGET_64BIT)
+    return "mov{<imodesuffix>}\t{%%fs:0, %0|%0, <iptrsize> PTR fs:0}";
+  else
+    return "mov{<imodesuffix>}\t{%%gs:0, %0|%0, <iptrsize> PTR gs:0}";
+}
+  [(set_attr "type" "imov")
+   (set_attr "modrm" "0")
+   (set_attr "length" "7")
+   (set_attr "memory" "load")
+   (set_attr "imm_disp" "false")])
+
+(define_insn "*load_tp_x32"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
+  "TARGET_X32"
+  "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
   [(set_attr "type" "imov")
    (set_attr "modrm" "0")
    (set_attr "length" "7")
@@ -12736,12 +12749,17 @@ 
    (set_attr "imm_disp" "false")])
 
 (define_insn "*add_tp_<mode>"
-  [(set (match_operand:P 0 "register_operand" "=r")
-	(plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
-		(match_operand:P 1 "register_operand" "0")))
+  [(set (match_operand:PTR 0 "register_operand" "=r")
+	(plus:PTR (unspec:PTR [(const_int 0)] UNSPEC_TP)
+		  (match_operand:PTR 1 "register_operand" "0")))
    (clobber (reg:CC FLAGS_REG))]
   ""
-  "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
+{
+  if (TARGET_64BIT)
+    return "add{<imodesuffix>}\t{%%fs:0, %0|%0, <iptrsize> PTR fs:0}";
+  else
+    return "add{<imodesuffix>}\t{%%gs:0, %0|%0, <iptrsize> PTR gs:0}";
+}
   [(set_attr "type" "alu")
    (set_attr "modrm" "0")
    (set_attr "length" "7")