[ARM/FDPIC,v5,10/21,ARM] FDPIC: Implement TLS support.

Message ID 20190515124006.25840-11-christophe.lyon@st.com
State Superseded
Headers show
Series
  • FDPIC ABI for ARM
Related show

Commit Message

Christophe Lyon May 15, 2019, 12:39 p.m.
Support additional relocations: TLS_GD32_FDPIC, TLS_LDM32_FDPIC, and
TLS_IE32_FDPIC.

We do not support the GNU2 TLS dialect.

2019-XX-XX  Christophe Lyon  <christophe.lyon@st.com>
	Mickaël Guêné <mickael.guene@st.com>

	gcc/
	* config/arm/arm.c (tls_reloc): Add TLS_GD32_FDPIC,
	TLS_LDM32_FDPIC and TLS_IE32_FDPIC.
	(arm_call_tls_get_addr): Add FDPIC support.
	(legitimize_tls_address): Likewise.
	(arm_emit_tls_decoration): Likewise.

Change-Id: I4ea5034ff654540c4658d0a79fb92f70550cdf4a

-- 
2.6.3

Comments

Kyrill Tkachov Sept. 4, 2019, 2:16 p.m. | #1
Hi Christophe,

On 5/15/19 1:39 PM, Christophe Lyon wrote:
> Support additional relocations: TLS_GD32_FDPIC, TLS_LDM32_FDPIC, and

> TLS_IE32_FDPIC.

>

> We do not support the GNU2 TLS dialect.

>

> 2019-XX-XX  Christophe Lyon  <christophe.lyon@st.com>

>         Mickaël Guêné <mickael.guene@st.com>

>

>         gcc/

>         * config/arm/arm.c (tls_reloc): Add TLS_GD32_FDPIC,

>         TLS_LDM32_FDPIC and TLS_IE32_FDPIC.

>         (arm_call_tls_get_addr): Add FDPIC support.

>         (legitimize_tls_address): Likewise.

>         (arm_emit_tls_decoration): Likewise.

>

> Change-Id: I4ea5034ff654540c4658d0a79fb92f70550cdf4a

>

> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c

> index 99d13bf..5fc7a20 100644

> --- a/gcc/config/arm/arm.c

> +++ b/gcc/config/arm/arm.c

> @@ -2379,9 +2379,12 @@ char arm_arch_name[] = "__ARM_ARCH_PROFILE__";

>

>  enum tls_reloc {

>    TLS_GD32,

> +  TLS_GD32_FDPIC,

>    TLS_LDM32,

> +  TLS_LDM32_FDPIC,

>    TLS_LDO32,

>    TLS_IE32,

> +  TLS_IE32_FDPIC,

>    TLS_LE32,

>    TLS_DESCSEQ  /* GNU scheme */

>  };

> @@ -8760,20 +8763,34 @@ arm_call_tls_get_addr (rtx x, rtx reg, rtx 

> *valuep, int reloc)

>    gcc_assert (reloc != TLS_DESCSEQ);

>    start_sequence ();

>

> -  labelno = GEN_INT (pic_labelno++);

> -  label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), 

> UNSPEC_PIC_LABEL);

> -  label = gen_rtx_CONST (VOIDmode, label);

> +  if (TARGET_FDPIC)

> +    {

> +      sum = gen_rtx_UNSPEC (Pmode,

> +                           gen_rtvec (2, x, GEN_INT (reloc)),

> +                           UNSPEC_TLS);

> +    }

> +  else

> +    {

> +      labelno = GEN_INT (pic_labelno++);

> +      label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), 

> UNSPEC_PIC_LABEL);

> +      label = gen_rtx_CONST (VOIDmode, label);

>

> -  sum = gen_rtx_UNSPEC (Pmode,

> -                       gen_rtvec (4, x, GEN_INT (reloc), label,

> -                                  GEN_INT (TARGET_ARM ? 8 : 4)),

> -                       UNSPEC_TLS);

> +      sum = gen_rtx_UNSPEC (Pmode,

> +                           gen_rtvec (4, x, GEN_INT (reloc), label,

> +                                      GEN_INT (TARGET_ARM ? 8 : 4)),

> +                           UNSPEC_TLS);

> +    }

>    reg = load_tls_operand (sum, reg);

>

> -  if (TARGET_ARM)

> -    emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));

> +  if (TARGET_FDPIC)

> +    {

> +      emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode, 

> FDPIC_REGNUM)));

> +    }


No {} around single statement.

>    else

> -    emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));

> +    if (TARGET_ARM)

> +      emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));



Merge that "if" with the "else" in an "else if"

> +    else

> +      emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));

>

>    *valuep = emit_library_call_value (get_tls_get_addr (), NULL_RTX,

>                                       LCT_PURE, /* LCT_CONST?  */

> @@ -8808,6 +8825,7 @@ arm_tls_descseq_addr (rtx x, rtx reg)

>    return reg;

>  }

>

> +

>  rtx

>  legitimize_tls_address (rtx x, rtx reg)

>  {

> @@ -8820,6 +8838,9 @@ legitimize_tls_address (rtx x, rtx reg)

>      case TLS_MODEL_GLOBAL_DYNAMIC:

>        if (TARGET_GNU2_TLS)

>          {

> +         if (TARGET_FDPIC)

> +           gcc_unreachable();

> +


Use gcc_assert (TARGET_FDPIC)


>            reg = arm_tls_descseq_addr (x, reg);

>

>            tp = arm_load_tp (NULL_RTX);

> @@ -8829,7 +8850,10 @@ legitimize_tls_address (rtx x, rtx reg)

>        else

>          {

>            /* Original scheme */

> -         insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);

> +         if (TARGET_FDPIC)

> +           insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32_FDPIC);

> +         else

> +           insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);

>            dest = gen_reg_rtx (Pmode);

>            emit_libcall_block (insns, dest, ret, x);

>          }

> @@ -8838,6 +8862,9 @@ legitimize_tls_address (rtx x, rtx reg)

>      case TLS_MODEL_LOCAL_DYNAMIC:

>        if (TARGET_GNU2_TLS)

>          {

> +         if (TARGET_FDPIC)

> +           gcc_unreachable();

> +


Likewise.

Ok with those changes.

Thanks,

Kyrill


>            reg = arm_tls_descseq_addr (x, reg);

>

>            tp = arm_load_tp (NULL_RTX);

> @@ -8846,7 +8873,10 @@ legitimize_tls_address (rtx x, rtx reg)

>          }

>        else

>          {

> -         insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32);

> +         if (TARGET_FDPIC)

> +           insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32_FDPIC);

> +         else

> +           insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32);

>

