PATCH: Properly generate X32 IE sequence

Uros Bizjak ubizjak@gmail.com
Mon Mar 19 17:30:00 GMT 2012


On Mon, Mar 19, 2012 at 6:01 PM, Uros Bizjak <ubizjak@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:

--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 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)
        ret

Uros.



More information about the Gcc-patches mailing list