On Mon, Mar 19, 2012 at 6:01 PM, Uros Bizjak <ubiz...@gmail.com> wrote:
>>>> For x32, thread pointer is an unsigned 32bit value.
>>>> movl %fs:0, %eax
>>>> is the correct instruction to load thread pointer into EAX and RAX.
>>> So, where is ZERO_EXTEND RTX then?
>> Thread pointer (TP) is an opaque value to GCC. GCC needs to load
>> TP into a SImode or DImode register. ZERO_EXTEND isn't needed
>> when there is a single instruction to load TP into a DImode register.
> I don't agree with this explanation. The mode can't be SImode and
> DImode. TP is either SImode or ZERO_EXTENDed to DImode, this is the
> reason we went for all that TARGET_X32 stuff in TP load RTX.
> Please test my proposed patch. If it works OK, I will commit it to SVN.
The onyl acceptable way is to generate ZERO_EXTEND in place, so:
get_thread_pointer (enum machine_mode tp_mode, bool to_reg)
rtx tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
if (GET_MODE (tp) != tp_mode)
gcc_assert (GET_MODE (tp) == SImode);
gcc_assert (tp_mode == DImode);
tp = gen_rtx_ZERO_EXTEND (tp_mode, tp);
tp = copy_to_mode_reg (tp_mode, tp);
This will generate:
movq c@gottpoff(%rip), %rax
movzbl %fs:(%rax), %eax
movb %al, y(%rip)
movq w@gottpoff(%rip), %rax
movzwl %fs:(%rax), %eax
movw %ax, i(%rip)