>            /* Attach a unique REG_EQUIV, to allow the RTL optimizers to

>               share the LDM result with other LD model accesses.  */

> @@ -8865,23 +8895,35 @@ legitimize_tls_address (rtx x, rtx reg)

>        return dest;

>

>      case TLS_MODEL_INITIAL_EXEC:

> -      labelno = GEN_INT (pic_labelno++);

> -      label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), 

> UNSPEC_PIC_LABEL);

> -      label = gen_rtx_CONST (VOIDmode, label);

> -      sum = gen_rtx_UNSPEC (Pmode,

> -                           gen_rtvec (4, x, GEN_INT (TLS_IE32), label,

> -                                      GEN_INT (TARGET_ARM ? 8 : 4)),

> -                           UNSPEC_TLS);

> -      reg = load_tls_operand (sum, reg);

> -

> -      if (TARGET_ARM)

> -       emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));

> -      else if (TARGET_THUMB2)

> -       emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg, labelno));

> +      if (TARGET_FDPIC)

> +       {

> +         sum = gen_rtx_UNSPEC (Pmode,

> +                               gen_rtvec (2, x, GEN_INT 

> (TLS_IE32_FDPIC)),

> +                               UNSPEC_TLS);

> +         reg = load_tls_operand (sum, reg);

> +         emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode, 

> FDPIC_REGNUM)));

> +         emit_move_insn (reg, gen_rtx_MEM (Pmode, reg));

> +       }

>        else

>          {

> -         emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));

> -         emit_move_insn (reg, gen_const_mem (SImode, reg));

> +         labelno = GEN_INT (pic_labelno++);

> +         label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), 

> UNSPEC_PIC_LABEL);

> +         label = gen_rtx_CONST (VOIDmode, label);

> +         sum = gen_rtx_UNSPEC (Pmode,

> +                               gen_rtvec (4, x, GEN_INT (TLS_IE32), 

> label,

> +                                          GEN_INT (TARGET_ARM ? 8 : 4)),

> +                               UNSPEC_TLS);

> +         reg = load_tls_operand (sum, reg);

> +

> +         if (TARGET_ARM)

> +           emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));

> +         else if (TARGET_THUMB2)

> +           emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg, 

> labelno));

> +         else

> +           {

> +             emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));

> +             emit_move_insn (reg, gen_const_mem (SImode, reg));

> +           }

>          }

>

>        tp = arm_load_tp (NULL_RTX);

> @@ -28218,15 +28260,24 @@ arm_emit_tls_decoration (FILE *fp, rtx x)

>      case TLS_GD32:

>        fputs ("(tlsgd)", fp);

>        break;

> +    case TLS_GD32_FDPIC:

> +      fputs ("(tlsgd_fdpic)", fp);

> +      break;

>      case TLS_LDM32:

>        fputs ("(tlsldm)", fp);

>        break;

> +    case TLS_LDM32_FDPIC:

> +      fputs ("(tlsldm_fdpic)", fp);

> +      break;

>      case TLS_LDO32:

>        fputs ("(tlsldo)", fp);

>        break;

>      case TLS_IE32:

>        fputs ("(gottpoff)", fp);

>        break;

> +    case TLS_IE32_FDPIC:

> +      fputs ("(gottpoff_fdpic)", fp);

> +      break;

>      case TLS_LE32:

>        fputs ("(tpoff)", fp);

>        break;

> -- 

> 2.6.3

>
Christophe Lyon Sept. 4, 2019, 8:03 p.m. | #2
On Wed, 4 Sep 2019 at 16:16, Kyrill Tkachov <kyrylo.tkachov@foss.arm.com> wrote:
>

> Hi Christophe,

>

> On 5/15/19 1:39 PM, Christophe Lyon wrote:

> > Support additional relocations: TLS_GD32_FDPIC, TLS_LDM32_FDPIC, and

> > TLS_IE32_FDPIC.

> >

> > We do not support the GNU2 TLS dialect.

> >

> > 2019-XX-XX  Christophe Lyon  <christophe.lyon@st.com>

> >         Mickaël Guêné <mickael.guene@st.com>

> >

> >         gcc/

> >         * config/arm/arm.c (tls_reloc): Add TLS_GD32_FDPIC,

> >         TLS_LDM32_FDPIC and TLS_IE32_FDPIC.

> >         (arm_call_tls_get_addr): Add FDPIC support.

> >         (legitimize_tls_address): Likewise.

> >         (arm_emit_tls_decoration): Likewise.

> >

> > Change-Id: I4ea5034ff654540c4658d0a79fb92f70550cdf4a

> >

> > diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c

> > index 99d13bf..5fc7a20 100644

> > --- a/gcc/config/arm/arm.c

> > +++ b/gcc/config/arm/arm.c

> > @@ -2379,9 +2379,12 @@ char arm_arch_name[] = "__ARM_ARCH_PROFILE__";

> >

> >  enum tls_reloc {

> >    TLS_GD32,

> > +  TLS_GD32_FDPIC,

> >    TLS_LDM32,

> > +  TLS_LDM32_FDPIC,

> >    TLS_LDO32,

> >    TLS_IE32,

> > +  TLS_IE32_FDPIC,

> >    TLS_LE32,

> >    TLS_DESCSEQ  /* GNU scheme */

> >  };

> > @@ -8760,20 +8763,34 @@ arm_call_tls_get_addr (rtx x, rtx reg, rtx

> > *valuep, int reloc)

> >    gcc_assert (reloc != TLS_DESCSEQ);

> >    start_sequence ();

> >

> > -  labelno = GEN_INT (pic_labelno++);

> > -  label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno),

> > UNSPEC_PIC_LABEL);

> > -  label = gen_rtx_CONST (VOIDmode, label);

> > +  if (TARGET_FDPIC)

> > +    {

> > +      sum = gen_rtx_UNSPEC (Pmode,

> > +                           gen_rtvec (2, x, GEN_INT (reloc)),

> > +                           UNSPEC_TLS);

> > +    }

> > +  else

> > +    {

> > +      labelno = GEN_INT (pic_labelno++);

> > +      label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno),

> > UNSPEC_PIC_LABEL);

> > +      label = gen_rtx_CONST (VOIDmode, label);

> >

> > -  sum = gen_rtx_UNSPEC (Pmode,

> > -                       gen_rtvec (4, x, GEN_INT (reloc), label,

> > -                                  GEN_INT (TARGET_ARM ? 8 : 4)),

> > -                       UNSPEC_TLS);

> > +      sum = gen_rtx_UNSPEC (Pmode,

> > +                           gen_rtvec (4, x, GEN_INT (reloc), label,

> > +                                      GEN_INT (TARGET_ARM ? 8 : 4)),

> > +                           UNSPEC_TLS);

