On Thu, Jul 28, 2011 at 11:31 AM, Uros Bizjak <ubiz...@gmail.com> wrote: > On Thu, Jul 28, 2011 at 8:30 PM, H.J. Lu <hjl.to...@gmail.com> wrote: > >>>>>> 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. >>> >>> Why?? >>> >>> This part makes no sense: >>> >>> - 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); >>> >>> You will create zero_extend (unspec ...), that won't be matched by any >>> pattern. >> >> No. I created zero_exten from (reg:SI) to (reg: DI). >> >>> Can you please explain, how is this pattern different than DImode >>> pattern, proposed in my patch? >>> >>> +(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")]) >>> >>> vs: >>> >>> +(define_insn "*load_tp_x32" >>> + [(set (match_operand:DI 0 "register_operand" "=r") >>> + (unspec:DI [(const_int 0)] UNSPEC_TP))] >> >> That is wrong since source (TP) is 32bit. This pattern tells compiler >> source is 64bit. > > Where? >
Here is the revised patch. The difference is I changed *add_tp_x32 to SImode. For --- extern __thread int __libc_errno __attribute__ ((tls_model ("initial-exec"))); int * __errno_location (void) { return &__libc_errno; } --- compiled with -mx32 -O2 -fPIC DImode *add_tp_x32 generates: movq __libc_errno@gottpoff(%rip), %rax addl %fs:0, %eax mov %eax, %eax ret SImode *add_tp_x32 generates: movl %fs:0, %eax addl __libc_errno@gottpoff(%rip), %eax ret 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.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.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.md b/gcc/config/i386/i386.md index f33b8a0..7658522 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: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") @@ -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")