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]

Re: PATCH: PR target/47715: [x32] Use SImode for thread pointer


On Thu, Jul 28, 2011 at 9:00 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Jul 28, 2011 at 8:59 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Thu, Jul 28, 2011 at 7:59 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>>> On Thu, Jul 28, 2011 at 4:47 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>
>>>>>>>>> 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?
>>>>>>>>
>>>>>>>> -ENOTESTCASE.
>>>>>>>>
>>>>>>>
>>>>>>> There is no standalone testcase. ?The symptom is in glibc build, I
>>>>>>> got
>>>>>>>
>>>>>>> CPP='/export/build/gnu/gcc-x32/release/usr/gcc-4.7.0-x32/bin/gcc -mx32
>>>>>>> ?-E -x c-header'
>>>>>>> /export/build/gnu/glibc-x32/build-x86_64-linux/elf/ld-linux-x32.so.2
>>>>>>> --library-path /export/build/gnu/glibc-x32/build-x86_64-linux:/export/build/gnu/glibc-x32/build-x86_64-linux/math:/export/build/gnu/glibc-x32/build-x86_64-linux/elf:/export/build/gnu/glibc-x32/build-x86_64-linux/dlfcn:/export/build/gnu/glibc-x32/build-x86_64-linux/nss:/export/build/gnu/glibc-x32/build-x86_64-linux/nis:/export/build/gnu/glibc-x32/build-x86_64-linux/rt:/export/build/gnu/glibc-x32/build-x86_64-linux/resolv:/export/build/gnu/glibc-x32/build-x86_64-linux/crypt:/export/build/gnu/glibc-x32/build-x86_64-linux/nptl
>>>>>>> /export/build/gnu/glibc-x32/build-x86_64-linux/sunrpc/rpcgen -Y
>>>>>>> ../scripts -h rpcsvc/yppasswd.x -o
>>>>>>> /export/build/gnu/glibc-x32/build-x86_64-linux/sunrpc/rpcsvc/yppasswd.T
>>>>>>> make[5]: *** [/export/build/gnu/glibc-x32/build-x86_64-linux/sunrpc/xbootparam_prot.stmp]
>>>>>>> Segmentation fault
>>>>>>> make[5]: *** Waiting for unfinished jobs....
>>>>>>> make[5]: *** [/export/build/gnu/glibc-x32/build-x86_64-linux/sunrpc/xrstat.stmp]
>>>>>>> Segmentation fault
>>>>>>> make[5]: *** [/export/build/gnu/glibc-x32/build-x86_64-linux/sunrpc/xyppasswd.stmp]
>>>>>>> Segmentation fault
>>>>>>>
>>>>>>> since thread pointer is 32bit in x32.
>>>>>>>
>>>>>>
>>>>>> If we load thread pointer (fs segment register) in x32 with 64bit
>>>>>> load, the upper 32bits are garbage.gcc-x32-tls-tp-2.patch
>>>>>> We must load 32bit
>>>>>
>>>>> So, instead of huge complications with new mode iterator, just
>>>>> introduce two new patterns that will shadow existing ones for
>>>>> TARGET_X32.
>>>>>
>>>>> Like in attached (untested) patch.
>>>>>
>>>>
>>>> I tried the following patch with typos fixed. ?It almost worked,
>>>> except for this failure in glibc testsuite:
>>>>
>>>> gen-locale.sh: line 27: 14755 Aborted ? ? ? ? ? ? ? ? (core dumped)
>>>> I18NPATH=. GCONV_PATH=${common_objpfx}iconvdata ${localedef} --quiet
>>>> -c -f $charmap -i $input ${common_objpfx}localedata/$out
>>>> Charmap: "ISO-8859-1" Inputfile: "nb_NO" Outputdir: "nb_NO.ISO-8859-1" failed
>>>> make[4]: *** [/export/build/gnu/glibc-x32/build-x86_64-linux/localedata/nb_NO.ISO-8859-1/LC_CTYPE]
>>>> Error 1
>>>>
>>>> I will add:
>>>>
>>>> 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;
>>>>
>>>> since TP must be 32bit.
>>>
>>> No, this won't have the desired effect. It will change the UNSPEC, so
>>> it won't match patterns in i386.md.
>>>
>>> Can you debug the failure a bit more? With my patterns, add{l} and
>>> mov{l} should clear top 32bits.
>>>
>>
>> TP is 32bit in x32 ?For load_tp_x32, we load SImode value and
>> zero-extend to DImode. For add_tp_x32, we are adding SImode
>> value. ?We can't pretend TP is 64bit. ?load_tp_x32 and add_tp_x32
>> must take SImode TP.
>>
>
> I will see what I can do.
>

Here is the updated patch to use 32bit TP for 32.  OK for trunk?

Thanks.


-- 
H.J.
-----
2011-07-28  Uros Bizjak  <ubizjak@gmail.com>
	    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 (*load_tp_x32):  New.
	(*add_tp_x32): Likewise.
	(*load_tp_<mode>): Disabled for TARGET_X32.
	(*add_tp_<mode>): Likewise.
2011-07-28  Uros Bizjak  <ubizjak@gmail.com>
	    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 (*load_tp_x32):  New.
	(*add_tp_x32): Likewise.
	(*load_tp_<mode>): Disabled for TARGET_X32.
	(*add_tp_<mode>): Likewise.

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 8723dc5..8d20849 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 f33b8a0..f4717b5 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -12444,10 +12452,21 @@
 (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_<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 +12474,25 @@
    (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_<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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]