> > +    }

> >    reg = load_tls_operand (sum, reg);

> >

> > -  if (TARGET_ARM)

> > -    emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));

> > +  if (TARGET_FDPIC)

> > +    {

> > +      emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode,

> > FDPIC_REGNUM)));

> > +    }

>

> No {} around single statement.

>

> >    else

> > -    emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));

> > +    if (TARGET_ARM)

> > +      emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));

>

>

> Merge that "if" with the "else" in an "else if"

>

> > +    else

> > +      emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));

> >

> >    *valuep = emit_library_call_value (get_tls_get_addr (), NULL_RTX,

> >                                       LCT_PURE, /* LCT_CONST?  */

> > @@ -8808,6 +8825,7 @@ arm_tls_descseq_addr (rtx x, rtx reg)

> >    return reg;

> >  }

> >

> > +

> >  rtx

> >  legitimize_tls_address (rtx x, rtx reg)

> >  {

> > @@ -8820,6 +8838,9 @@ legitimize_tls_address (rtx x, rtx reg)

> >      case TLS_MODEL_GLOBAL_DYNAMIC:

> >        if (TARGET_GNU2_TLS)

> >          {

> > +         if (TARGET_FDPIC)

> > +           gcc_unreachable();

> > +

>

> Use gcc_assert (TARGET_FDPIC)

>

>

> >            reg = arm_tls_descseq_addr (x, reg);

> >

> >            tp = arm_load_tp (NULL_RTX);

> > @@ -8829,7 +8850,10 @@ legitimize_tls_address (rtx x, rtx reg)

> >        else

> >          {

> >            /* Original scheme */

> > -         insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);

> > +         if (TARGET_FDPIC)

> > +           insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32_FDPIC);

> > +         else

> > +           insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);

> >            dest = gen_reg_rtx (Pmode);

> >            emit_libcall_block (insns, dest, ret, x);

> >          }

> > @@ -8838,6 +8862,9 @@ legitimize_tls_address (rtx x, rtx reg)

> >      case TLS_MODEL_LOCAL_DYNAMIC:

> >        if (TARGET_GNU2_TLS)

> >          {

> > +         if (TARGET_FDPIC)

> > +           gcc_unreachable();

> > +

>

> Likewise.

>

> Ok with those changes.


Thanks, here is the updated version, with the initialization of labelno in
call_tls_get_addr moved from patch 4/21.


>

> Thanks,

>

> Kyrill

>

>

> >            reg = arm_tls_descseq_addr (x, reg);

> >

> >            tp = arm_load_tp (NULL_RTX);

> > @@ -8846,7 +8873,10 @@ legitimize_tls_address (rtx x, rtx reg)

> >          }

> >        else

> >          {

> > -         insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32);

> > +         if (TARGET_FDPIC)

> > +           insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32_FDPIC);

> > +         else

> > +           insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32);

> >

> >            /* Attach a unique REG_EQUIV, to allow the RTL optimizers to

> >               share the LDM result with other LD model accesses.  */

> > @@ -8865,23 +8895,35 @@ legitimize_tls_address (rtx x, rtx reg)

> >        return dest;

> >

> >      case TLS_MODEL_INITIAL_EXEC:

> > -      labelno = GEN_INT (pic_labelno++);

> > -      label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno),

> > UNSPEC_PIC_LABEL);

> > -      label = gen_rtx_CONST (VOIDmode, label);

> > -      sum = gen_rtx_UNSPEC (Pmode,

> > -                           gen_rtvec (4, x, GEN_INT (TLS_IE32), label,

> > -                                      GEN_INT (TARGET_ARM ? 8 : 4)),

> > -                           UNSPEC_TLS);

> > -      reg = load_tls_operand (sum, reg);

> > -

> > -      if (TARGET_ARM)

> > -       emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));

> > -      else if (TARGET_THUMB2)

> > -       emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg, labelno));

> > +      if (TARGET_FDPIC)

> > +       {

> > +         sum = gen_rtx_UNSPEC (Pmode,

> > +                               gen_rtvec (2, x, GEN_INT

> > (TLS_IE32_FDPIC)),

> > +                               UNSPEC_TLS);

> > +         reg = load_tls_operand (sum, reg);

> > +         emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode,

> > FDPIC_REGNUM)));

> > +         emit_move_insn (reg, gen_rtx_MEM (Pmode, reg));

> > +       }

> >        else

> >          {

> > -         emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));

> > -         emit_move_insn (reg, gen_const_mem (SImode, reg));

> > +         labelno = GEN_INT (pic_labelno++);

> > +         label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno),

> > UNSPEC_PIC_LABEL);

> > +         label = gen_rtx_CONST (VOIDmode, label);

> > +         sum = gen_rtx_UNSPEC (Pmode,

> > +                               gen_rtvec (4, x, GEN_INT (TLS_IE32),

> > label,

> > +                                          GEN_INT (TARGET_ARM ? 8 : 4)),

> > +                               UNSPEC_TLS);

> > +         reg = load_tls_operand (sum, reg);

> > +

> > +         if (TARGET_ARM)

> > +           emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));

> > +         else if (TARGET_THUMB2)

> > +           emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg,

> > labelno));

> > +         else

> > +           {

> > +             emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));

> > +             emit_move_insn (reg, gen_const_mem (SImode, reg));

> > +           }

> >          }

> >

> >        tp = arm_load_tp (NULL_RTX);

> > @@ -28218,15 +28260,24 @@ arm_emit_tls_decoration (FILE *fp, rtx x)

> >      case TLS_GD32:

> >        fputs ("(tlsgd)", fp);

> >        break;

> > +    case TLS_GD32_FDPIC:

> > +      fputs ("(tlsgd_fdpic)", fp);

> > +      break;

> >      case TLS_LDM32:

> >        fputs ("(tlsldm)", fp);

> >        break;

> > +    case TLS_LDM32_FDPIC:

> > +      fputs ("(tlsldm_fdpic)", fp);

> > +      break;

> >      case TLS_LDO32:

> >        fputs ("(tlsldo)", fp);

> >        break;

> >      case TLS_IE32:

> >        fputs ("(gottpoff)", fp);

> >        break;

> > +    case TLS_IE32_FDPIC:

> > +      fputs ("(gottpoff_fdpic)", fp);

> > +      break;

> >      case TLS_LE32:

> >        fputs ("(tpoff)", fp);

> >        break;

> > --

> > 2.6.3

