On Thu, Jul 28, 2011 at 6:40 AM, Uros Bizjak <ubiz...@gmail.com> wrote: > On Thu, Jul 28, 2011 at 3:24 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. >> 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. >
We can't just shadow them. They have to be disabled for x32. I am testing this. -- H.J. --- diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index aaaf53a..9191b98 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -12452,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:DI 0 "register_operand" "=r") + (unspec:DI [(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") @@ -12463,12 +12474,25 @@ (set_attr "memory" "load") (set_attr "imm_disp" "false")]) +(define_insn "*add_tp_x32" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP) + (match_operand:DI 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")