On Mon, Mar 19, 2012 at 8:51 AM, H.J. Lu <[email protected]> wrote:
> On Sun, Mar 18, 2012 at 1:55 PM, Uros Bizjak <[email protected]> wrote:
>> On Sun, Mar 18, 2012 at 5:01 PM, Uros Bizjak <[email protected]> wrote:
>>
>>>> I am testing this patch. OK for trunk if it passes all tests?
>>>
>>> No, force_reg will generate a pseudo, so this conversion is valid only
>>> for !can_create_pseudo ().
>>>
>>> At least for *tls_initial_exec_x32_store, you will need a temporary to
>>> split the pattern after reload.
>
> Here is the updated patch to add can_create_pseudo. I also changed
> tls_initial_exec_x32 to take an input register operand as thread pointer.
>
>> Please try attached patch. It simply throws away all recent
>> complications w.r.t. to thread pointer and always handles TP in
>> DImode.
>>
>> The testcase:
>>
>> --cut here--
>> __thread int foo __attribute__ ((tls_model ("initial-exec")));
>>
>> void bar (int x)
>> {
>> foo = x;
>> }
>>
>> int baz (void)
>> {
>> return foo;
>> }
>> --cut here--
>>
>> Now compiles to:
>>
>> bar:
>> movq foo@gottpoff(%rip), %rax
>> movl %edi, %fs:(%rax)
>> ret
>>
>> baz:
>> movq foo@gottpoff(%rip), %rax
>> movl %fs:(%rax), %eax
>> ret
>>
>> In effect, this always generates %fs(%rDI) and emits REX prefix before
>> mov/add to satisfy brain-dead linkers.
>>
>> The patch is bootstrapping now on x86_64-pc-linux-gnu.
>>
>
> For
>
> --
> extern __thread char c;
> extern char y;
> void
> ie (void)
> {
> y = c;
> }
> --
>
> Your patch generates:
>
> movl %fs:0, %eax
> movq c@gottpoff(%rip), %rdx
> movzbl (%rax,%rdx), %edx
> movb %dl, y(%rip)
> ret
>
> It can be optimized to:
>
> movq c@gottpoff(%rip), %rax
> movzbl %fs:(%rax), %eax
> movb %al, y(%rip)
> ret
>
Combine failed:
(set (reg:QI 63 [ c ])
(mem/c:QI (plus:DI (zero_extend:DI (unspec:SI [
(const_int 0 [0])
] UNSPEC_TP))
(mem/u/c:DI (const:DI (unspec:DI [
(symbol_ref:SI ("c") [flags 0x60]
<var_decl 0x7ffff19b8140 c>)
] UNSPEC_GOTNTPOFF)) [2 S8 A8])) [0 c+0 S1 A8]))
--
H.J.