> >
commit 481d4161a6cdf88091cd2fef7ee7fe6b8a836d18
Author: Christophe Lyon <christophe.lyon@linaro.org>
Date:   Thu Feb 8 14:42:05 2018 +0100

    [ARM] FDPIC: Implement TLS support.
    
    Support additional relocations: TLS_GD32_FDPIC, TLS_LDM32_FDPIC, and
    TLS_IE32_FDPIC.
    
    We do not support the GNU2 TLS dialect.
    
    2019-XX-XX  Christophe Lyon  <christophe.lyon@st.com>
    	Mickaël Guêné <mickael.guene@st.com>
    
    	gcc/
    	* config/arm/arm.c (tls_reloc): Add TLS_GD32_FDPIC,
    	TLS_LDM32_FDPIC and TLS_IE32_FDPIC.
    	(arm_call_tls_get_addr): Add FDPIC support.
    	(legitimize_tls_address): Likewise.
    	(arm_emit_tls_decoration): Likewise.
    
    Change-Id: I4ea5034ff654540c4658d0a79fb92f70550cdf4a

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 8930ff2..724edea 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -2379,9 +2379,12 @@ char arm_arch_name[] = "__ARM_ARCH_PROFILE__";
 
 enum tls_reloc {
   TLS_GD32,
+  TLS_GD32_FDPIC,
   TLS_LDM32,
+  TLS_LDM32_FDPIC,
   TLS_LDO32,
   TLS_IE32,
+  TLS_IE32_FDPIC,
   TLS_LE32,
   TLS_DESCSEQ	/* GNU scheme */
 };
@@ -8742,22 +8745,33 @@ load_tls_operand (rtx x, rtx reg)
 static rtx_insn *
 arm_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc)
 {
-  rtx label, labelno, sum;
+  rtx label, labelno = NULL_RTX, sum;
 
   gcc_assert (reloc != TLS_DESCSEQ);
   start_sequence ();
 
-  labelno = GEN_INT (pic_labelno++);
-  label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
-  label = gen_rtx_CONST (VOIDmode, label);
+  if (TARGET_FDPIC)
+    {
+      sum = gen_rtx_UNSPEC (Pmode,
+			    gen_rtvec (2, x, GEN_INT (reloc)),
+			    UNSPEC_TLS);
+    }
+  else
+    {
+      labelno = GEN_INT (pic_labelno++);
+      label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
+      label = gen_rtx_CONST (VOIDmode, label);
 
-  sum = gen_rtx_UNSPEC (Pmode,
-			gen_rtvec (4, x, GEN_INT (reloc), label,
-				   GEN_INT (TARGET_ARM ? 8 : 4)),
-			UNSPEC_TLS);
+      sum = gen_rtx_UNSPEC (Pmode,
+			    gen_rtvec (4, x, GEN_INT (reloc), label,
+				       GEN_INT (TARGET_ARM ? 8 : 4)),
+			    UNSPEC_TLS);
+    }
   reg = load_tls_operand (sum, reg);
 
-  if (TARGET_ARM)
+  if (TARGET_FDPIC)
+      emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode, FDPIC_REGNUM)));
+  else if (TARGET_ARM)
     emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));
   else
     emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
@@ -8795,6 +8809,7 @@ arm_tls_descseq_addr (rtx x, rtx reg)
   return reg;
 }
 
+
 rtx
 legitimize_tls_address (rtx x, rtx reg)
 {
@@ -8807,6 +8822,8 @@ legitimize_tls_address (rtx x, rtx reg)
     case TLS_MODEL_GLOBAL_DYNAMIC:
       if (TARGET_GNU2_TLS)
 	{
+	  gcc_assert (TARGET_FDPIC);
+
 	  reg = arm_tls_descseq_addr (x, reg);
 
 	  tp = arm_load_tp (NULL_RTX);
@@ -8816,7 +8833,10 @@ legitimize_tls_address (rtx x, rtx reg)
       else
 	{
 	  /* Original scheme */
-	  insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);
+	  if (TARGET_FDPIC)
+	    insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32_FDPIC);
+	  else
+	    insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);
 	  dest = gen_reg_rtx (Pmode);
 	  emit_libcall_block (insns, dest, ret, x);
 	}
@@ -8825,6 +8845,8 @@ legitimize_tls_address (rtx x, rtx reg)
     case TLS_MODEL_LOCAL_DYNAMIC:
       if (TARGET_GNU2_TLS)
 	{
+	  gcc_assert (TARGET_FDPIC);
+
 	  reg = arm_tls_descseq_addr (x, reg);
 
 	  tp = arm_load_tp (NULL_RTX);
@@ -8833,7 +8855,10 @@ legitimize_tls_address (rtx x, rtx reg)
 	}
       else
 	{
-	  insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32);
+	  if (TARGET_FDPIC)
+	    insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32_FDPIC);
+	  else
+	    insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32);
 
 	  /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
 	     share the LDM result with other LD model accesses.  */
@@ -8852,23 +8877,35 @@ legitimize_tls_address (rtx x, rtx reg)
       return dest;
 
     case TLS_MODEL_INITIAL_EXEC:
-      labelno = GEN_INT (pic_labelno++);
-      label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
-      label = gen_rtx_CONST (VOIDmode, label);
-      sum = gen_rtx_UNSPEC (Pmode,
-			    gen_rtvec (4, x, GEN_INT (TLS_IE32), label,
-				       GEN_INT (TARGET_ARM ? 8 : 4)),
-			    UNSPEC_TLS);
-      reg = load_tls_operand (sum, reg);
-
-      if (TARGET_ARM)
-	emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));
-      else if (TARGET_THUMB2)
-	emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg, labelno));
+      if (TARGET_FDPIC)
+	{
+	  sum = gen_rtx_UNSPEC (Pmode,
+				gen_rtvec (2, x, GEN_INT (TLS_IE32_FDPIC)),
+				UNSPEC_TLS);
+	  reg = load_tls_operand (sum, reg);
+	  emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode, FDPIC_REGNUM)));
+	  emit_move_insn (reg, gen_rtx_MEM (Pmode, reg));
+	}
       else
 	{
-	  emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
-	  emit_move_insn (reg, gen_const_mem (SImode, reg));
+	  labelno = GEN_INT (pic_labelno++);
+	  label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
+	  label = gen_rtx_CONST (VOIDmode, label);
+	  sum = gen_rtx_UNSPEC (Pmode,
+				gen_rtvec (4, x, GEN_INT (TLS_IE32), label,
+					   GEN_INT (TARGET_ARM ? 8 : 4)),
+				UNSPEC_TLS);
+	  reg = load_tls_operand (sum, reg);
+
+	  if (TARGET_ARM)
+	    emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));
+	  else if (TARGET_THUMB2)
+	    emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg, labelno));
+	  else
+	    {
+	      emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
+	      emit_move_insn (reg, gen_const_mem (SImode, reg));
+	    }
 	}
 
       tp = arm_load_tp (NULL_RTX);
