On Mon, Mar 19, 2012 at 10:29 AM, Uros Bizjak <ubiz...@gmail.com> wrote:
> 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.
FWIW, TP maintained by OS is opaque to GCC and GCC mode doesn't
apply to the TP value maintained by OS. The instruction pattern to load TP
into a register is provided by OS and is also opaque to GCC. X32 OS provides
single instructions to load TP into SImode and DImode registers. We
can load x32 TP into SImode register and ZERO_EXTENDs to DImode.
Or we can use the OS provided instruction to load TP into DImode
>> 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:
> --cut here--
> static rtx
> 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);
> if (to_reg)
> tp = copy_to_mode_reg (tp_mode, tp);
> return tp;
> --cut here--
This version works fine.