public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [ARM] TLS Descriptor support
@ 2011-05-10 11:23 Nathan Sidwell
  2011-05-10 13:14 ` Joseph S. Myers
                   ` (4 more replies)
  0 siblings, 5 replies; 17+ messages in thread
From: Nathan Sidwell @ 2011-05-10 11:23 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1050 bytes --]

This patch implements TLS descriptor support in GCC.  TLS descriptors are 
described at http://www.codesourcery.com/publications/RFC-TLSDESC-ARM.txt and 
blessed by ARM, who have reserved the relocation numbers.

Binutils and GLIBC patches are already committed (there is an orthogonal glibc 
patch to do with make dependencies that I need to post though).

This patch adds a --with-tls={arm|gnu} configuration option, to specify the 
default scheme.  It can be overridden with a -mtls-dialect={arm|gnu} option 
(this is the name used by the x86 backend, which also has tlsdescriptor 
support).  I have not added --with-tls support to the x86 bits of config.gcc 
etc, but it would be simple to do so.

The arm.{c,h,md} changes are fairly mechanical -- a new tls pattern and smarts 
to emit it appropriately.

This patch has been tested for both default arm and default gnu tls schemes 
using the gcc and glibc testsuites for an arm-linux-gnueabi target.

ok?

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery


[-- Attachment #2: gcc.patch --]
[-- Type: text/x-patch, Size: 14706 bytes --]

2011-05-10  Nathan Sidwell  <nathan@codesourcery.com>

	* doc/invoke.texi (ARM Options): Document -mtls-dialect option.
	* doc/install.texi (Configuration): Document --with-tls.
	* config.gcc (arm*-*-linux*): Default to arm-style tls.
	(arm*-*-*): Add --with-tls option.
	(all_defaults): Add 'tls'.
	* config/arm/arm.c (target_tls_dialect): New.
	(enum tls_reloc): Add TLS_DESCSEQ.
	(arm_override_options): Process target_tls_dialect_switch value.
	(arm_call_tls_get_addr): Clean up. Assert not tls descriptor.
	(arm_tls_descseq_addr): New.
	(legitimize_tls_address): Add tlsdesc support.
	(arm_cannot_copy_insn_p): Check for tlscall.
	(arm_emit_tls_decoration): Likewise.
	* config/arm/arm.h (TARGET_ARM_TLS, TARGET_GNU_TLS): New.
	(OPTION_DEFAULT_SPECS): Add with-tls support.
	(enum arm_tls_type): New.
	(target_tls_dialect): New.
	* config/arm/arm.opt (mtls-dialect): New switch.
	* config/arm/arm.md (tlscall): New.

	testsuite/
	* gcc.target/arm/tlscall.c: New.

Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 172962)
+++ doc/invoke.texi	(working copy)
@@ -469,7 +469,7 @@ Objective-C and Objective-C++ Dialects}.
 -mthumb  -marm @gol
 -mtpcs-frame  -mtpcs-leaf-frame @gol
 -mcaller-super-interworking  -mcallee-super-interworking @gol
--mtp=@var{name} @gol
+-mtp=@var{name} -mtls-dialect=@var{dialect} @gol
 -mword-relocations @gol
 -mfix-cortex-m3-ldrd}
 
@@ -10332,6 +10332,17 @@ models are @option{soft}, which generate
 best available method for the selected processor.  The default setting is
 @option{auto}.
 
+@item -mtls-dialect=@var{dialect}
+@opindex mtls-dialect
+Specify the dialect to use for accessing thread local storage.  Two
+dialects are supported - @option{arm} and @option{gnu}.  The
+@option{arm} dialect selects the ARM EABI scheme for supporting local
+and global dynamic tls models.  The @option{gnu} dialect selects the
+experimental GNU scheme.  The GNU scheme is compatible with the ARM
+scheme, but does require new assembler, linker and library
+support.  Initial and local exec TLS models are unaffected by this
+option and use the ARM EABI scheme.
+
 @item -mword-relocations
 @opindex mword-relocations
 Only generate absolute relocations on word sized values (i.e. R_ARM_ABS32).
Index: doc/install.texi
===================================================================
--- doc/install.texi	(revision 172962)
+++ doc/install.texi	(working copy)
@@ -1003,6 +1003,12 @@ information normally used on 386 SVR4 pl
 workable alternative.  This requires gas and gdb, as the normal SVR4
 tools can not generate or interpret stabs.
 
+@item --with-tls=@var{dialect}
+Specify the default tls dialect, for systems were there is a choice.
+For ARM targets, possible values for @var{dialect} are @code{arm} or
+@code{gnu}, which select between the ARM EABI dialect and the GNU TLS
+descriptor-based dialect.
+
 @item --disable-multilib
 Specify that multiple target
 libraries to support different target variants, calling
Index: testsuite/gcc.target/arm/tlscall.c
===================================================================
--- testsuite/gcc.target/arm/tlscall.c	(revision 0)
+++ testsuite/gcc.target/arm/tlscall.c	(revision 0)
@@ -0,0 +1,31 @@
+/* Test non-duplication of tlscall insn */
+
+/* { dg-do assemble } */
+/* { dg-options "-O2 -fPIC -mtls-dialect=gnu" } */
+
+typedef struct _IO_FILE FILE;
+
+extern int foo(void);
+extern int bar(void);
+
+void uuid__generate_time()
+{
+ static int has_init = 0;
+ static __thread int state_fd = -2;
+ static __thread FILE *state_f;
+
+ if (!has_init) {
+   foo();
+   has_init = 1;
+ }
+
+ if (state_fd == -2) {
+  if (!state_f) {
+   state_fd = -1;
+  }
+ }
+ if (state_fd >= 0) {
+  while (bar() < 0) {}
+ }
+
+}
Index: config.gcc
===================================================================
--- config.gcc	(revision 172962)
+++ config.gcc	(working copy)
@@ -813,6 +813,7 @@ arm*-*-linux*)			# ARM GNU/Linux with EL
 	    tmake_file="$tmake_file arm/t-linux"
 	    ;;
 	esac
+	with_tls=${with_tls:arm}
 	tm_file="$tm_file arm/aout.h arm/arm.h"
 	tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp"
 	;;
@@ -3064,7 +3065,7 @@ case "${target}" in
 		;;
 
 	arm*-*-*)
-		supported_defaults="arch cpu float tune fpu abi mode"
+		supported_defaults="arch cpu float tune fpu abi mode tls"
 		for which in cpu tune; do
 			# See if it matches any of the entries in arm-cores.def
 			eval "val=\$with_$which"
@@ -3147,6 +3148,17 @@ case "${target}" in
 			;;
 		esac
 
+		case "$with_tls" in
+		"" \
+		| arm | gnu)
+			# OK
+			;;
+		*)
+			echo "Unknown TLS method used in --with-tls=$with_tls" 1>&2
+			exit 1
+			;;
+		esac
+
 		if test "x$with_arch" != x && test "x$with_cpu" != x; then
 			echo "Warning: --with-arch overrides --with-cpu=$with_cpu" 1>&2
 		fi
@@ -3624,7 +3636,7 @@ case ${target} in
 esac
 
 t=