@@ -28205,15 +28242,24 @@ arm_emit_tls_decoration (FILE *fp, rtx x)
     case TLS_GD32:
       fputs ("(tlsgd)", fp);
       break;
+    case TLS_GD32_FDPIC:
+      fputs ("(tlsgd_fdpic)", fp);
+      break;
     case TLS_LDM32:
       fputs ("(tlsldm)", fp);
       break;
+    case TLS_LDM32_FDPIC:
+      fputs ("(tlsldm_fdpic)", fp);
+      break;
     case TLS_LDO32:
       fputs ("(tlsldo)", fp);
       break;
     case TLS_IE32:
       fputs ("(gottpoff)", fp);
       break;
+    case TLS_IE32_FDPIC:
+      fputs ("(gottpoff_fdpic)", fp);
+      break;
     case TLS_LE32:
       fputs ("(tpoff)", fp);
       break;
Christophe Lyon Sept. 9, 2019, 8:54 a.m. | #3
On Wed, 4 Sep 2019 at 22:03, Christophe Lyon <christophe.lyon@linaro.org> wrote:
>

> On Wed, 4 Sep 2019 at 16:16, Kyrill Tkachov <kyrylo.tkachov@foss.arm.com> wrote:

> >

> > Hi Christophe,

> >

> > On 5/15/19 1:39 PM, Christophe Lyon wrote:

> > > Support additional relocations: TLS_GD32_FDPIC, TLS_LDM32_FDPIC, and

> > > TLS_IE32_FDPIC.

> > >

> > > We do not support the GNU2 TLS dialect.

> > >

> > > 2019-XX-XX  Christophe Lyon  <christophe.lyon@st.com>

> > >         Mickaël Guêné <mickael.guene@st.com>

> > >

> > >         gcc/

> > >         * config/arm/arm.c (tls_reloc): Add TLS_GD32_FDPIC,

> > >         TLS_LDM32_FDPIC and TLS_IE32_FDPIC.

> > >         (arm_call_tls_get_addr): Add FDPIC support.

> > >         (legitimize_tls_address): Likewise.

> > >         (arm_emit_tls_decoration): Likewise.

> > >

> > > Change-Id: I4ea5034ff654540c4658d0a79fb92f70550cdf4a

> > >

> > > diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c

> > > index 99d13bf..5fc7a20 100644

> > > --- a/gcc/config/arm/arm.c

> > > +++ b/gcc/config/arm/arm.c

> > > @@ -2379,9 +2379,12 @@ char arm_arch_name[] = "__ARM_ARCH_PROFILE__";

> > >

> > >  enum tls_reloc {

> > >    TLS_GD32,

> > > +  TLS_GD32_FDPIC,

> > >    TLS_LDM32,

> > > +  TLS_LDM32_FDPIC,

> > >    TLS_LDO32,

> > >    TLS_IE32,

> > > +  TLS_IE32_FDPIC,

> > >    TLS_LE32,

> > >    TLS_DESCSEQ  /* GNU scheme */

> > >  };

> > > @@ -8760,20 +8763,34 @@ arm_call_tls_get_addr (rtx x, rtx reg, rtx

> > > *valuep, int reloc)

> > >    gcc_assert (reloc != TLS_DESCSEQ);

> > >    start_sequence ();

> > >

> > > -  labelno = GEN_INT (pic_labelno++);

> > > -  label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno),

> > > UNSPEC_PIC_LABEL);

> > > -  label = gen_rtx_CONST (VOIDmode, label);

> > > +  if (TARGET_FDPIC)

> > > +    {

> > > +      sum = gen_rtx_UNSPEC (Pmode,

> > > +                           gen_rtvec (2, x, GEN_INT (reloc)),

> > > +                           UNSPEC_TLS);

> > > +    }

> > > +  else

> > > +    {

> > > +      labelno = GEN_INT (pic_labelno++);

> > > +      label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno),

> > > UNSPEC_PIC_LABEL);

> > > +      label = gen_rtx_CONST (VOIDmode, label);

> > >

> > > -  sum = gen_rtx_UNSPEC (Pmode,

> > > -                       gen_rtvec (4, x, GEN_INT (reloc), label,

> > > -                                  GEN_INT (TARGET_ARM ? 8 : 4)),

> > > -                       UNSPEC_TLS);

> > > +      sum = gen_rtx_UNSPEC (Pmode,

> > > +                           gen_rtvec (4, x, GEN_INT (reloc), label,

> > > +                                      GEN_INT (TARGET_ARM ? 8 : 4)),

> > > +                           UNSPEC_TLS);

> > > +    }

> > >    reg = load_tls_operand (sum, reg);

> > >

> > > -  if (TARGET_ARM)

> > > -    emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));

> > > +  if (TARGET_FDPIC)

> > > +    {

> > > +      emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode,

> > > FDPIC_REGNUM)));

> > > +    }

> >

> > No {} around single statement.

> >

> > >    else

> > > -    emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));

> > > +    if (TARGET_ARM)

> > > +      emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));

> >

> >

> > Merge that "if" with the "else" in an "else if"

> >

> > > +    else

> > > +      emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));

> > >

> > >    *valuep = emit_library_call_value (get_tls_get_addr (), NULL_RTX,

> > >                                       LCT_PURE, /* LCT_CONST?  */

> > > @@ -8808,6 +8825,7 @@ arm_tls_descseq_addr (rtx x, rtx reg)

> > >    return reg;

> > >  }

> > >

> > > +

> > >  rtx

> > >  legitimize_tls_address (rtx x, rtx reg)

> > >  {

> > > @@ -8820,6 +8838,9 @@ legitimize_tls_address (rtx x, rtx reg)

> > >      case TLS_MODEL_GLOBAL_DYNAMIC:

> > >        if (TARGET_GNU2_TLS)

> > >          {

> > > +         if (TARGET_FDPIC)

> > > +           gcc_unreachable();

> > > +

> >

> > Use gcc_assert (TARGET_FDPIC)

> >

> >

> > >            reg = arm_tls_descseq_addr (x, reg);

> > >

> > >            tp = arm_load_tp (NULL_RTX);

> > > @@ -8829,7 +8850,10 @@ legitimize_tls_address (rtx x, rtx reg)

> > >        else

> > >          {

> > >            /* Original scheme */

> > > -         insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);

> > > +         if (TARGET_FDPIC)

> > > +           insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32_FDPIC);

> > > +         else

> > > +           insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);

