Hi Bill,

On Thu, May 23, 2019 at 09:11:44PM -0500, Bill Schmidt wrote:
> (1) When a function uses PC-relative code generation, all direct calls (other 
> than 
> sibcalls) that the function makes to local or external callees should appear 
> as
> "bl sym@notoc" and should not be followed by a nop instruction.  @notoc 
> indicates
> that the assembler should annotate the call with R_PPC64_REL24_NOTOC, meaning
> that the caller does not guarantee that r2 contains a valid TOC pointer.  Thus
> the linker should not try to replace a subsequent "nop" with a TOC restore
> instruction.

All necessary linker (and binutils and GAS) support is upstream already, right?

> In creating the new sibcall patterns, I did not duplicate the "c" alternatives
> that allow for bctr or blr sibcalls.  I don't think there's a way to generate
> those currently.  The bctr would be legitimate for PC-relative sibcalls if you
> can prove that the target function is in the same binary, but we don't appear
> to detect that possibility today.

But you could see that the target is in the same translation unit, for example?
That should be a simple test to make, too.

>        pld 12,0(0),1
>        .reloc .-8,R_PPC64_PLT_PCREL34_NOTOC,foo

Are we guaranteed the assembler always writes a pld like this as 8 bytes?

>       * gcc.target/powerpc/notoc-direct-1.c: New.
>       * gcc.target/powerpc/pcrel-sibcall-1.c: New.

A few more testcases would be useful.  Well we'll gain a lot of-em soon
enough, I suppose.

>    static char str[32];  /* 2 spare */
> -  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
> +  if (rs6000_pcrel_p (cfun))
> +    sprintf (str, "b%s %s@notoc%s", sibcall ? "" : "l", z, arg);
> +  else if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
>      sprintf (str, "b%s %s%s%s", sibcall ? "" : "l", z, arg,
>            sibcall ? "" : "\n\tnop");

Two spare, and you add one char (@notoc vs. ..nop), so at a minimum you
need to correct the comment?

> +  if (DEFAULT_ABI == ABI_V4
> +      && (!TARGET_SECURE_PLT
> +       || !flag_pic
> +       || (decl
> +           && (*targetm.binds_local_p) (decl))))
> +    return true;
> +
> +  return false;

Please invert this (put the "return false" ondition in the if, like the
preceding comment says).

>    if (TARGET_PLTSEQ)
>      {
>        rtx base = const0_rtx;
> -      int regno;
> -      if (DEFAULT_ABI == ABI_ELFv2)
> +      int regno = 12;
> +      if (rs6000_pcrel_p (cfun))
>       {
> -       base = gen_rtx_REG (Pmode, TOC_REGISTER);
> -       regno = 12;
> +       rtx reg = gen_rtx_REG (Pmode, regno);
> +       rtx u = gen_rtx_UNSPEC (Pmode, gen_rtvec (3, base, call_ref, arg),
> +                               UNSPEC_PLT_PCREL);
> +       emit_insn (gen_rtx_SET (reg, u));
> +       return reg;
>       }

You don't need a regno variable here, so don't use it, only set it later
where it _is_ used?

> +(define_insn "*pltseq_plt_pcrel<mode>"
> +  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
> +     (unspec:P [(match_operand:P 1 "" "")
> +                (match_operand:P 2 "symbol_ref_operand" "s")
> +                (match_operand:P 3 "" "")]
> +               UNSPEC_PLT_PCREL))]
> +  "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
> +   && rs6000_pcrel_p (cfun)"
> +{
> +  return rs6000_pltseq_template (operands, 4);

Maybe those "4" magic constants should be an enum?

> +int zz0 ()
> +{
> +  asm ("");
> +  return 16;
> +};

You might want to put in a comment what this asm is for.


Please consider those things.  Okay for trunk with that.  Thanks!


Segher

Reply via email to