-all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu divide llsc mips-plt synci"
+all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu divide llsc mips-plt synci tls"
 for option in $all_defaults
 do
 	eval "val=\$with_"`echo $option | sed s/-/_/g`
Index: config/arm/arm.c
===================================================================
--- config/arm/arm.c	(revision 172962)
+++ config/arm/arm.c	(working copy)
@@ -644,6 +644,9 @@ enum arm_abi_type arm_abi;
 /* Which thread pointer model to use.  */
 enum arm_tp_type target_thread_pointer = TP_AUTO;
 
+/* Which tls dialect to use.  */
+enum arm_tls_type target_tls_dialect = TLS_ARM;
+
 /* Used to parse -mstructure_size_boundary command line option.  */
 int    arm_structure_size_boundary = DEFAULT_STRUCTURE_SIZE_BOUNDARY;
 
@@ -1031,7 +1034,8 @@ enum tls_reloc {
   TLS_LDM32,
   TLS_LDO32,
   TLS_IE32,
-  TLS_LE32
+  TLS_LE32,
+  TLS_DESCSEQ	/* GNU scheme */
 };
 
 /* The maximum number of insns to be used when loading a constant.  */
@@ -1755,6 +1759,17 @@ arm_option_override (void)
 	error ("invalid thread pointer option: -mtp=%s", target_thread_switch);
     }
 
+  if (target_tls_dialect_switch)
+    {
+      if (strcmp (target_tls_dialect_switch, "arm") == 0)
+	target_tls_dialect = TLS_ARM;
+      else if (strcmp (target_tls_dialect_switch, "gnu") == 0)
+	target_tls_dialect = TLS_GNU;
+      else
+	error ("invalid thread dialect option: -mtls-dialect=%s",
+	       target_tls_dialect_switch);
+    }
+
   /* Use the cp15 method if it is available.  */
   if (target_thread_pointer == TP_AUTO)
     {
@@ -5957,6 +5972,7 @@ arm_call_tls_get_addr (rtx x, rtx reg, r
 {
   rtx insns, label, labelno, sum;
 
+  gcc_assert (reloc != TLS_DESCSEQ);
   start_sequence ();
 
   labelno = GEN_INT (pic_labelno++);
@@ -5971,20 +5987,42 @@ arm_call_tls_get_addr (rtx x, rtx reg, r
 
   if (TARGET_ARM)
     emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));
-  else if (TARGET_THUMB2)
-    emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
-  else /* TARGET_THUMB1 */
+  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?  */
+  
+  *valuep = emit_library_call_value (get_tls_get_addr (), NULL_RTX,
+				     LCT_PURE, /* LCT_CONST?  */
 				     Pmode, 1, reg, Pmode);
-
+  
   insns = get_insns ();
   end_sequence ();
 
   return insns;
 }
 
+static rtx
+arm_tls_descseq_addr (rtx x, rtx reg)
+{
+  rtx labelno = GEN_INT (pic_labelno++);
+  rtx label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
+  rtx sum = gen_rtx_UNSPEC (Pmode,
+			    gen_rtvec (4, x, GEN_INT (TLS_DESCSEQ),
+				       gen_rtx_CONST (VOIDmode, label),
+				       GEN_INT (!TARGET_ARM)),
+			    UNSPEC_TLS);
+  rtx reg0 = load_tls_operand (sum, gen_rtx_REG (SImode, 0));
+  
+  emit_insn (gen_tlscall (x, labelno));
+  if (!reg)
+    reg = gen_reg_rtx (SImode);
+  else
+    gcc_assert (REGNO (reg) != 0);
+
+  emit_move_insn (reg, reg0);
+
+  return reg;
+}
+
 rtx
 legitimize_tls_address (rtx x, rtx reg)
 {
@@ -5994,26 +6032,49 @@ legitimize_tls_address (rtx x, rtx reg)
   switch (model)
     {
     case TLS_MODEL_GLOBAL_DYNAMIC:
-      insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);
-      dest = gen_reg_rtx (Pmode);
-      emit_libcall_block (insns, dest, ret, x);
-      return dest;
+      if (TARGET_ARM_TLS)
+	{
+	  insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);
+	  dest = gen_reg_rtx (Pmode);
+	  emit_libcall_block (insns, dest, ret, x);
+	  return dest;
+	}
+      else
+	{
+	  reg = arm_tls_descseq_addr (x, reg);
 
-    case TLS_MODEL_LOCAL_DYNAMIC:
-      insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32);
+	  tp = arm_load_tp (NULL_RTX);
+	  
+	  return gen_rtx_PLUS (Pmode, tp, reg);
+	}
 
-      /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
-	 share the LDM result with other LD model accesses.  */
-      eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const1_rtx),
-			    UNSPEC_TLS);
-      dest = gen_reg_rtx (Pmode);
-      emit_libcall_block (insns, dest, ret, eqv);
+    case TLS_MODEL_LOCAL_DYNAMIC:
+      if (TARGET_ARM_TLS)
+	{
+	  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.  */
+	  eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const1_rtx),
+				UNSPEC_TLS);
+	  dest = gen_reg_rtx (Pmode);
+	  emit_libcall_block (insns, dest, ret, eqv);
+	  
+	  /* Load the addend.  */
+	  addend = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, x,
+						     GEN_INT (TLS_LDO32)),
+				   UNSPEC_TLS);
+	  addend = force_reg (SImode, gen_rtx_CONST (SImode, addend));
+	  return gen_rtx_PLUS (Pmode, dest, addend);
+	}
+      else
+	{
+	  reg = arm_tls_descseq_addr (x, reg);
 
-      /* Load the addend.  */
-      addend = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, x, GEN_INT (TLS_LDO32)),
-			       UNSPEC_TLS);
-      addend = force_reg (SImode, gen_rtx_CONST (SImode, addend));
-      return gen_rtx_PLUS (Pmode, dest, addend);
+	  tp = arm_load_tp (NULL_RTX);
+	  
+	  return gen_rtx_PLUS (Pmode, tp, reg);
+	}
 
     case TLS_MODEL_INITIAL_EXEC:
       labelno = GEN_INT (pic_labelno++);