> > >            dest = gen_reg_rtx (Pmode);

> > >            emit_libcall_block (insns, dest, ret, x);

> > >          }

> > > @@ -8838,6 +8862,9 @@ legitimize_tls_address (rtx x, rtx reg)

> > >      case TLS_MODEL_LOCAL_DYNAMIC:

> > >        if (TARGET_GNU2_TLS)

> > >          {

> > > +         if (TARGET_FDPIC)

> > > +           gcc_unreachable();

> > > +

> >

> > Likewise.

> >

> > Ok with those changes.

>

> Thanks, here is the updated version, with the initialization of labelno in

> call_tls_get_addr moved from patch 4/21.

>

There was an obvious mistake in the previous update: the attached
version inverts the assert condition to:
gcc_assert (!TARGET_FDPIC);


>

> >

> > Thanks,

> >

> > Kyrill

> >

> >

> > >            reg = arm_tls_descseq_addr (x, reg);

> > >

> > >            tp = arm_load_tp (NULL_RTX);

> > > @@ -8846,7 +8873,10 @@ legitimize_tls_address (rtx x, rtx reg)

> > >          }

> > >        else

> > >          {

> > > -         insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32);

> > > +         if (TARGET_FDPIC)

> > > +           insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32_FDPIC);

> > > +         else

> > > +           insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32);

> > >

> > >            /* Attach a unique REG_EQUIV, to allow the RTL optimizers to

> > >               share the LDM result with other LD model accesses.  */

> > > @@ -8865,23 +8895,35 @@ legitimize_tls_address (rtx x, rtx reg)

> > >        return dest;

> > >

> > >      case TLS_MODEL_INITIAL_EXEC:

> > > -      labelno = GEN_INT (pic_labelno++);

> > > -      label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno),

> > > UNSPEC_PIC_LABEL);

> > > -      label = gen_rtx_CONST (VOIDmode, label);

> > > -      sum = gen_rtx_UNSPEC (Pmode,

> > > -                           gen_rtvec (4, x, GEN_INT (TLS_IE32), label,

> > > -                                      GEN_INT (TARGET_ARM ? 8 : 4)),

> > > -                           UNSPEC_TLS);

> > > -      reg = load_tls_operand (sum, reg);

> > > -

> > > -      if (TARGET_ARM)

> > > -       emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));

> > > -      else if (TARGET_THUMB2)

> > > -       emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg, labelno));

> > > +      if (TARGET_FDPIC)

> > > +       {

> > > +         sum = gen_rtx_UNSPEC (Pmode,

> > > +                               gen_rtvec (2, x, GEN_INT

> > > (TLS_IE32_FDPIC)),

> > > +                               UNSPEC_TLS);

> > > +         reg = load_tls_operand (sum, reg);

> > > +         emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode,

> > > FDPIC_REGNUM)));

> > > +         emit_move_insn (reg, gen_rtx_MEM (Pmode, reg));

> > > +       }

> > >        else

> > >          {

> > > -         emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));

> > > -         emit_move_insn (reg, gen_const_mem (SImode, reg));

> > > +         labelno = GEN_INT (pic_labelno++);

> > > +         label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno),

> > > UNSPEC_PIC_LABEL);

> > > +         label = gen_rtx_CONST (VOIDmode, label);

> > > +         sum = gen_rtx_UNSPEC (Pmode,

> > > +                               gen_rtvec (4, x, GEN_INT (TLS_IE32),

> > > label,

> > > +                                          GEN_INT (TARGET_ARM ? 8 : 4)),

> > > +                               UNSPEC_TLS);

> > > +         reg = load_tls_operand (sum, reg);

> > > +

> > > +         if (TARGET_ARM)

> > > +           emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));

> > > +         else if (TARGET_THUMB2)

> > > +           emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg,

> > > labelno));

> > > +         else

> > > +           {

> > > +             emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));

> > > +             emit_move_insn (reg, gen_const_mem (SImode, reg));

> > > +           }

> > >          }

> > >

> > >        tp = arm_load_tp (NULL_RTX);

> > > @@ -28218,15 +28260,24 @@ arm_emit_tls_decoration (FILE *fp, rtx x)

> > >      case TLS_GD32:

> > >        fputs ("(tlsgd)", fp);

> > >        break;

> > > +    case TLS_GD32_FDPIC:

> > > +      fputs ("(tlsgd_fdpic)", fp);

> > > +      break;

> > >      case TLS_LDM32:

> > >        fputs ("(tlsldm)", fp);

> > >        break;

> > > +    case TLS_LDM32_FDPIC:

> > > +      fputs ("(tlsldm_fdpic)", fp);

> > > +      break;

> > >      case TLS_LDO32:

> > >        fputs ("(tlsldo)", fp);

> > >        break;

> > >      case TLS_IE32:

> > >        fputs ("(gottpoff)", fp);

> > >        break;

> > > +    case TLS_IE32_FDPIC:

> > > +      fputs ("(gottpoff_fdpic)", fp);

> > > +      break;

> > >      case TLS_LE32:

> > >        fputs ("(tpoff)", fp);

> > >        break;

> > > --

> > > 2.6.3

> > >
commit 481d4161a6cdf88091cd2fef7ee7fe6b8a836d18
Author: Christophe Lyon <christophe.lyon@linaro.org>
Date:   Thu Feb 8 14:42:05 2018 +0100

    [ARM] FDPIC: Implement TLS support.
    
    Support additional relocations: TLS_GD32_FDPIC, TLS_LDM32_FDPIC, and
    TLS_IE32_FDPIC.
    
    We do not support the GNU2 TLS dialect.
    
    2019-XX-XX  Christophe Lyon  <christophe.lyon@st.com>
    	Mickaël Guêné <mickael.guene@st.com>
    
    	gcc/
    	* config/arm/arm.c (tls_reloc): Add TLS_GD32_FDPIC,
    	TLS_LDM32_FDPIC and TLS_IE32_FDPIC.
    	(arm_call_tls_get_addr): Add FDPIC support.
    	(legitimize_tls_address): Likewise.
    	(arm_emit_tls_decoration): Likewise.
    
    Change-Id: I4ea5034ff654540c4658d0a79fb92f70550cdf4a

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 8930ff2..724edea 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -2379,9 +2379,12 @@ char arm_arch_name[] = "__ARM_ARCH_PROFILE__";
 
 enum tls_reloc {
   TLS_GD32,
+  TLS_GD32_FDPIC,
   TLS_LDM32,
+  TLS_LDM32_FDPIC,
   TLS_LDO32,
   TLS_IE32,
+  TLS_IE32_FDPIC,
   TLS_LE32,
   TLS_DESCSEQ	/* GNU scheme */
 };
