PATCH: Fix 64-bit Solaris 2/x86 IE TLS code sequence

Uros Bizjak ubizjak@gmail.com
Mon Mar 1 17:35:00 GMT 2010


Hello!

> But even if we conclude that Sun ld is too restrictive in this case, we
> need to fix gcc to work around its requirement, which is what the
> following patch attempts:
>
> * For one, I force the thread pointer into %rax if TARGET_SUN_TLS (which
>    has been reused here to be always 1 on Solaris 2, even with GNU as/ld;
>    this will be part of a subsequent patch to enable TLS with Sun as.
>    This part seems to work just fine.
>
> * Afterwards, I try to emit the addq with destination %rax: this works
>    in some cases, but occasionally fails like this:
>
>          movq    %fs:0, %rax
>          movq    %rax, %rdx
>          addq    cnt@gottpoff(%rip), %rdx
>
>    Being practically ignorant about this part of GCC, I need advice how
>    to fix this.  Perhaps this can only be achieved with a define_insn in
>    i386.md?  If so, how would this look?
>
> Comments or suggestions?
>    

This won't work, since reload can substitute hard register from your 
expander with another at will. You need to specialize "*load_tp_di" (and 
probably also "*add_tp_di", so they will accept only %rax as its output 
register. This can be achieved by using "=a" output register constraint:

(define_insn "*load_tp_di_sun"
   [(set (match_operand:DI 0 "register_operand" "=a")
     (unspec:DI [(const_int 0)] UNSPEC_TP))]
   "TARGET_64BIT && TARGET_SUN_TLS"
   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
   [(set_attr "type" "imov")
    (set_attr "modrm" "0")
    (set_attr "length" "7")
    (set_attr "memory" "load")
    (set_attr "imm_disp" "false")])

(Put this pattern before existing "*load_tp_di", so it will shadow 
existing pattern properly.)

As far as addq is concerned, you will need to disable generic add 
patterns for tls_symbolic_operand and provide special ones that will 
handle  tls_symbolic_operand.  Try to add "! tls_symbolic_operand 
(operands[2], VOIDmode) to PLUS rtx patterns and provide specialized 
replacement. Something like (untested):

(define_insn "*adddi_1_tls_sun"
   [(set (match_operand:DI 0 "register_operand" "=a")
     (plus:SWI48
       (match_operand:DI 1 "register_operand" "0")
       (match_operand:DI 2 "tls_symbolic_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
   ...

Uros.





More information about the Gcc-patches mailing list