Re: PC-relative TLS support

2019-08-21 Thread Alan Modra
On Mon, Aug 19, 2019 at 07:45:19AM -0500, Segher Boessenkool wrote:
> But if you think we can remove the !TARGET_TLS_MARKERS everywhere it
> is relevant at all, now is the time, patches very welcome, it would be
> a nice cleanup :-)  Needs testing everywhere of course, but now is
> stage 1 :-)

This patch removes !TARGET_TLS_MARKERS support.  -mtls-markers (and
-mno-tls-markers) disappear as valid options too, because I figure
they haven't been used too much except by people testing the
compiler.  Bootstrapped and regression tested powerpc64le-linux and
powerpc-ibm-aix7.1.3.0 (on gcc111).  I believe powerpc*-darwin doesn't
support TLS.

Requiring an 8 year old binutils-2.20 shouldn't be that onerous.

Note that this patch doesn't remove the configure test to set
HAVE_AS_TLS_MARKERS.  I was wondering whether I ought to hook that
into a "sorry, your assembler is too old" error?

* config/rs6000/rs6000-protos.h (rs6000_output_tlsargs): Delete.
* config/rs6000/rs6000.c (rs6000_output_tlsargs): Delete.
(rs6000_legitimize_tls_address): Remove !TARGET_TLS_MARKERS code.
(rs6000_call_template_1): Delete TARGET_TLS_MARKERS test and
allow other UNSPECs besides UNSPEC_TLSGD and UNSPEC_TLSLD.
(rs6000_indirect_call_template_1): Likewise.
(rs6000_pltseq_template): Likewise.
(rs6000_opt_vars): Remove "tls-markers" entry.
* config/rs6000/rs6000.h (TARGET_TLS_MARKERS): Don't define.
(IS_NOMARK_TLSGETADDR): Likewise.
* config/rs6000/rs6000.md (tls_gd): Replace TARGET_TLS_MARKERS
with !TARGET_XCOFF.
(tls_gd_high, tls_gd_low): Likewise.
(tls_ld, tls_ld_high, tls_ld_low): Likewise.
(pltseq_plt_pcrel): Likewise.
(call_value_local32): Remove IS_NOMARK_TLSGETADDR predicate test.
(call_value_local64): Likewise.
(call_value_indirect_nonlocal_sysv): Remove IS_NOMARK_TLSGETADDR
output and length attribute sub-expression.
(call_value_nonlocal_sysv),
(call_value_nonlocal_sysv_secure),
(call_value_local_aix, call_value_nonlocal_aix),
(call_value_indirect_aix, call_value_indirect_elfv2),
(call_value_indirect_pcrel): Likewise.
* config/rs6000/rs6000.opt (mtls-markers): Delete.
* doc/install.texi (powerpc-*-*): Require binutils-2.20.

diff --git a/gcc/config/rs6000/rs6000-protos.h 
b/gcc/config/rs6000/rs6000-protos.h
index 06e40d94b17..88b5b7cec55 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -139,7 +139,6 @@ extern bool valid_sf_si_move (rtx, rtx, machine_mode);
 extern void rs6000_emit_move (rtx, rtx, machine_mode);
 extern bool rs6000_legitimate_offset_address_p (machine_mode, rtx,
bool, bool);
-extern void rs6000_output_tlsargs (rtx *);
 extern rtx rs6000_find_base_term (rtx);
 extern rtx rs6000_return_addr (int, rtx);
 extern void rs6000_output_symbol_ref (FILE*, rtx);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index e792116fb40..5e2b08c3c72 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -8329,41 +8329,6 @@ rs6000_legitimize_tls_address_aix (rtx addr, enum 
tls_model model)
   return dest;
 }
 