@@ -8742,22 +8745,33 @@ load_tls_operand (rtx x, rtx reg)
 static rtx_insn *
 arm_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc)
 {
-  rtx label, labelno, sum;
+  rtx label, labelno = NULL_RTX, sum;
 
   gcc_assert (reloc != TLS_DESCSEQ);
   start_sequence ();
 
-  labelno = GEN_INT (pic_labelno++);
-  label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
-  label = gen_rtx_CONST (VOIDmode, label);
+  if (TARGET_FDPIC)
+    {
+      sum = gen_rtx_UNSPEC (Pmode,
+			    gen_rtvec (2, x, GEN_INT (reloc)),
+			    UNSPEC_TLS);
+    }
+  else
+    {
+      labelno = GEN_INT (pic_labelno++);
+      label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
+      label = gen_rtx_CONST (VOIDmode, label);
 
-  sum = gen_rtx_UNSPEC (Pmode,
-			gen_rtvec (4, x, GEN_INT (reloc), label,
-				   GEN_INT (TARGET_ARM ? 8 : 4)),
-			UNSPEC_TLS);
+      sum = gen_rtx_UNSPEC (Pmode,
+			    gen_rtvec (4, x, GEN_INT (reloc), label,
+				       GEN_INT (TARGET_ARM ? 8 : 4)),
+			    UNSPEC_TLS);
+    }
   reg = load_tls_operand (sum, reg);
 
-  if (TARGET_ARM)
+  if (TARGET_FDPIC)
+      emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode, FDPIC_REGNUM)));
+  else if (TARGET_ARM)
     emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));
   else
     emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
@@ -8795,6 +8809,7 @@ arm_tls_descseq_addr (rtx x, rtx reg)
   return reg;
 }
 
+
 rtx
 legitimize_tls_address (rtx x, rtx reg)
 {
@@ -8807,6 +8822,8 @@ legitimize_tls_address (rtx x, rtx reg)
     case TLS_MODEL_GLOBAL_DYNAMIC:
       if (TARGET_GNU2_TLS)
 	{
+	  gcc_assert (!TARGET_FDPIC);
+
 	  reg = arm_tls_descseq_addr (x, reg);
 
 	  tp = arm_load_tp (NULL_RTX);
@@ -8816,7 +8833,10 @@ legitimize_tls_address (rtx x, rtx reg)
       else
 	{
 	  /* Original scheme */
-	  insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);
+	  if (TARGET_FDPIC)
+	    insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32_FDPIC);
+	  else
+	    insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);
 	  dest = gen_reg_rtx (Pmode);
 	  emit_libcall_block (insns, dest, ret, x);
 	}
@@ -8825,6 +8845,8 @@ legitimize_tls_address (rtx x, rtx reg)
     case TLS_MODEL_LOCAL_DYNAMIC:
       if (TARGET_GNU2_TLS)
 	{
+	  gcc_assert (!TARGET_FDPIC);
+
 	  reg = arm_tls_descseq_addr (x, reg);
 
 	  tp = arm_load_tp (NULL_RTX);
@@ -8833,7 +8855,10 @@ legitimize_tls_address (rtx x, rtx reg)
 	}
       else
 	{
-	  insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32);
+	  if (TARGET_FDPIC)
+	    insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32_FDPIC);
+	  else
+	    insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32);
 
 	  /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
 	     share the LDM result with other LD model accesses.  */
@@ -8852,23 +8877,35 @@ legitimize_tls_address (rtx x, rtx reg)
       return dest;
 
     case TLS_MODEL_INITIAL_EXEC:
-      labelno = GEN_INT (pic_labelno++);
-      label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
-      label = gen_rtx_CONST (VOIDmode, label);
-      sum = gen_rtx_UNSPEC (Pmode,
-			    gen_rtvec (4, x, GEN_INT (TLS_IE32), label,
-				       GEN_INT (TARGET_ARM ? 8 : 4)),
-			    UNSPEC_TLS);
-      reg = load_tls_operand (sum, reg);
-
-      if (TARGET_ARM)
-	emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));
-      else if (TARGET_THUMB2)
-	emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg, labelno));
+      if (TARGET_FDPIC)
+	{
+	  sum = gen_rtx_UNSPEC (Pmode,
+				gen_rtvec (2, x, GEN_INT (TLS_IE32_FDPIC)),
+				UNSPEC_TLS);
+	  reg = load_tls_operand (sum, reg);
+	  emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode, FDPIC_REGNUM)));
+	  emit_move_insn (reg, gen_rtx_MEM (Pmode, reg));
+	}
       else
 	{
-	  emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
-	  emit_move_insn (reg, gen_const_mem (SImode, reg));
+	  labelno = GEN_INT (pic_labelno++);
+	  label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
+	  label = gen_rtx_CONST (VOIDmode, label);
+	  sum = gen_rtx_UNSPEC (Pmode,
+				gen_rtvec (4, x, GEN_INT (TLS_IE32), label,
+					   GEN_INT (TARGET_ARM ? 8 : 4)),
+				UNSPEC_TLS);
+	  reg = load_tls_operand (sum, reg);
+
+	  if (TARGET_ARM)
+	    emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));
+	  else if (TARGET_THUMB2)
+	    emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg, labelno));
+	  else
+	    {
+	      emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
+	      emit_move_insn (reg, gen_const_mem (SImode, reg));
+	    }
 	}
 
       tp = arm_load_tp (NULL_RTX);
@@ -28205,15 +28242,24 @@ arm_emit_tls_decoration (FILE *fp, rtx x)
     case TLS_GD32:
       fputs ("(tlsgd)", fp);
       break;
+    case TLS_GD32_FDPIC:
+      fputs ("(tlsgd_fdpic)", fp);
+      break;
     case TLS_LDM32:
       fputs ("(tlsldm)", fp);
       break;
+    case TLS_LDM32_FDPIC:
+      fputs ("(tlsldm_fdpic)", fp);
+      break;
     case TLS_LDO32:
       fputs ("(tlsldo)", fp);
       break;
     case TLS_IE32:
       fputs ("(gottpoff)", fp);
       break;
+    case TLS_IE32_FDPIC:
+      fputs ("(gottpoff_fdpic)", fp);
+      break;
     case TLS_LE32:
       fputs ("(tpoff)", fp);
       break;

