This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: PR target/47715: [x32] Use SImode for thread pointer
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: gcc-patches at gcc dot gnu dot org, Uros Bizjak <ubizjak at gmail dot com>
- Date: Wed, 27 Jul 2011 20:11:21 -0700
- Subject: PATCH: PR target/47715: [x32] Use SImode for thread pointer
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
Hi,
In x32, thread pointer is 32bit and choice of segment register for the
thread base ptr load should be based on TARGET_64BIT. This patch
implements it. OK for trunk?
Thanks.
H.J.
---
2011-07-27 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.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 8723dc5..d32d64d 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -12120,7 +12120,9 @@ get_thread_pointer (bool 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 e91a299..c772f94 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -951,9 +951,14 @@
;; This mode iterator allows :P to be used for patterns that operate on
;; pointer-sized quantities. Exactly one of the two alternatives will match.
(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
+
+;; This mode iterator allows :PTR to be used for patterns that operate on
+;; ptr_mode sized quantities.
+(define_mode_iterator PTR
+ [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
;; Pointer modes in 64bit.
(define_mode_iterator PTR64 [(SI "TARGET_X32") DI])
;; Scheduling descriptions
output_asm_insn
("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
fputs (ASM_SHORT "0x6666\n", asm_out_file);
(define_insn "*tls_local_dynamic_base_32_gnu"
@@ -12438,15 +12451,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 %<tp_seg>: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")
@@ -12454,12 +12480,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")