On Thu, Jul 28, 2011 at 9:00 AM, H.J. Lu <hjl.to...@gmail.com> wrote: > On Thu, Jul 28, 2011 at 8:59 AM, H.J. Lu <hjl.to...@gmail.com> wrote: >> On Thu, Jul 28, 2011 at 7:59 AM, Uros Bizjak <ubiz...@gmail.com> wrote: >>> On Thu, Jul 28, 2011 at 4:47 PM, H.J. Lu <hjl.to...@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 <ubiz...@gmail.com> H.J. Lu <hongjiu...@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 <ubiz...@gmail.com> H.J. Lu <hongjiu...@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")