Patch

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 99d13bf..5fc7a20 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -2379,9 +2379,12 @@  char arm_arch_name[] = "__ARM_ARCH_PROFILE__";
 
 enum tls_reloc {
   TLS_GD32,
+  TLS_GD32_FDPIC,
   TLS_LDM32,
+  TLS_LDM32_FDPIC,
   TLS_LDO32,
   TLS_IE32,
+  TLS_IE32_FDPIC,
   TLS_LE32,
   TLS_DESCSEQ	/* GNU scheme */
 };
@@ -8760,20 +8763,34 @@  arm_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc)
   gcc_assert (reloc != TLS_DESCSEQ);
   start_sequence ();
 
-  labelno = GEN_INT (pic_labelno++);
-  label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
-  label = gen_rtx_CONST (VOIDmode, label);
+  if (TARGET_FDPIC)
+    {
+      sum = gen_rtx_UNSPEC (Pmode,
+			    gen_rtvec (2, x, GEN_INT (reloc)),
+			    UNSPEC_TLS);
+    }
+  else
+    {
+      labelno = GEN_INT (pic_labelno++);
+      label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
+      label = gen_rtx_CONST (VOIDmode, label);
 
-  sum = gen_rtx_UNSPEC (Pmode,
-			gen_rtvec (4, x, GEN_INT (reloc), label,
-				   GEN_INT (TARGET_ARM ? 8 : 4)),
-			UNSPEC_TLS);
+      sum = gen_rtx_UNSPEC (Pmode,
+			    gen_rtvec (4, x, GEN_INT (reloc), label,
+				       GEN_INT (TARGET_ARM ? 8 : 4)),
+			    UNSPEC_TLS);
+    }
   reg = load_tls_operand (sum, reg);
 
-  if (TARGET_ARM)
-    emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));
+  if (TARGET_FDPIC)
+    {
+      emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode, FDPIC_REGNUM)));
+    }
   else
-    emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
+    if (TARGET_ARM)
+      emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));
+    else
+      emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
 
   *valuep = emit_library_call_value (get_tls_get_addr (), NULL_RTX,
 				     LCT_PURE, /* LCT_CONST?  */
@@ -8808,6 +8825,7 @@  arm_tls_descseq_addr (rtx x, rtx reg)
   return reg;
 }
 
+
 rtx
 legitimize_tls_address (rtx x, rtx reg)
 {
@@ -8820,6 +8838,9 @@  legitimize_tls_address (rtx x, rtx reg)
     case TLS_MODEL_GLOBAL_DYNAMIC:
       if (TARGET_GNU2_TLS)
 	{
+	  if (TARGET_FDPIC)
+	    gcc_unreachable();
+
 	  reg = arm_tls_descseq_addr (x, reg);
 
 	  tp = arm_load_tp (NULL_RTX);
@@ -8829,7 +8850,10 @@  legitimize_tls_address (rtx x, rtx reg)
       else
 	{
 	  /* Original scheme */
-	  insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);
+	  if (TARGET_FDPIC)
+	    insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32_FDPIC);
+	  else
+	    insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);
 	  dest = gen_reg_rtx (Pmode);
 	  emit_libcall_block (insns, dest, ret, x);
 	}
@@ -8838,6 +8862,9 @@  legitimize_tls_address (rtx x, rtx reg)
     case TLS_MODEL_LOCAL_DYNAMIC:
       if (TARGET_GNU2_TLS)
 	{
+	  if (TARGET_FDPIC)
+	    gcc_unreachable();
+
 	  reg = arm_tls_descseq_addr (x, reg);
 
 	  tp = arm_load_tp (NULL_RTX);
@@ -8846,7 +8873,10 @@  legitimize_tls_address (rtx x, rtx reg)
 	}
       else
 	{
-	  insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32);
+	  if (TARGET_FDPIC)
+	    insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32_FDPIC);
+	  else
+	    insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32);
 
 	  /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
 	     share the LDM result with other LD model accesses.  */
@@ -8865,23 +8895,35 @@  legitimize_tls_address (rtx x, rtx reg)
       return dest;
 
     case TLS_MODEL_INITIAL_EXEC:
-      labelno = GEN_INT (pic_labelno++);
-      label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
-      label = gen_rtx_CONST (VOIDmode, label);
-      sum = gen_rtx_UNSPEC (Pmode,
-			    gen_rtvec (4, x, GEN_INT (TLS_IE32), label,
-				       GEN_INT (TARGET_ARM ? 8 : 4)),
-			    UNSPEC_TLS);
-      reg = load_tls_operand (sum, reg);
-
-      if (TARGET_ARM)
-	emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));
-      else if (TARGET_THUMB2)
-	emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg, labelno));
+      if (TARGET_FDPIC)
+	{
+	  sum = gen_rtx_UNSPEC (Pmode,
+				gen_rtvec (2, x, GEN_INT (TLS_IE32_FDPIC)),
+				UNSPEC_TLS);
+	  reg = load_tls_operand (sum, reg);
+	  emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode, FDPIC_REGNUM)));
+	  emit_move_insn (reg, gen_rtx_MEM (Pmode, reg));
+	}
       else
 	{
-	  emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
-	  emit_move_insn (reg, gen_const_mem (SImode, reg));
+	  labelno = GEN_INT (pic_labelno++);
+	  label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
+	  label = gen_rtx_CONST (VOIDmode, label);
+	  sum = gen_rtx_UNSPEC (Pmode,
+				gen_rtvec (4, x, GEN_INT (TLS_IE32), label,
+					   GEN_INT (TARGET_ARM ? 8 : 4)),
+				UNSPEC_TLS);
+	  reg = load_tls_operand (sum, reg);
+
+	  if (TARGET_ARM)
+	    emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));
+	  else if (TARGET_THUMB2)
+	    emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg, labelno));
+	  else
+	    {
+	      emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
+	      emit_move_insn (reg, gen_const_mem (SImode, reg));
+	    }
 	}
 
       tp = arm_load_tp (NULL_RTX);
@@ -28218,15 +28260,24 @@  arm_emit_tls_decoration (FILE *fp, rtx x)
     case TLS_GD32:
       fputs ("(tlsgd)", fp);
       break;
+    case TLS_GD32_FDPIC:
+      fputs ("(tlsgd_fdpic)", fp);
+      break;
     case TLS_LDM32:
       fputs ("(tlsldm)", fp);
       break;
+    case TLS_LDM32_FDPIC:
+      fputs ("(tlsldm_fdpic)", fp);
+      break;
     case TLS_LDO32:
       fputs ("(tlsldo)", fp);
       break;
     case TLS_IE32:
       fputs ("(gottpoff)", fp);
       break;
+    case TLS_IE32_FDPIC:
+      fputs ("(gottpoff_fdpic)", fp);
+      break;
     case TLS_LE32:
       fputs ("(tpoff)", fp);
       break;