@@ -9445,6 +9506,11 @@ arm_note_pic_base (rtx *x, void *date AT
 static bool
 arm_cannot_copy_insn_p (rtx insn)
 {
+  /* The tls call insn cannot be copied, as it is paired with a data
+     word.  */
+  if (recog_memoized (insn) == CODE_FOR_tlscall)
+    return true;
+  
   return for_each_rtx (&PATTERN (insn), arm_note_pic_base, NULL);
 }
 
@@ -22985,6 +23051,9 @@ arm_emit_tls_decoration (FILE *fp, rtx x
     case TLS_LE32:
       fputs ("(tpoff)", fp);
       break;
+    case TLS_DESCSEQ:
+      fputs ("(tlsdesc)", fp);
+      break;
     default:
       gcc_unreachable ();
     }
@@ -22994,9 +23063,11 @@ arm_emit_tls_decoration (FILE *fp, rtx x
     case TLS_GD32:
     case TLS_LDM32:
     case TLS_IE32:
+    case TLS_DESCSEQ:
       fputs (" + (. - ", fp);
       output_addr_const (fp, XVECEXP (x, 0, 2));
-      fputs (" - ", fp);
+      /* For DESCSEQ the 3rd operand encodes thumbness, and is added */
+      fputs (reloc == TLS_DESCSEQ ? " + " : " - ", fp);
       output_addr_const (fp, XVECEXP (x, 0, 3));
       fputc (')', fp);
       break;
Index: config/arm/arm.h
===================================================================
--- config/arm/arm.h	(revision 172962)
+++ config/arm/arm.h	(working copy)
@@ -218,6 +218,8 @@ extern void (*arm_lang_output_object_att
 
 #define TARGET_HARD_TP			(target_thread_pointer == TP_CP15)
 #define TARGET_SOFT_TP			(target_thread_pointer == TP_SOFT)
+#define TARGET_ARM_TLS			(target_tls_dialect == TLS_ARM)
+#define TARGET_GNU_TLS			(target_tls_dialect == TLS_GNU)
 
 /* Only 16-bit thumb code.  */
 #define TARGET_THUMB1			(TARGET_THUMB && !arm_arch_thumb2)
@@ -306,7 +308,8 @@ extern void (*arm_lang_output_object_att
      by -march).
    --with-float is ignored if -mfloat-abi is specified.
    --with-fpu is ignored if -mfpu is specified.
-   --with-abi is ignored is -mabi is specified.  */
+   --with-abi is ignored if -mabi is specified.
+   --with-tls is ignored if -mtls-dialect is specified. */
 #define OPTION_DEFAULT_SPECS \
   {"arch", "%{!march=*:%{!mcpu=*:-march=%(VALUE)}}" }, \
   {"cpu", "%{!march=*:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
@@ -314,7 +317,8 @@ extern void (*arm_lang_output_object_att
   {"float", "%{!mfloat-abi=*:-mfloat-abi=%(VALUE)}" }, \
   {"fpu", "%{!mfpu=*:-mfpu=%(VALUE)}"}, \
   {"abi", "%{!mabi=*:-mabi=%(VALUE)}"}, \
-  {"mode", "%{!marm:%{!mthumb:-m%(VALUE)}}"},
+  {"mode", "%{!marm:%{!mthumb:-m%(VALUE)}}"}, \
+  {"tls", "%{!mtls-dialect:-mtls-dialect=%(VALUE)}"},
 
 /* Which floating point model to use.  */
 enum arm_fp_model
@@ -400,7 +404,13 @@ enum arm_tp_type {
   TP_CP15
 };
 
+enum arm_tls_type {
+  TLS_ARM,
+  TLS_GNU
+};
+
 extern enum arm_tp_type target_thread_pointer;
+extern enum arm_tls_type target_tls_dialect;
 
 /* Nonzero if this chip supports the ARM Architecture 3M extensions.  */
 extern int arm_arch3m;
Index: config/arm/arm.opt
===================================================================
--- config/arm/arm.opt	(revision 172962)
+++ config/arm/arm.opt	(working copy)
@@ -138,6 +138,10 @@ mthumb-interwork
 Target Report Mask(INTERWORK)
 Support calls between Thumb and ARM instruction sets
 
+mtls-dialect=
+Target RejectNegative Joined Var(target_tls_dialect_switch)
+Specify thread local storage scheme
+
 mtp=
 Target RejectNegative Joined Var(target_thread_switch)
 Specify how to access the thread pointer
Index: config/arm/arm.md
===================================================================
--- config/arm/arm.md	(revision 172962)
+++ config/arm/arm.md	(working copy)
@@ -10620,6 +10620,28 @@
   [(set_attr "conds" "clob")]
 )
 
+;; tls descriptor call
+(define_insn "tlscall"
+  [(set (reg:SI 0) (unspec:SI [(reg:SI 0)
+                               (match_operand:SI 0 "" "X")
+			       (match_operand 1 "" "")] UNSPEC_TLS))
+   (clobber (reg:SI 1))
+   (clobber (reg:SI LR_REGNUM))
+   (clobber (reg:SI CC_REGNUM))]
+  "TARGET_GNU_TLS"
+  {
+    targetm.asm_out.internal_label (asm_out_file, "LPIC",
+				    INTVAL (operands[1]));
+    /* The + is to avoid an assembly parse ambiguity with symbols that
+       look like register names, which is unsuccessfully recovered from.  */
+    return TARGET_THUMB2 ? "blx\\t%c0(tlscall)" : "bl\\t+%c0(tlscall)";
+  }
+  [(set_attr "conds" "clob")
+   (set_attr "length" "4")]
+)
+
+;;
+
 ;; We only care about the lower 16 bits of the constant 
 ;; being inserted into the upper 16 bits of the register.
 (define_insn "*arm_movtas_ze" 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-05-10 11:23 [ARM] TLS Descriptor support Nathan Sidwell
@ 2011-05-10 13:14 ` Joseph S. Myers
  2011-05-11 15:43   ` Nathan Sidwell
  2011-05-26  9:32 ` Nathan Sidwell
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 17+ messages in thread
From: Joseph S. Myers @ 2011-05-10 13:14 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches

On Tue, 10 May 2011, Nathan Sidwell wrote:

> +@item -mtls-dialect=@var{dialect}
> +@opindex mtls-dialect
> +Specify the dialect to use for accessing thread local storage.  Two
> +dialects are supported - @option{arm} and @option{gnu}.  The

Use "---" (em dash, unspaced) instead of " - ".

> +@option{arm} dialect selects the ARM EABI scheme for supporting local
> +and global dynamic tls models.  The @option{gnu} dialect selects the

"TLS" not "tls".

> +Specify the default tls dialect, for systems were there is a choice.

Likewise.

> +	with_tls=${with_tls:arm}

Do you mean ${with_tls:-arm}?

> @@ -1755,6 +1759,17 @@ arm_option_override (void)
>  	error ("invalid thread pointer option: -mtp=%s", target_thread_switch);
>      }
>  
> +  if (target_tls_dialect_switch)
> +    {
> +      if (strcmp (target_tls_dialect_switch, "arm") == 0)
> +	target_tls_dialect = TLS_ARM;
> +      else if (strcmp (target_tls_dialect_switch, "gnu") == 0)
> +	target_tls_dialect = TLS_GNU;
> +      else
> +	error ("invalid thread dialect option: -mtls-dialect=%s",
> +	       target_tls_dialect_switch);
> +    }

Rather than checking for strings manually like this, it's now better to 
use the .opt Enum facility for options such as this with a fixed 
enumerated set of values, so target_tls_dialect can be set directly from 
the .opt file using Var and Enum.  (If you want a custom error message, 
you can use UnknownError on the enumeration record to specify it.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-05-10 13:14 ` Joseph S. Myers
@ 2011-05-11 15:43   ` Nathan Sidwell
  0 siblings, 0 replies; 17+ messages in thread
From: Nathan Sidwell @ 2011-05-11 15:43 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: GCC Patches

On 05/10/11 12:36, Joseph S. Myers wrote:

thanks for the review.  I've addressed these issues, but will wait for 
arm-specific review before reposting (I presume you want the chance to check the 
non-mechanical opt-machinery changes)

nathan

-- 
Nathan Sidwell

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-05-10 11:23 [ARM] TLS Descriptor support Nathan Sidwell
  2011-05-10 13:14 ` Joseph S. Myers
@ 2011-05-26  9:32 ` Nathan Sidwell
  2011-05-27  4:43 ` Ramana Radhakrishnan
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 17+ messages in thread
From: Nathan Sidwell @ 2011-05-26  9:32 UTC (permalink / raw)
  To: gcc-patches

On 05/10/11 07:49, Nathan Sidwell wrote:
> This patch implements TLS descriptor support in GCC. TLS descriptors are
> described at http://www.codesourcery.com/publications/RFC-TLSDESC-ARM.txt and
> blessed by ARM, who have reserved the relocation numbers.

http://gcc.gnu.org/ml/gcc-patches/2011-05/msg00708.html
ping?

nathan
-- 
Nathan Sidwell

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-05-10 11:23 [ARM] TLS Descriptor support Nathan Sidwell
  2011-05-10 13:14 ` Joseph S. Myers
  2011-05-26  9:32 ` Nathan Sidwell
@ 2011-05-27  4:43 ` Ramana Radhakrishnan
  2011-05-31 13:03   ` Nathan Sidwell
  2011-06-06 16:27 ` Richard Earnshaw
  2011-06-21  8:42 ` Nathan Sidwell
  4 siblings, 1 reply; 17+ messages in thread
From: Ramana Radhakrishnan @ 2011-05-27  4:43 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches

Thanks for this and sorry about the length of time in reviewing this .

On 10/05/11 07:49, Nathan Sidwell wrote:
> This patch implements TLS descriptor support in GCC. TLS descriptors are
> described at
> http://www.codesourcery.com/publications/RFC-TLSDESC-ARM.txt and blessed
> by ARM, who have reserved the relocation numbers.
>
> Binutils and GLIBC patches are already committed (there is an orthogonal
> glibc patch to do with make dependencies that I need to post though).
>
> This patch adds a --with-tls={arm|gnu} configuration option, to specify
> the default scheme. It can be overridden with a -mtls-dialect={arm|gnu}
> option (this is the name used by the x86 backend, which also has
> tlsdescriptor support). I have not added --with-tls support to the x86
> bits of config.gcc etc, but it would be simple to do so.

Could you consider adding a check in the configury to test if a binutils 
version of recent vintage is being used when --with-tls=gnu is in ?

Could you also use R0_REGNUM, R1_REGNUM instead of 0 and 1 in the 
"tlscall" pattern ?


>
> This patch has been tested for both default arm and default gnu tls
> schemes using the gcc and glibc testsuites for an arm-linux-gnueabi target.

Presumably for v7-a and v5te and with this as default ? On hardware ?


cheers
Ramana


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-05-27  4:43 ` Ramana Radhakrishnan
@ 2011-05-31 13:03   ` Nathan Sidwell
  2011-06-03 22:50     ` Ramana Radhakrishnan
  0 siblings, 1 reply; 17+ messages in thread
From: Nathan Sidwell @ 2011-05-31 13:03 UTC (permalink / raw)
  To: Ramana Radhakrishnan; +Cc: GCC Patches

On 05/27/11 01:47, Ramana Radhakrishnan wrote:

> Could you consider adding a check in the configury to test if a binutils version
> of recent vintage is being used when --with-tls=gnu is in ?

I thought about that and it didn't seem worth it.  We're not autodetecting 
whether to default to gnu-style tls and you'll find out soon enough if your 
binutils is too old.

>
> Could you also use R0_REGNUM, R1_REGNUM instead of 0 and 1 in the "tlscall"
> pattern ?

>> This patch has been tested for both default arm and default gnu tls
>> schemes using the gcc and glibc testsuites for an arm-linux-gnueabi target.
>
> Presumably for v7-a and v5te and with this as default ? On hardware ?

Hm, I see our testing for fsf build uses qemu -- this patch has been tested on 
hardware in our releases.  Just not this exact version of the patch.

nathan

-- 
Nathan Sidwell

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-05-31 13:03   ` Nathan Sidwell
@ 2011-06-03 22:50     ` Ramana Radhakrishnan
  2011-06-06  9:50       ` Nathan Sidwell
  0 siblings, 1 reply; 17+ messages in thread
From: Ramana Radhakrishnan @ 2011-06-03 22:50 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches

On 31 May 2011 11:03, Nathan Sidwell <nathan@codesourcery.com> wrote:
> On 05/27/11 01:47, Ramana Radhakrishnan wrote:
>
>> Could you consider adding a check in the configury to test if a binutils
>> version
>> of recent vintage is being used when --with-tls=gnu is in ?
>
> I thought about that and it didn't seem worth it.  We're not autodetecting
> whether to default to gnu-style tls and you'll find out soon enough if your
> binutils is too old.


I noticed this today - and maybe I don't quite understand it yet.

>   /* The + is to avoid an assembly parse ambiguity with symbols that
> +       look like register names, which is unsuccessfully recovered from.  */
> +    return TARGET_THUMB2 ? "blx\\t%c0(tlscall)" : "bl\\t+%c0(tlscall)";


How are things handled for Thumb1 in case someone builds a routine for
Thumb1 which uses tlsdesc ? I went and read the doc and didn't see any
difference between T1 and T2 in the specification . Would the linker
and everyone else do the right thing or should we have the blx
instruction for TARGET_THUMB and v5t . I have a feeling that I'm
missing something here .




cheers
Ramana

>
> nathan
>
> --
> Nathan Sidwell
>
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-06-03 22:50     ` Ramana Radhakrishnan
@ 2011-06-06  9:50       ` Nathan Sidwell
  2011-06-06  9:54         ` Ramana Radhakrishnan
  0 siblings, 1 reply; 17+ messages in thread
From: Nathan Sidwell @ 2011-06-06  9:50 UTC (permalink / raw)
  To: Ramana Radhakrishnan; +Cc: GCC Patches

On 06/03/11 23:50, Ramana Radhakrishnan wrote:

> How are things handled for Thumb1 in case someone builds a routine for
> Thumb1 which uses tlsdesc ? I went and read the doc and didn't see any
> difference between T1 and T2 in the specification . Would the linker
> and everyone else do the right thing or should we have the blx
> instruction for TARGET_THUMB and v5t . I have a feeling that I'm
> missing something here .

You're asking how does the thumb1 bl instruction get handled?  The linker emits 
a veneer -- a variant of the t<->a veneers it already deals with.

If you're asking something else, can you rephrase the question?

nathan

-- 
Nathan Sidwell

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-06-06  9:50       ` Nathan Sidwell
@ 2011-06-06  9:54         ` Ramana Radhakrishnan
  2011-06-06  9:56           ` Nathan Sidwell
  0 siblings, 1 reply; 17+ messages in thread
From: Ramana Radhakrishnan @ 2011-06-06  9:54 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches

> If you're asking something else, can you rephrase the question?

Sorry if I wasn't too clear.  My question really should have read "why
do we have to special case Thumb2" ? The linker should be able to
veneer the t-> a calls either through the veneering sequence (in case
of T1 without blx) or convert the bl to a blx (modulo the case with
out of range branches). As I said I'm probably missing something here.

cheers
Ramana

>
> nathan
>
> --
> Nathan Sidwell
>
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-06-06  9:54         ` Ramana Radhakrishnan
@ 2011-06-06  9:56           ` Nathan Sidwell
  2011-06-06 16:10             ` Ramana Radhakrishnan
  0 siblings, 1 reply; 17+ messages in thread
From: Nathan Sidwell @ 2011-06-06  9:56 UTC (permalink / raw)
  To: Ramana Radhakrishnan; +Cc: GCC Patches

On 06/06/11 10:53, Ramana Radhakrishnan wrote:
>> If you're asking something else, can you rephrase the question?
>
> Sorry if I wasn't too clear.  My question really should have read "why
> do we have to special case Thumb2" ? The linker should be able to
> veneer the t->  a calls either through the veneering sequence (in case
> of T1 without blx) or convert the bl to a blx (modulo the case with
> out of range branches). As I said I'm probably missing something here.

Maybe we don't.  It just seems neater to emit blx on arches that have it.

nathan
-- 
Nathan Sidwell

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-06-06  9:56           ` Nathan Sidwell
@ 2011-06-06 16:10             ` Ramana Radhakrishnan
  0 siblings, 0 replies; 17+ messages in thread
From: Ramana Radhakrishnan @ 2011-06-06 16:10 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches

On 6 June 2011 10:56, Nathan Sidwell <nathan@codesourcery.com> wrote:
> On 06/06/11 10:53, Ramana Radhakrishnan wrote:
>>>
>>> If you're asking something else, can you rephrase the question?
>>
>> Sorry if I wasn't too clear.  My question really should have read "why
>> do we have to special case Thumb2" ? The linker should be able to
>> veneer the t->  a calls either through the veneering sequence (in case
>> of T1 without blx) or convert the bl to a blx (modulo the case with
>> out of range branches). As I said I'm probably missing something here.
>
> Maybe we don't.  It just seems neater to emit blx on arches that have it.
>

In which case the test should probably read -

(arm_arch5 && TARGET_THUMB) rather than (TARGET_THUMB2) since blx
exists since v5t

cheers
Ramana

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-05-10 11:23 [ARM] TLS Descriptor support Nathan Sidwell
                   ` (2 preceding siblings ...)
  2011-05-27  4:43 ` Ramana Radhakrishnan
@ 2011-06-06 16:27 ` Richard Earnshaw
  2011-06-07  6:11   ` Nathan Sidwell
  2011-06-21  8:42 ` Nathan Sidwell
  4 siblings, 1 reply; 17+ messages in thread
From: Richard Earnshaw @ 2011-06-06 16:27 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches

On 05/10/11 07:49, Nathan Sidwell wrote:
> This patch implements TLS descriptor support in GCC.  TLS descriptors 
> are described at 
> http://www.codesourcery.com/publications/RFC-TLSDESC-ARM.txt and 
> blessed by ARM, who have reserved the relocation numbers.
>
> Binutils and GLIBC patches are already committed (there is an 
> orthogonal glibc patch to do with make dependencies that I need to 
> post though).
>
> This patch adds a --with-tls={arm|gnu} configuration option, to 
> specify the default scheme.  It can be overridden with a 
> -mtls-dialect={arm|gnu} option (this is the name used by the x86 
> backend, which also has tlsdescriptor support).  I have not added 
> --with-tls support to the x86 bits of config.gcc etc, but it would be 
> simple to do so.
>
> The arm.{c,h,md} changes are fairly mechanical -- a new tls pattern 
> and smarts to emit it appropriately.
>
> This patch has been tested for both default arm and default gnu tls 
> schemes using the gcc and glibc testsuites for an arm-linux-gnueabi 
> target.
>
> ok?
>
> nathan
>
+    /* The + is to avoid an assembly parse ambiguity with symbols that
+       look like register names, which is unsuccessfully recovered 
from.  */
+    return TARGET_THUMB2 ? "blx\\t%c0(tlscall)" : "bl\\t+%c0(tlscall)";


Eh?  This is backwards.  There is blx <reg>, but no bl <reg>.  If the 
assembler gets confused with 'bl r0' then it needs to be fixed urgently.

Further, both the assembler and the linker know how to change bl to blx 
when needed, so it's best to just put out bl and be done with it.

R.



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-06-06 16:27 ` Richard Earnshaw
@ 2011-06-07  6:11   ` Nathan Sidwell
  2011-06-07 13:08     ` Richard Earnshaw
  0 siblings, 1 reply; 17+ messages in thread
From: Nathan Sidwell @ 2011-06-07  6:11 UTC (permalink / raw)
  To: Richard Earnshaw; +Cc: GCC Patches

On 06/06/11 17:27, Richard Earnshaw wrote:

> Eh? This is backwards. There is blx <reg>, but no bl <reg>. If the assembler
> gets confused with 'bl r0' then it needs to be fixed urgently.

Are you requiring the assembler be fixed before this patch can be committed 
(without the '+'?)

nathan

-- 
Nathan Sidwell

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-06-07  6:11   ` Nathan Sidwell
@ 2011-06-07 13:08     ` Richard Earnshaw
  0 siblings, 0 replies; 17+ messages in thread
From: Richard Earnshaw @ 2011-06-07 13:08 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches

On 06/07/11 07:11, Nathan Sidwell wrote:
> On 06/06/11 17:27, Richard Earnshaw wrote:
> 
>> Eh? This is backwards. There is blx <reg>, but no bl <reg>. If the assembler
>> gets confused with 'bl r0' then it needs to be fixed urgently.
> 
> Are you requiring the assembler be fixed before this patch can be committed 
> (without the '+'?)
> 
> nathan
> 

Yes, the assembler output here should be "bl\\t%c0(tlsdesc)" for all
variants.

I'd also much prefer that the named variant be GNU and GNU2, as they are
for x86.  It's much less confusing to users that way (the fact that the
first (GNU) variant is documented in the ARM ABI specification is simply
down to a lack of external documentation to refer to, but the underlying
model is the same as that used elsewere for the first GNU version).

R.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-05-10 11:23 [ARM] TLS Descriptor support Nathan Sidwell
                   ` (3 preceding siblings ...)
  2011-06-06 16:27 ` Richard Earnshaw
@ 2011-06-21  8:42 ` Nathan Sidwell
  2011-06-21 18:03   ` Ramana Radhakrishnan
  4 siblings, 1 reply; 17+ messages in thread
From: Nathan Sidwell @ 2011-06-21  8:42 UTC (permalink / raw)
  To: gcc-patches; +Cc: Joseph S. Myers, Ramana Radhakrishnan, Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 449 bytes --]

This patches addresses your comments.

I've fixed:
* config and option items Joseph pointed out in 
http://gcc.gnu.org/ml/gcc-patches/2011-05/msg00719.html
* md items Ramana pointed out in 
http://gcc.gnu.org/ml/gcc-patches/2011-05/msg02109.html
* option naming and assembly issues Richard pointed out in 
http://gcc.gnu.org/ml/gcc-patches/2011-06/msg00429.html

revalidated with defaults to both gnu and gnu2 style. ok?

nathan
-- 
Nathan Sidwell


[-- Attachment #2: arm-tls.patch --]
[-- Type: text/x-patch, Size: 14293 bytes --]

2011-06-21  Nathan Sidwell  <nathan@codesourcery.com>

	* doc/invoke.texi (ARM Options): Document -mtls-dialect option.
	* doc/install.texi (Configuration): Document --with-tls.
	* config.gcc (arm*-*-linux*): Default to gnu tls.
	(arm*-*-*): Add --with-tls option.
	(all_defaults): Add 'tls'.
	* config/arm/arm.c (enum tls_reloc): Add TLS_DESCSEQ.
	(arm_call_tls_get_addr): Clean up. Assert not tls descriptor.
	(arm_tls_descseq_addr): New.
	(legitimize_tls_address): Add tlsdesc support.
	(arm_cannot_copy_insn_p): Check for tlscall.
	(arm_emit_tls_decoration): Likewise.
	* config/arm/arm.h (TARGET_GNU2_TLS): New.
	(OPTION_DEFAULT_SPECS): Add with-tls support.
	* config/arm/arm.md (R1_REGNUM): Define.
	(tlscall): New.
	* config/arm/arm.opt (tls_type): New enumeration type and values.
	(mtls-dialect): New switch.
	* config/arm/arm-opts.h (enum tls_type): New.

	testsuite/
	* gcc.target/arm/tlscall.c: New.

Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 174801)
+++ doc/invoke.texi	(working copy)
@@ -476,7 +476,7 @@ Objective-C and Objective-C++ Dialects}.
 -mthumb  -marm @gol
 -mtpcs-frame  -mtpcs-leaf-frame @gol
 -mcaller-super-interworking  -mcallee-super-interworking @gol
--mtp=@var{name} @gol
+-mtp=@var{name} -mtls-dialect=@var{dialect} @gol
 -mword-relocations @gol
 -mfix-cortex-m3-ldrd}
 
@@ -10461,6 +10461,18 @@ models are @option{soft}, which generate
 best available method for the selected processor.  The default setting is
 @option{auto}.
 
+@item -mtls-dialect=@var{dialect}
+@opindex mtls-dialect
+Specify the dialect to use for accessing thread local storage.  Two
+dialects are supported --- @option{gnu} and @option{gnu2}.  The
+@option{gnu} dialect selects the original GNU scheme for supporting
+local and global dynamic TLS models.  The @option{gnu2} dialect
+selects the GNU descriptor scheme, which provides better performance
+for shared libraries.  The GNU descriptor scheme is compatible with
+the original scheme, but does require new assembler, linker and
+library support.  Initial and local exec TLS models are unaffected by
+this option and always use the original scheme.
+
 @item -mword-relocations
 @opindex mword-relocations
 Only generate absolute relocations on word sized values (i.e. R_ARM_ABS32).
Index: doc/install.texi
===================================================================
--- doc/install.texi	(revision 174801)
+++ doc/install.texi	(working copy)
@@ -1016,6 +1016,12 @@ information normally used on 386 SVR4 pl
 workable alternative.  This requires gas and gdb, as the normal SVR4
 tools can not generate or interpret stabs.
 
+@item --with-tls=@var{dialect}
+Specify the default TLS dialect, for systems were there is a choice.
+For ARM targets, possible values for @var{dialect} are @code{gnu} or
+@code{gnu2}, which select between the original GNU dialect and the GNU TLS
+descriptor-based dialect.
+
 @item --disable-multilib
 Specify that multiple target
 libraries to support different target variants, calling
Index: testsuite/gcc.target/arm/tlscall.c
===================================================================
--- testsuite/gcc.target/arm/tlscall.c	(revision 0)
+++ testsuite/gcc.target/arm/tlscall.c	(revision 0)
@@ -0,0 +1,31 @@
+/* Test non-duplication of tlscall insn */
+
+/* { dg-do assemble } */
+/* { dg-options "-O2 -fPIC -mtls-dialect=gnu2" } */
+
+typedef struct _IO_FILE FILE;
+
+extern int foo(void);
+extern int bar(void);
+
+void uuid__generate_time()
+{
+ static int has_init = 0;
+ static __thread int state_fd = -2;
+ static __thread FILE *state_f;
+
+ if (!has_init) {
+   foo();
+   has_init = 1;
+ }
+
+ if (state_fd == -2) {
+  if (!state_f) {
+   state_fd = -1;
+  }
+ }
+ if (state_fd >= 0) {
+  while (bar() < 0) {}
+ }
+
+}
Index: config.gcc
===================================================================
--- config.gcc	(revision 174801)
+++ config.gcc	(working copy)
@@ -822,6 +822,7 @@ arm*-*-linux*)			# ARM GNU/Linux with EL
 	    tmake_file="$tmake_file arm/t-linux"
 	    ;;
 	esac
+	with_tls=${with_tls:-gnu}
 	tm_file="$tm_file arm/aout.h arm/arm.h"
 	tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp"
 	;;
@@ -3059,7 +3060,7 @@ case "${target}" in
 		;;
 
 	arm*-*-*)
-		supported_defaults="arch cpu float tune fpu abi mode"
+		supported_defaults="arch cpu float tune fpu abi mode tls"
 		for which in cpu tune; do
 			# See if it matches any of the entries in arm-cores.def
 			eval "val=\$with_$which"
@@ -3142,6 +3143,17 @@ case "${target}" in
 			;;
 		esac
 
+		case "$with_tls" in
+		"" \
+		| gnu | gnu2)
+			# OK
+			;;
+		*)
+			echo "Unknown TLS method used in --with-tls=$with_tls" 1>&2
+			exit 1
+			;;
+		esac
+
 		if test "x$with_arch" != x && test "x$with_cpu" != x; then
 			echo "Warning: --with-arch overrides --with-cpu=$with_cpu" 1>&2
 		fi
@@ -3621,7 +3633,7 @@ case ${target} in
 esac
 
 t=
-all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu divide llsc mips-plt synci"
+all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu divide llsc mips-plt synci tls"
 for option in $all_defaults
 do
 	eval "val=\$with_"`echo $option | sed s/-/_/g`
Index: config/arm/arm.c
===================================================================
--- config/arm/arm.c	(revision 174801)
+++ config/arm/arm.c	(working copy)
@@ -1026,7 +1026,8 @@ enum tls_reloc {
   TLS_LDM32,
   TLS_LDO32,
   TLS_IE32,
-  TLS_LE32
+  TLS_LE32,
+  TLS_DESCSEQ	/* GNU scheme */
 };
 
 /* The maximum number of insns to be used when loading a constant.  */
@@ -5871,6 +5872,7 @@ arm_call_tls_get_addr (rtx x, rtx reg, r
 {
   rtx insns, label, labelno, sum;
 
+  gcc_assert (reloc != TLS_DESCSEQ);
   start_sequence ();
 
   labelno = GEN_INT (pic_labelno++);
@@ -5885,20 +5887,42 @@ arm_call_tls_get_addr (rtx x, rtx reg, r
 
   if (TARGET_ARM)
     emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));
-  else if (TARGET_THUMB2)
-    emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
-  else /* TARGET_THUMB1 */
+  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?  */
+  
+  *valuep = emit_library_call_value (get_tls_get_addr (), NULL_RTX,
+				     LCT_PURE, /* LCT_CONST?  */
 				     Pmode, 1, reg, Pmode);
-
+  
   insns = get_insns ();
   end_sequence ();
 
   return insns;
 }
 
+static rtx
+arm_tls_descseq_addr (rtx x, rtx reg)
+{
+  rtx labelno = GEN_INT (pic_labelno++);
+  rtx label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
+  rtx sum = gen_rtx_UNSPEC (Pmode,
+			    gen_rtvec (4, x, GEN_INT (TLS_DESCSEQ),
+				       gen_rtx_CONST (VOIDmode, label),
+				       GEN_INT (!TARGET_ARM)),
+			    UNSPEC_TLS);
+  rtx reg0 = load_tls_operand (sum, gen_rtx_REG (SImode, 0));
+  
+  emit_insn (gen_tlscall (x, labelno));
+  if (!reg)
+    reg = gen_reg_rtx (SImode);
+  else
+    gcc_assert (REGNO (reg) != 0);
+
+  emit_move_insn (reg, reg0);
+
+  return reg;
+}
+
 rtx
 legitimize_tls_address (rtx x, rtx reg)
 {
@@ -5908,26 +5932,51 @@ legitimize_tls_address (rtx x, rtx reg)
   switch (model)
     {
     case TLS_MODEL_GLOBAL_DYNAMIC:
-      insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);
-      dest = gen_reg_rtx (Pmode);
-      emit_libcall_block (insns, dest, ret, x);
+      if (TARGET_GNU2_TLS)
+	{
+	  reg = arm_tls_descseq_addr (x, reg);
+
+	  tp = arm_load_tp (NULL_RTX);
+	  
+	  dest = gen_rtx_PLUS (Pmode, tp, reg);
+	}
+      else
+	{
+	  /* Original scheme */
+	  insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);
+	  dest = gen_reg_rtx (Pmode);
+	  emit_libcall_block (insns, dest, ret, x);
+	}
       return dest;
 
     case TLS_MODEL_LOCAL_DYNAMIC:
-      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.  */
-      eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const1_rtx),
-			    UNSPEC_TLS);
-      dest = gen_reg_rtx (Pmode);
-      emit_libcall_block (insns, dest, ret, eqv);
+      if (TARGET_GNU2_TLS)
+	{
+	  reg = arm_tls_descseq_addr (x, reg);
 
-      /* Load the addend.  */
-      addend = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, x, GEN_INT (TLS_LDO32)),
-			       UNSPEC_TLS);
-      addend = force_reg (SImode, gen_rtx_CONST (SImode, addend));
-      return gen_rtx_PLUS (Pmode, dest, addend);
+	  tp = arm_load_tp (NULL_RTX);
+	  
+	  dest = gen_rtx_PLUS (Pmode, tp, reg);
+	}
+      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.  */
+	  eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const1_rtx),
+				UNSPEC_TLS);
+	  dest = gen_reg_rtx (Pmode);
+	  emit_libcall_block (insns, dest, ret, eqv);
+	  
+	  /* Load the addend.  */
+	  addend = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, x,
+						     GEN_INT (TLS_LDO32)),
+				   UNSPEC_TLS);
+	  addend = force_reg (SImode, gen_rtx_CONST (SImode, addend));
+	  dest = gen_rtx_PLUS (Pmode, dest, addend);
+	}
+      return dest;
 
     case TLS_MODEL_INITIAL_EXEC:
       labelno = GEN_INT (pic_labelno++);
@@ -9374,6 +9423,11 @@ arm_note_pic_base (rtx *x, void *date AT
 static bool
 arm_cannot_copy_insn_p (rtx insn)
 {
+  /* The tls call insn cannot be copied, as it is paired with a data
+     word.  */
+  if (recog_memoized (insn) == CODE_FOR_tlscall)
+    return true;
+  
   return for_each_rtx (&PATTERN (insn), arm_note_pic_base, NULL);
 }
 
@@ -22928,6 +22982,9 @@ arm_emit_tls_decoration (FILE *fp, rtx x
     case TLS_LE32:
       fputs ("(tpoff)", fp);
       break;
+    case TLS_DESCSEQ:
+      fputs ("(tlsdesc)", fp);
+      break;
     default:
       gcc_unreachable ();
     }
@@ -22937,9 +22994,11 @@ arm_emit_tls_decoration (FILE *fp, rtx x
     case TLS_GD32:
     case TLS_LDM32:
     case TLS_IE32:
+    case TLS_DESCSEQ:
       fputs (" + (. - ", fp);
       output_addr_const (fp, XVECEXP (x, 0, 2));
-      fputs (" - ", fp);
+      /* For DESCSEQ the 3rd operand encodes thumbness, and is added */
+      fputs (reloc == TLS_DESCSEQ ? " + " : " - ", fp);
       output_addr_const (fp, XVECEXP (x, 0, 3));
       fputc (')', fp);
       break;
Index: config/arm/arm.h
===================================================================
--- config/arm/arm.h	(revision 174801)
+++ config/arm/arm.h	(working copy)
@@ -220,6 +220,7 @@ extern void (*arm_lang_output_object_att
 
 #define TARGET_HARD_TP			(target_thread_pointer == TP_CP15)
 #define TARGET_SOFT_TP			(target_thread_pointer == TP_SOFT)
+#define TARGET_GNU2_TLS			(target_tls_dialect == TLS_GNU2)
 
 /* Only 16-bit thumb code.  */
 #define TARGET_THUMB1			(TARGET_THUMB && !arm_arch_thumb2)
@@ -313,7 +314,8 @@ extern void (*arm_lang_output_object_att
      by -march).
    --with-float is ignored if -mfloat-abi is specified.
    --with-fpu is ignored if -mfpu is specified.
-   --with-abi is ignored is -mabi is specified.  */
+   --with-abi is ignored if -mabi is specified.
+   --with-tls is ignored if -mtls-dialect is specified. */
 #define OPTION_DEFAULT_SPECS \
   {"arch", "%{!march=*:%{!mcpu=*:-march=%(VALUE)}}" }, \
   {"cpu", "%{!march=*:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
@@ -321,7 +323,8 @@ extern void (*arm_lang_output_object_att
   {"float", "%{!mfloat-abi=*:-mfloat-abi=%(VALUE)}" }, \
   {"fpu", "%{!mfpu=*:-mfpu=%(VALUE)}"}, \
   {"abi", "%{!mabi=*:-mabi=%(VALUE)}"}, \
-  {"mode", "%{!marm:%{!mthumb:-m%(VALUE)}}"},
+  {"mode", "%{!marm:%{!mthumb:-m%(VALUE)}}"}, \
+  {"tls", "%{!mtls-dialect:-mtls-dialect=%(VALUE)}"},
 
 /* Which floating point model to use.  */
 enum arm_fp_model
Index: config/arm/arm.opt
===================================================================
--- config/arm/arm.opt	(revision 174801)
+++ config/arm/arm.opt	(working copy)
@@ -21,6 +21,16 @@
 HeaderInclude
 config/arm/arm-opts.h
 
+Enum
+Name(tls_type) Type(enum arm_tls_type)
+TLS dialect to use:
+
+EnumValue
+Enum(tls_type) String(gnu) Value(TLS_GNU)
+
+EnumValue
+Enum(tls_type) String(gnu2) Value(TLS_GNU2)
+
 mabi=
 Target RejectNegative Joined Enum(arm_abi_type) Var(arm_abi) Init(ARM_DEFAULT_ABI)
 Specify an ABI
@@ -190,6 +200,10 @@ mthumb-interwork
 Target Report Mask(INTERWORK)
 Support calls between Thumb and ARM instruction sets
 
+mtls-dialect=
+Target RejectNegative Joined Enum(tls_type) Var(target_tls_dialect) Init(TLS_GNU)
+Specify thread local storage scheme
+
 mtp=
 Target RejectNegative Joined Enum(arm_tp_type) Var(target_thread_pointer) Init(TP_AUTO)
 Specify how to access the thread pointer
Index: config/arm/arm.md
===================================================================
--- config/arm/arm.md	(revision 174801)
+++ config/arm/arm.md	(working copy)
@@ -31,6 +31,7 @@
 ;; Register numbers
 (define_constants
   [(R0_REGNUM        0)		; First CORE register
+   (R1_REGNUM	     1)		; Second CORE register
    (IP_REGNUM	    12)		; Scratch register
    (SP_REGNUM	    13)		; Stack pointer
    (LR_REGNUM       14)		; Return address register
@@ -10703,6 +10704,27 @@
   [(set_attr "conds" "clob")]
 )
 
+;; 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")]
+)
+
+;;
+
 ;; We only care about the lower 16 bits of the constant 
 ;; being inserted into the upper 16 bits of the register.
 (define_insn "*arm_movtas_ze" 
Index: config/arm/arm-opts.h
===================================================================
--- config/arm/arm-opts.h	(revision 174801)
+++ config/arm/arm-opts.h	(working copy)
@@ -68,4 +68,9 @@ enum arm_tp_type {
   TP_CP15
 };
 
+/* Which TLS scheme to use.  */
+enum arm_tls_type {
+  TLS_GNU,
+  TLS_GNU2
+};
 #endif

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-06-21  8:42 ` Nathan Sidwell
@ 2011-06-21 18:03   ` Ramana Radhakrishnan
  2011-06-22 17:52     ` Nathan Sidwell
  0 siblings, 1 reply; 17+ messages in thread
From: Ramana Radhakrishnan @ 2011-06-21 18:03 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: gcc-patches, Joseph S. Myers, Richard Earnshaw

> revalidated with defaults to both gnu and gnu2 style. ok?

This is OK .

Ramana
>
> nathan
> --
> Nathan Sidwell
>
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [ARM] TLS Descriptor support
  2011-06-21 18:03   ` Ramana Radhakrishnan
@ 2011-06-22 17:52     ` Nathan Sidwell
  0 siblings, 0 replies; 17+ messages in thread
From: Nathan Sidwell @ 2011-06-22 17:52 UTC (permalink / raw)
  To: Ramana Radhakrishnan; +Cc: gcc-patches, Joseph S. Myers, Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 392 bytes --]

On 06/21/11 18:24, Ramana Radhakrishnan wrote:
>> revalidated with defaults to both gnu and gnu2 style. ok?
>
> This is OK .

sigh, in backporting the relevant bits, I noticed a problem with the 
OPTION_DEFAULT_SPECS string, fixed thusly, committed as obvious.  And then I 
noticed I'd failed to commit the config.gcc fragment.

Back of the class for me today :(

nathan

-- 
Nathan Sidwell


[-- Attachment #2: all.diff --]
[-- Type: text/plain, Size: 2102 bytes --]

2011-06-22  Nathan Sidwell  <nathan@codesourcery.com>

	* config/arm/arm.h (OPTION_DEFAULT_SPECS): Fix -mtls-dialect
	typo.
	* config.gcc (arm*-*-linux*): Default to gnu tls.
	(arm*-*-*): Add --with-tls option.
	(all_defaults): Add 'tls'.

Index: config.gcc
===================================================================
--- config.gcc	(revision 175297)
+++ config.gcc	(working copy)
@@ -863,6 +863,7 @@
 	    tmake_file="$tmake_file arm/t-linux"
 	    ;;
 	esac
+	with_tls=${with_tls:-gnu}
 	tm_file="$tm_file arm/aout.h arm/arm.h"
 	tmake_file="${tmake_file} arm/t-arm-softfp soft-fp/t-softfp"
 	;;
@@ -3039,7 +3040,7 @@
 		;;
 
 	arm*-*-*)
-		supported_defaults="arch cpu float tune fpu abi mode"
+		supported_defaults="arch cpu float tune fpu abi mode tls"
 		for which in cpu tune; do
 			# See if it matches any of the entries in arm-cores.def
 			eval "val=\$with_$which"
@@ -3122,6 +3123,17 @@
 			;;
 		esac
 
+		case "$with_tls" in
+		"" \
+		| gnu | gnu2)
+			# OK
+			;;
+		*)
+			echo "Unknown TLS method used in --with-tls=$with_tls" 1>&2
+			exit 1
+			;;
+		esac
+
 		if test "x$with_arch" != x && test "x$with_cpu" != x; then
 			echo "Warning: --with-arch overrides --with-cpu=$with_cpu" 1>&2
 		fi
@@ -3601,7 +3613,7 @@
 esac
 
 t=
-all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu divide llsc mips-plt synci"
+all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu divide llsc mips-plt synci tls"
 for option in $all_defaults
 do
 	eval "val=\$with_"`echo $option | sed s/-/_/g`
Index: config/arm/arm.h
===================================================================
--- config/arm/arm.h	(revision 175297)
+++ config/arm/arm.h	(working copy)
@@ -324,7 +324,7 @@
   {"fpu", "%{!mfpu=*:-mfpu=%(VALUE)}"}, \
   {"abi", "%{!mabi=*:-mabi=%(VALUE)}"}, \
   {"mode", "%{!marm:%{!mthumb:-m%(VALUE)}}"}, \
-  {"tls", "%{!mtls-dialect:-mtls-dialect=%(VALUE)}"},
+  {"tls", "%{!mtls-dialect=*:-mtls-dialect=%(VALUE)}"},
 
 /* Which floating point model to use.  */
 enum arm_fp_model

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2011-06-22 17:03 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-10 11:23 [ARM] TLS Descriptor support Nathan Sidwell
2011-05-10 13:14 ` Joseph S. Myers
2011-05-11 15:43   ` Nathan Sidwell
2011-05-26  9:32 ` Nathan Sidwell
2011-05-27  4:43 ` Ramana Radhakrishnan
2011-05-31 13:03   ` Nathan Sidwell
2011-06-03 22:50     ` Ramana Radhakrishnan
2011-06-06  9:50       ` Nathan Sidwell
2011-06-06  9:54         ` Ramana Radhakrishnan
2011-06-06  9:56           ` Nathan Sidwell
2011-06-06 16:10             ` Ramana Radhakrishnan
2011-06-06 16:27 ` Richard Earnshaw
2011-06-07  6:11   ` Nathan Sidwell
2011-06-07 13:08     ` Richard Earnshaw
2011-06-21  8:42 ` Nathan Sidwell
2011-06-21 18:03   ` Ramana Radhakrishnan
2011-06-22 17:52     ` Nathan Sidwell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).