-/* Output arg setup instructions for a !TARGET_TLS_MARKERS
-   __tls_get_addr call.  */
-
-void
-rs6000_output_tlsargs (rtx *operands)
-{
-  /* Set up operands for output_asm_insn, without modifying OPERANDS.  */
-  rtx op[3];
-
-  /* The set dest of the call, ie. r3, which is also the first arg reg.  */
-  op[0] = operands[0];
-  /* The TLS symbol from global_tlsarg stashed as CALL operand 2.  */
-  op[1] = XVECEXP (operands[2], 0, 0);
-  if (XINT (operands[2], 1) == UNSPEC_TLSGD)
-{
-  /* The GOT register.  */
-  op[2] = XVECEXP (operands[2], 0, 1);
-  if (TARGET_CMODEL != CMODEL_SMALL)
-   output_asm_insn ("addis %0,%2,%1@got@tlsgd@ha\n\t"
-"addi %0,%0,%1@got@tlsgd@l", op);
-  else
-   output_asm_insn ("addi %0,%2,%1@got@tlsgd", op);
-}
-  else if (XINT (operands[2], 1) == UNSPEC_TLSLD)
-{
-  if (TARGET_CMODEL != CMODEL_SMALL)
-   output_asm_insn ("addis %0,%1,%&@got@tlsld@ha\n\t"
-"addi %0,%0,%&@got@tlsld@l", op);
-  else
-   output_asm_insn ("addi %0,%1,%&@got@tlsld", op);
-}
-  else
-gcc_unreachable ();
-}
-
 /* Passes the tls arg value for global dynamic and local dynamic
emit_library_call_value in rs6000_legitimize_tls_address to
rs6000_call_aix and rs6000_call_sysv.  This is used to emit the
@@ -8465,16 +8430,10 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model 
model)
  rtx arg = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, addr, got),
UNSPEC_TLSGD);
  tga = rs6000_tls_get_addr ();
+ rtx argreg = gen_rtx_REG (Pmode, 3);
+ emit_insn (gen_rtx_SET (argreg, arg));
  global_tlsarg = arg;
- if 

Re: PC-relative TLS support

2019-08-19 Thread Segher Boessenkool
On Fri, Aug 16, 2019 at 11:29:30AM +0930, Alan Modra wrote:
> On Thu, Aug 15, 2019 at 01:24:07PM -0500, Segher Boessenkool wrote:
> > On Thu, Aug 15, 2019 at 01:35:10PM +0930, Alan Modra wrote:
> > > Supporting TLS for -mpcrel turns out to be relatively simple, in part
> > > due to deciding that !TARGET_TLS_MARKERS with -mpcrel is silly.  No
> > > assembler that I know of supporting prefix insns lacks TLS marker
> > > support.
> > 
> > Will this stay that way?  (Or do we not care, not now anyway?)
> 
> I'd say we leave that problem to someone who wants pcrel without tls
> markers.  It's not hard to do, just extend rs6000_output_tlsargs and
> adjust IS_NOMARK_TLSGETADDR length attribute expressions.

Okay, so the latter option :-)

> > > Also, at some point powerpc gcc ought to remove
> > > !TARGET_TLS_MARKERS generally and simplify all the occurrences of
> > > IS_NOMARK_TLSGETADDR in rs6000.md rather than complicating them.
> > 
> > The last time this came up (a year ago) the conclusion was that we first
> > would have to remove AIX support.
> 
> Hmm, I wonder has that changed?  A quick look at the source says the
> AIX TLS support uses completely different patterns and shouldn't care.

https://gcc.gnu.org/ml/gcc-patches/2018-11/msg02259.html

But if you think we can remove the !TARGET_TLS_MARKERS everywhere it
is relevant at all, now is the time, patches very welcome, it would be
a nice cleanup :-)  Needs testing everywhere of course, but now is
stage 1 :-)


Segher


Re: PC-relative TLS support

2019-08-15 Thread Alan Modra
On Thu, Aug 15, 2019 at 01:24:07PM -0500, Segher Boessenkool wrote:
> Hi!
> 
> On Thu, Aug 15, 2019 at 01:35:10PM +0930, Alan Modra wrote:
> > Supporting TLS for -mpcrel turns out to be relatively simple, in part
> > due to deciding that !TARGET_TLS_MARKERS with -mpcrel is silly.  No
> > assembler that I know of supporting prefix insns lacks TLS marker
> > support.
> 
> Will this stay that way?  (Or do we not care, not now anyway?)

I'd say we leave that problem to someone who wants pcrel without tls
markers.  It's not hard to do, just extend rs6000_output_tlsargs and
adjust IS_NOMARK_TLSGETADDR length attribute expressions.

> > Also, at some point powerpc gcc ought to remove
> > !TARGET_TLS_MARKERS generally and simplify all the occurrences of
> > IS_NOMARK_TLSGETADDR in rs6000.md rather than complicating them.
> 
> The last time this came up (a year ago) the conclusion was that we first
> would have to remove AIX support.

Hmm, I wonder has that changed?  A quick look at the source says the
AIX TLS support uses completely different patterns and shouldn't care.

> (Changelog has whitespace damage, I guess that is just from how you
> mailed this?  Please fix when applying it).

Fixed.  (It wasn't the mailer..)

-- 
Alan Modra
Australia Development Lab, IBM


Re: PC-relative TLS support

2019-08-15 Thread Segher Boessenkool
Hi!

On Thu, Aug 15, 2019 at 01:35:10PM +0930, Alan Modra wrote:
> Supporting TLS for -mpcrel turns out to be relatively simple, in part
> due to deciding that !TARGET_TLS_MARKERS with -mpcrel is silly.  No
> assembler that I know of supporting prefix insns lacks TLS marker
> support.

Will this stay that way?  (Or do we not care, not now anyway?)

> Also, at some point powerpc gcc ought to remove
> !TARGET_TLS_MARKERS generally and simplify all the occurrences of
> IS_NOMARK_TLSGETADDR in rs6000.md rather than complicating them.

The last time this came up (a year ago) the conclusion was that we first
would have to remove AIX support.

> * config/rs6000/predicates.md (unspec_tls): Allow const0_rtx for got
>   element of unspec vec.
> * config/rs6000/rs6000.c (rs6000_option_override_internal): Disable
>   -mpcrel if -mno-tls-markers.
>   (rs6000_legitimize_tls_address): Support PC-relative TLS.
> * config/rs6000/rs6000.md (UNSPEC_TLSTLS_PCREL): New unspec.
>   (tls_gd_pcrel, tls_ld_pcrel): New insns.
> (tls_dtprel, tls_tprel): Set attr prefixed when tls_size is not 16.
> (tls_got_tprel_pcrel, tls_tls_pcrel): New insns.

(Changelog has whitespace damage, I guess that is just from how you
mailed this?  Please fix when applying it).

The patch is fine when its prerequisites are in.  Thanks,


Segher


PC-relative TLS support

2019-08-14 Thread Alan Modra
Supporting TLS for -mpcrel turns out to be relatively simple, in part
due to deciding that !TARGET_TLS_MARKERS with -mpcrel is silly.  No
assembler that I know of supporting prefix insns lacks TLS marker
support.  Also, at some point powerpc gcc ought to remove
!TARGET_TLS_MARKERS generally and simplify all the occurrences of
IS_NOMARK_TLSGETADDR in rs6000.md rather than complicating them.

Mike, the rs6000_option_override_internal hunk is new compared to
the patch you had from me.

* config/rs6000/predicates.md (unspec_tls): Allow const0_rtx for got
element of unspec vec.
* config/rs6000/rs6000.c (rs6000_option_override_internal): Disable
-mpcrel if -mno-tls-markers.
(rs6000_legitimize_tls_address): Support PC-relative TLS.
* config/rs6000/rs6000.md (UNSPEC_TLSTLS_PCREL): New unspec.
(tls_gd_pcrel, tls_ld_pcrel): New insns.
(tls_dtprel, tls_tprel): Set attr prefixed when tls_size is not 16.
(tls_got_tprel_pcrel, tls_tls_pcrel): New insns.

diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index fba87946ec7..4ea588e1027 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -995,9 +995,9 @@
   if (CONST_INT_P (op))
 return 1;
   if (XINT (op, 1) == UNSPEC_TLSGD)
-return REG_P (XVECEXP (op, 0, 1));
+return REG_P (XVECEXP (op, 0, 1)) || XVECEXP (op, 0, 1) == const0_rtx;
   if (XINT (op, 1) == UNSPEC_TLSLD)
-return REG_P (XVECEXP (op, 0, 0));
+return REG_P (XVECEXP (op, 0, 0)) || XVECEXP (op, 0, 0) == const0_rtx;
   return 0;
 })
 
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 6aca0ce5bf3..c04206ab139 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -4216,6 +4216,16 @@ rs6000_option_override_internal (bool global_init_p)
| OPTION_MASK_PCREL_OPT);
 }
 
+  /* -mpcrel requires tls marker support.  */
+  if (TARGET_PCREL && !TARGET_TLS_MARKERS)
+{
+  if ((rs6000_isa_flags_explicit & OPTION_MASK_PCREL) != 0)
+   error ("%qs requires %qs", "-mpcrel", "-mtls-markers");
+
+  rs6000_isa_flags &= ~(OPTION_MASK_PCREL
+   | OPTION_MASK_PCREL_OPT);
+}
+
   /* Check -mfuture debug switches.  */
   if (!TARGET_PCREL && TARGET_PCREL_OPT)
 {
@@ -8613,7 +8623,8 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model 
model)
 return rs6000_legitimize_tls_address_aix (addr, model);
 
   dest = gen_reg_rtx (Pmode);
