On Mon, Jan 20, 2020 at 10:46 PM H.J. Lu <hjl.to...@gmail.com> wrote:

> > > OK. Let's go with this version, but please investigate if we need to
> > > calculate TLS address in ptr_mode instead of Pmode. Due to quite some
> > > zero-extension from ptr_mode to Pmode hacks in this area, it looks to
> > > me that the whole calculation should be performed in ptr_mode (SImode
> > > in case of x32), and the result zero-extended to Pmode in case when
> > > Pmode = DImode.
> > >
> >
> > I checked it in.  I will investigate if we can use ptr_mode for TLS.
>
> Here is a patch to perform GNU2 TLS address computation in ptr_mode
> and zero-extend result to Pmode.

     case TLS_MODEL_GLOBAL_DYNAMIC:
-      dest = gen_reg_rtx (Pmode);
+      dest = gen_reg_rtx (TARGET_GNU2_TLS ? ptr_mode : Pmode);

Please put these in their respective arms of "if (TARGET_GNU2_TLS).

     case TLS_MODEL_LOCAL_DYNAMIC:
-      base = gen_reg_rtx (Pmode);
+      base = gen_reg_rtx (TARGET_GNU2_TLS ? ptr_mode : Pmode);

Also here.

A question: Do we need to emit the following part in Pmode?

      off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
      off = gen_rtx_CONST (Pmode, off);

      dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, off));

If this can operate in ptr_mode then ...

-        emit_insn (gen_tls_dynamic_gnu2_64 (Pmode, base, tmp));
+        {
+          emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, base, tmp));
+          if (GET_MODE (base) != Pmode)
+        base = gen_rtx_ZERO_EXTEND (Pmode, base);
+        }

... please keep base in ptr_mode, no need to zero_extend it.

-      tp = get_thread_pointer (Pmode, true);
-      set_unique_reg_note (get_last_insn (), REG_EQUAL,
-                   gen_rtx_MINUS (Pmode, tmp, tp));

Just change the above to ptr_mode. There is no zero_extend needed here, because:

--cut here--
      off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
      off = gen_rtx_CONST (Pmode, off);

      dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, off));

      if (TARGET_GNU2_TLS)
    {
      if (GET_MODE (tp) != Pmode)
        {
          dest = lowpart_subreg (ptr_mode, dest, Pmode);
          dest = gen_rtx_PLUS (ptr_mode, tp, dest);
          dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
        }
      else
        dest = gen_rtx_PLUS (ptr_mode, tp, dest);
      dest = force_reg (Pmode, dest);
--cut here--

all the above part should operate in ptr_mode (for TARGET_GNU2_TLS at
least), followed by the same part of

--cut here--
      dest = gen_rtx_PLUS (ptr_mode, tp, dest);
      if (GET_MODE (dest) != Pmode)
         dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
      dest = force_reg (Pmode, dest);

      if (GET_MODE (x) != Pmode)
        x = gen_rtx_ZERO_EXTEND (Pmode, x);

      set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
--cut here--

as is the case with TLS_MODEL_GLOBAL_DYNAMIC.

Uros.

Reply via email to