Re: how to use emit_clobber () ?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



William Tambe via Gcc-help <gcc-help@xxxxxxxxxxx> writes:
> Correcting typo in my previous email.
>
> On Sat, Apr 25, 2020 at 3:21 PM William Tambe <tambewilliam@xxxxxxxxx> wrote:
>>
>> The following define_expand is used to generate a call to
>> __tls_get_addr() when the first operand of movsi is detected as a TLS
>> symbol by tls_symbol_operand().
>>
>> I am trying to accomplish generating a call to __tls_get_addr()
>> passing two arguments in two registers where I would like to clobber
>> the first register argument.
>>
>> However the use of emit_clobber() has no effect.
>>
>> Any idea, how emit_clobber should be used below ?
>>
>> (define_expand "movsi"
>>  [(set (match_operand:SI 0 "nonimmediate_operand" "")
>>        (match_operand:SI 1 "general_operand"      ""))]
>>  ""
>>  {
>>    rtx op0 = operands[0];
>>    rtx op1 = operands[1];
>>    if (tls_symbolic_operand (op0, VOIDmode)) {
>>      rtx arg0 = gen_rtx_REG (SImode, ARCH_FIRST_ARG_REGNUM);
>>      rtx arg1 = gen_rtx_REG (SImode, ARCH_FIRST_ARG_REGNUM+1);
>>      emit_insn (arg1);
>>      emit_clobber (gen__movsi (arg0, op0));
>
> Above is incorrect; what I am using is below:
>      emit_clobber (arg1);
>      emit_insn (gen__movsi (arg0, op0));
>
> Question remain the same; any idea how emit_clobber should be used in
> order to have an effect ?
>
>>      rtx fn = gen_rtx_MEM (FUNCTION_MODE, gen_arch_tga());
>>      rtx_insn *insn = emit_call_insn (gen_call_value (arg0, fn, const0_rtx));
>>      RTL_CONST_CALL_P (insn) = 1;
>>      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg0);
>>      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg1);

The last line says that the call uses the current value of arg1, but
nothing in the above seems to set arg1 to a real value.

What is the clobber of arg1 meant to model?  I.e. what actually clobbers
arg1?  Is it the call itself?  If so, is arg1 normally preserved by
calls on this target?  If arg1 is normally preserved by calls, you can
make an exception for this call by adding a CLOBBER (rather than a USE)
to the CALL_INSN_FUNCTION_USAGE.  If arg1 is normally clobbered by calls,
you shouldn't need to do anything special.

On most targets, the __tls_get_addr function preserves many more
registers than the normal ABI, so it is often better not to represent
it as a call_insn.  E.g. arm.md has:

;; tls descriptor call
(define_insn "tlscall"
  [(set (reg:SI R0_REGNUM)
        (unspec:SI [(reg:SI R0_REGNUM)
                    (match_operand:SI 0 "" "X")
	            (match_operand 1 "" "")] UNSPEC_TLS))
   (clobber (reg:SI R1_REGNUM))
   (clobber (reg:SI LR_REGNUM))
   (clobber (reg:SI CC_REGNUM))]
  "TARGET_GNU2_TLS"
  {
    targetm.asm_out.internal_label (asm_out_file, "LPIC",
				    INTVAL (operands[1]));
    return "bl\\t%c0(tlscall)";
  }
  [(set_attr "conds" "clob")
   (set_attr "length" "4")
   (set_attr "type" "branch")]
)

which says that only R0, R1, LR and CC are clobbered by the call.

Thanks,
Richard



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux