On Tue, Mar 20, 2012 at 11:43 AM, Uros Bizjak <ubiz...@gmail.com> wrote:
> On Tue, Mar 20, 2012 at 7:27 PM, H.J. Lu <hjl.to...@gmail.com> wrote:
>
>>>> I think use the OS provided instruction to load TP into DImode register
>>>> could simplify the code.
>>>
>>> Which OS provided instruction?
>>>
>>> Please see how TP is defined in get_thread_pointer, it is in ptr_mode:
>>>
>>>  rtx tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
>>>
>>> This says that TP is in SImode on X32.
>
>> TP is defined as (unspec:DI [(const_int 0]) UNSPEC_TP)
>> and provided by OS.  It is a CONST_INT, but its value is opaque
>> to GCC. MODE here has no impact on its value provided by OS.
>> X32 OS provides instructions to load TP to into an SImode and
>> DImode registers.
>
> You must be looking to some other GCC sources than me.
>
> (define_insn "*load_tp_x32"
>  [(set (match_operand:SI 0 "register_operand" "=r")
>        (unspec:SI [(const_int 0)] UNSPEC_TP))]
>  "TARGET_X32"
>  "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
>  [(set_attr "type" "imov")
>   (set_attr "modrm" "0")
>   (set_attr "length" "7")
>   (set_attr "memory" "load")
>   (set_attr "imm_disp" "false")])
>
> (define_insn "*load_tp_x32_zext"
>  [(set (match_operand:DI 0 "register_operand" "=r")
>        (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
>  "TARGET_X32"
>  "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
>  [(set_attr "type" "imov")
>   (set_attr "modrm" "0")
>   (set_attr "length" "7")
>   (set_attr "memory" "load")
>   (set_attr "imm_disp" "false")])
>

Thread pointer (TP) points to thread control block (TCB).  X32 TCB is

typedef struct
{
  void *tcb;            /* Pointer to the TCB.  Not necessarily the
                           thread descriptor used by libpthread.  */
  ...
}

It is a 32bit address set up by OS.  That is where 0 in "%fs:0" comes
from since it is the first field of the struct %fs points to.  X32 OS provides

mov %fs:0, %eax

to load the address of TCB into EAX and

mov %fs:0, %eax

to load the address of TCB into RAX since OS guarantees that the upper
32bits of the address of TCB are all 0s. We added "*load_tp_x32_zext"
since we zero-extend SI TP to DI TP.   Or we can use

mov %fs:0, %eax

to directly load the value of the tcb field into RAX and remove
"*load_tp_x32_zext".  It will simplify the code.


-- 
H.J.

Reply via email to