Patchwork PATCH, v2: PR target/47715: [x32] Use SImode for thread pointer

login
register
mail settings
Submitter Uros Bizjak
Date July 29, 2011, 9:11 a.m.
Message ID <CAFULd4bmAX-fA=m97Mq_CN6H96mDwayawG6JFyE_B78+OkzyFg@mail.gmail.com>
Download mbox | patch
Permalink /patch/107374/
State New
Headers show

Comments

Uros Bizjak - July 29, 2011, 9:11 a.m.
Hello!

ABI specifies that TP is loaded in ptr_mode. Attached patch implements
this requirement.

2011-07-29  Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/i386.md (*load_tp_x32): New.
	(*load_tp_x32_zext): Ditto.
	(*add_tp_x32): Ditto.
	(*add_tp_x32_zext): Ditto.
	(*load_tp_<mode>): Disable for !TARGET_X32 targets.
	(*add_tp_<mode>): Ditto.
	* config/i386/i386.c (get_thread_pointer): Load thread pointer in
	ptr_mode and convert to Pmode if needed.

Testing on x86_64-pc-linux-gnu in progress. H.J., please test this
version on x32.

Uros.

Patch

Index: i386.md
===================================================================
--- i386.md	(revision 176915)
+++ i386.md	(working copy)
@@ -12444,10 +12444,32 @@ 
 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
 
 ;; Load and add the thread base pointer from %<tp_seg>:0.
+(define_insn "*load_tp_x32"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(unspec:SI [(const_int 0)] UNSPEC_TP))]
+  "TARGET_X32"
+  "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs: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_zext"
+  [(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")
+   (set_attr "memory" "load")
+   (set_attr "imm_disp" "false")])
+
 (define_insn "*load_tp_<mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
 	(unspec:P [(const_int 0)] UNSPEC_TP))]
-  ""
+  "!TARGET_X32"
   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
   [(set_attr "type" "imov")
    (set_attr "modrm" "0")
@@ -12455,12 +12477,39 @@ 
    (set_attr "memory" "load")
    (set_attr "imm_disp" "false")])
 
+(define_insn "*add_tp_x32"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
+		 (match_operand:SI 1 "register_operand" "0")))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_X32"
+  "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
+  [(set_attr "type" "alu")
+   (set_attr "modrm" "0")
+   (set_attr "length" "7")
+   (set_attr "memory" "load")
+   (set_attr "imm_disp" "false")])
+
+(define_insn "*add_tp_x32_zext"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(zero_extend:DI
+	  (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
+		   (match_operand:SI 1 "register_operand" "0"))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_X32"
+  "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
+  [(set_attr "type" "alu")
+   (set_attr "modrm" "0")
+   (set_attr "length" "7")
+   (set_attr "memory" "load")
+   (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")))
    (clobber (reg:CC FLAGS_REG))]
-  ""
+  "!TARGET_X32"
   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
   [(set_attr "type" "alu")
    (set_attr "modrm" "0")
Index: i386.c
===================================================================
--- i386.c	(revision 176915)
+++ i386.c	(working copy)
@@ -12118,17 +12118,15 @@  legitimize_pic_address (rtx orig, rtx re
 static rtx
 get_thread_pointer (bool to_reg)
 {
-  rtx tp, reg, insn;
+  rtx tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
 
-  tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
-  if (!to_reg)
-    return tp;
+  if (GET_MODE (tp) != Pmode)
+    tp = convert_to_mode (Pmode, tp, 1);
 
-  reg = gen_reg_rtx (Pmode);
-  insn = gen_rtx_SET (VOIDmode, reg, tp);
-  insn = emit_insn (insn);
+  if (to_reg)
+    tp = copy_addr_to_reg (tp);
 
-  return reg;
+  return tp;
 }
 
 /* Construct the SYMBOL_REF for the tls_get_addr function.  */