-  if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
+  if (model == TLS_MODEL_LOCAL_EXEC
+  && (rs6000_tls_size == 16 || rs6000_pcrel_p (cfun)))
 {
   rtx tlsreg;
 
@@ -8660,7 +8671,9 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model 
model)
 them in the .got section.  So use a pointer to the .got section,
 not one to secondary TOC sections used by 64-bit -mminimal-toc,
 or to secondary GOT sections used by 32-bit -fPIC.  */
-  if (TARGET_64BIT)
+  if (rs6000_pcrel_p (cfun))
+   got = const0_rtx;
+  else if (TARGET_64BIT)
got = gen_rtx_REG (Pmode, 2);
   else
{
@@ -8735,7 +8748,7 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model 
model)
  rtx uns = gen_rtx_UNSPEC (Pmode, vec, UNSPEC_TLS_GET_ADDR);
  set_unique_reg_note (get_last_insn (), REG_EQUAL, uns);
 
- if (rs6000_tls_size == 16)
+ if (rs6000_tls_size == 16 || rs6000_pcrel_p (cfun))
{
  if (TARGET_64BIT)
insn = gen_tls_dtprel_64 (dest, tmp1, addr);
@@ -8776,7 +8789,14 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model 
model)
  else
insn = gen_tls_got_tprel_32 (tmp2, got, addr);
  emit_insn (insn);
- if (TARGET_64BIT)
+ if (rs6000_pcrel_p (cfun))
+   {
+ if (TARGET_64BIT)
+   insn = gen_tls_tls_pcrel_64 (dest, tmp2, addr);
+ else
+   insn = gen_tls_tls_pcrel_32 (dest, tmp2, addr);
+   }
+ else if (TARGET_64BIT)
insn = gen_tls_tls_64 (dest, tmp2, addr);
  else
insn = gen_tls_tls_32 (dest, tmp2, addr);
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 0e7d90e5357..6e32d8fdff1 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -88,6 +88,7 @@
UNSPEC_TLSTPRELLO
UNSPEC_TLSGOTTPREL
UNSPEC_TLSTLS
+   UNSPEC_TLSTLS_PCREL
UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
UNSPEC_STFIWX
UNSPEC_POPCNTB
@@ -9514,6 +9515,15 @@
 
 ;; TLS support.
 
+(define_insn "*tls_gd_pcrel"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
+   (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
+  (const_int 0)]
+ UNSPEC_TLSGD))]
+  "HAVE_AS_TLS && TARGET_TLS_MARKERS"
+  "la %0,%1@got@tlsgd@pcrel"
+  [(set_attr "prefixed" "yes")])
+