* [PATCH] AIX native TLS support
@ 2012-12-12 20:51 David Edelsohn
0 siblings, 0 replies; 3+ messages in thread
From: David Edelsohn @ 2012-12-12 20:51 UTC (permalink / raw)
To: GCC Patches
This is the next set of patches for native TLS support on AIX. This
mainly adds support for BSS symbols. This should use local common and
I created a tbss section name, but I cannot figure out how to convince
the AIX assembler to match the TOC symbols reference to the lcomm
symbol. Disassembly of XLC output shows that it uses COMMON symbols,
so I am punting to that as well.
This patch also removes the section anchor flag from native TLS
symbols if it was set.
This patch uses the logic from bss_initializer_p(). Should that
function in varasm.c be made non-static?
Bootstrapped on powerpc-ibm-aix7.1.0.0, although this still does not
pass libgomp testsuite.
Thanks, David
* xcoffout.c (xcoff_tbss_section_name): Define.
* xcoffout.h (xcoff_tbss_section_name): Declare.
* config/rs6000/xcoff.h (TARGET_ENCODE_SECTION_INFO): Define.
(ASM_OUTPUT_TLS_COMMON): Merge strings.
* config/rs6000/rs6000.c (tls_private_dat_section): New.
(output_toc): Only output CSECT decoration for TLS.
Output appropriate CSECT for data or bss.
(rs6000_xcoff_asm_init_sections) Define tls_private_data_section.
(rs6000_xcoff_select_section): Handle TLS bss and private data.
(rs6000_xcoff_file_start): Generate xcoff_tbss_section_name.
(rs6000_xcoff_encode_section_info): Strip SYMBOL_FLAG_HAS_BLOCK_INFO
from native TLS symbols.
Index: xcoffout.c
===================================================================
--- xcoffout.c (revision 194435)
+++ xcoffout.c (working copy)
@@ -67,6 +67,7 @@
char *xcoff_bss_section_name;
char *xcoff_private_data_section_name;
char *xcoff_tls_data_section_name;
+char *xcoff_tbss_section_name;
char *xcoff_read_only_section_name;
/* Last source file name mentioned in a NOTE insn. */
Index: xcoffout.h
===================================================================
--- xcoffout.h (revision 194435)
+++ xcoffout.h (working copy)
@@ -127,6 +127,7 @@
extern char *xcoff_bss_section_name;
extern char *xcoff_private_data_section_name;
extern char *xcoff_tls_data_section_name;
+extern char *xcoff_tbss_section_name;
extern char *xcoff_read_only_section_name;
/* Last source file name mentioned in a NOTE insn. */
Index: config/rs6000/xcoff.h
===================================================================
--- config/rs6000/xcoff.h (revision 194435)
+++ config/rs6000/xcoff.h (working copy)
@@ -98,6 +98,7 @@
#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
#define TARGET_STRIP_NAME_ENCODING rs6000_xcoff_strip_name_encoding
#define TARGET_SECTION_TYPE_FLAGS rs6000_xcoff_section_type_flags
+#define TARGET_ENCODE_SECTION_INFO rs6000_xcoff_encode_section_info
/* FP save and restore routines. */
#define SAVE_FP_PREFIX "._savef"
@@ -308,8 +309,8 @@
#define ASM_OUTPUT_TLS_COMMON(FILE, DECL, NAME, SIZE) \
do { fputs(COMMON_ASM_OP, (FILE)); \
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
- fputs("[UL]", (FILE)); \
- fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)); \
+ fprintf ((FILE), "[UL],"HOST_WIDE_INT_PRINT_UNSIGNED"\n", \
+ (SIZE)); \
} while (0)
#endif
Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c (revision 194435)
+++ config/rs6000/rs6000.c (working copy)
@@ -209,6 +209,7 @@ static short cached_can_issue_more;
static GTY(()) section *read_only_data_section;
static GTY(()) section *private_data_section;
static GTY(()) section *tls_data_section;
+static GTY(()) section *tls_private_data_section;
static GTY(()) section *read_only_private_data_section;
static GTY(()) section *sdata2_section;
static GTY(()) section *toc_section;
@@ -22316,23 +22317,39 @@ output_toc (FILE *file, rtx x, int labelno, enum m
output_addr_const (file, x);
#if HAVE_AS_TLS
- if (TARGET_XCOFF && GET_CODE (base) == SYMBOL_REF)
+ if (TARGET_XCOFF && GET_CODE (base) == SYMBOL_REF
+ && SYMBOL_REF_TLS_MODEL (base) != 0)
{
+ tree decl = SYMBOL_REF_DECL (base);
+ if (DECL_INITIAL (decl) == NULL_TREE
+ || DECL_INITIAL (decl) == error_mark_node
+ || (flag_zero_initialized_in_bss
+ /* Leave constant zeroes in .rodata so they
+ can be shared. */
+ && !TREE_READONLY (decl)
+ && initializer_zerop (DECL_INITIAL (decl))))
+ fputs ("[UL]", file);
+ else
+ fputs ("[TL]", file);
+
if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_EXEC)
- fputs ("[TL]@le", file);
+ fputs ("@le", file);
else if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_INITIAL_EXEC)
- fputs ("[TL]@ie", file);
+ fputs ("@ie", file);
/* Use global-dynamic for local-dynamic. */
else if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_GLOBAL_DYNAMIC
|| SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_DYNAMIC)
{
- fputs ("[TL]\n", file);
+ putc ('\n', file);
(*targetm.asm_out.internal_label) (file, "LCM", labelno);
fputs ("\t.tc .", file);
RS6000_OUTPUT_BASENAME (file, name);
fputs ("[TC],", file);
output_addr_const (file, x);
- fputs ("[TL]@m", file);
+ if (TREE_PUBLIC (SYMBOL_REF_DECL (base)))
+ fputs ("[TL]@m", file);
+ else
+ fputs ("[UL]@m", file);
}
}
#endif
@@ -25705,6 +25722,11 @@ rs6000_xcoff_asm_init_sections (void)
rs6000_xcoff_output_tls_section_asm_op,
&xcoff_tls_data_section_name);
+ tls_private_data_section
+ = get_unnamed_section (SECTION_TLS,
+ rs6000_xcoff_output_tls_section_asm_op,
+ &xcoff_private_data_section_name);
+
read_only_private_data_section
= get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
&xcoff_private_data_section_name);
@@ -25758,7 +25780,24 @@ rs6000_xcoff_select_section (tree decl, int reloc,
{
#if HAVE_AS_TLS
if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
- return tls_data_section;
+ {
+ if (TREE_PUBLIC (decl))
+ return tls_data_section;
+ else if (DECL_INITIAL (decl) == NULL_TREE
+ || DECL_INITIAL (decl) == error_mark_node
+ || (flag_zero_initialized_in_bss
+ /* Leave constant zeroes in .rodata so they
+ can be shared. */
+ && !TREE_READONLY (decl)
+ && initializer_zerop (DECL_INITIAL (decl))))
+ {
+ /* Convert to COMMON to emit in BSS. */
+ DECL_COMMON (decl) = 1;
+ return tls_comm_section;
+ }
+ else
+ return tls_private_data_section;
+ }
else
#endif
if (TREE_PUBLIC (decl))
@@ -25857,10 +25896,12 @@ rs6000_xcoff_file_start (void)
main_input_filename, ".bss_");
rs6000_gen_section_name (&xcoff_private_data_section_name,
main_input_filename, ".rw_");
+ rs6000_gen_section_name (&xcoff_read_only_section_name,
+ main_input_filename, ".ro_");
rs6000_gen_section_name (&xcoff_tls_data_section_name,
main_input_filename, ".tls_");
- rs6000_gen_section_name (&xcoff_read_only_section_name,
- main_input_filename, ".ro_");
+ rs6000_gen_section_name (&xcoff_tbss_section_name,
+ main_input_filename, ".tbss_[UL]");
fputs ("\t.file\t", asm_out_file);
output_quoted_string (asm_out_file, main_input_filename);
@@ -25886,6 +25927,29 @@ rs6000_xcoff_file_end (void)
? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
asm_out_file);
}
+
+static void
+rs6000_xcoff_encode_section_info (tree decl, rtx rtl, int first)
+{
+ rtx symbol;
+ int flags;
+
+ default_encode_section_info (decl, rtl, first);
+
+ /* Careful not to prod global register variables. */
+ if (!MEM_P (rtl))
+ return;
+ symbol = XEXP (rtl, 0);
+ if (GET_CODE (symbol) != SYMBOL_REF)
+ return;
+
+ flags = SYMBOL_REF_FLAGS (symbol);
+
+ if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
+ flags &= ~SYMBOL_FLAG_HAS_BLOCK_INFO;
+
+ SYMBOL_REF_FLAGS (symbol) = flags;
+}
#endif /* TARGET_XCOFF */
/* Compute a (partial) cost for rtx X. Return true if the complete
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] AIX native TLS support
2012-11-29 2:55 David Edelsohn
@ 2012-12-02 16:42 ` David Edelsohn
0 siblings, 0 replies; 3+ messages in thread
From: David Edelsohn @ 2012-12-02 16:42 UTC (permalink / raw)
To: GCC Patches
I checked in the patch.
The problem, at least for libgomp testsuite, is GCC is not correctly
emitting the definitions of some variables specified with
#pragma omp threadprivate(XXX)
The symptoms are the variable is placed in a TLS section anchor block,
which never should happen, or the BSS variable is not visible.
- David
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH] AIX native TLS support
@ 2012-11-29 2:55 David Edelsohn
2012-12-02 16:42 ` David Edelsohn
0 siblings, 1 reply; 3+ messages in thread
From: David Edelsohn @ 2012-11-29 2:55 UTC (permalink / raw)
To: GCC Patches
Below is a first attempt at native TLS support on AIX. It produces
the correct syntax and works for small testcases. All of GCC can
build with it enabled, but libstdc++ and libgomp do not run correctly,
so I am not enabling it by default.
The implementation treats local-dynamic as general-dynamic because AIX
local-dynamic is a mess to implement for not much gain.
Unlike PPC64 Linux, AIX requires TLS symbols to be placed in a special
CSECT mapping class and referenced with special TOC symbol
decorations, not assembler decorations left to the linker. The patch
leaves PPC64 Linux behavior unchanged.
Thanks, David
* xcoffout.c (xcoff_tls_data_section_name): Define.
* xcoffout.h (xcoff_tls_data_section_name): Declare.
* config/rs6000/rs6000.c (tls_data_section): Define.
(TARGET_USE_BLOCKS_FOR_DECL_P): Define.
(rs6000_legitimize_tls_address_aix): New function.
(rs6000_legitimize_tls_address): Use new function for AIX.
(rs6000_cannot_force_const_mem): No sum in TLS TOC symbols.
Allow TLS symbol in constant pool other than ELF.
(rs6000_legitimate_address_p): Allow TLS symbol other than ELF.
(rs6000_assemble_visibility): Do not emit anything on AIX.
(output_toc): Handle alias of TLS general-dynamic symbols.
Emit TLS decorations on symbols.
(rs6000_use_blocks_for_decl_p): New function.
(rs6000_xcoff_output_tls_section_asm_op): New function.
(rs6000_xcoff_asm_init_sections): Initialize tls_data_section.
(rs6000_xcoff_select_section): Choose tls_data_section for
thread-local storage.
(rs6000_xcoff_file_start): Generate xcoff_tls_data_section_name.
(rs6000_legitimate_constant_p): Allow TLS symbol other than ELF.
* config/rs6000/rs6000.md (tls_tls_): Restrict to ELF.
(tls_get_tpointer): New.
(tle_get_tpointer_internal): New.
(tls_get_addr<mode>): New.
(tls_get_addr_internal<mode>): New.
Index: xcoffout.c
===================================================================
--- xcoffout.c (revision 193917)
+++ xcoffout.c (working copy)
@@ -66,6 +66,7 @@
char *xcoff_bss_section_name;
char *xcoff_private_data_section_name;
+char *xcoff_tls_data_section_name;
char *xcoff_read_only_section_name;
/* Last source file name mentioned in a NOTE insn. */
Index: xcoffout.h
===================================================================
--- xcoffout.h (revision 193917)
+++ xcoffout.h (working copy)
@@ -126,6 +126,7 @@
extern char *xcoff_bss_section_name;
extern char *xcoff_private_data_section_name;
+extern char *xcoff_tls_data_section_name;
extern char *xcoff_read_only_section_name;
/* Last source file name mentioned in a NOTE insn. */
Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c (revision 193917)
+++ config/rs6000/rs6000.c (working copy)
@@ -208,6 +208,7 @@
static GTY(()) section *read_only_data_section;
static GTY(()) section *private_data_section;
+static GTY(()) section *tls_data_section;
static GTY(()) section *read_only_private_data_section;
static GTY(()) section *sdata2_section;
static GTY(()) section *toc_section;
@@ -1405,6 +1406,8 @@
#define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
#define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
+#undef TARGET_USE_BLOCKS_FOR_DECL_P
+#define TARGET_USE_BLOCKS_FOR_DECL_P rs6000_use_blocks_for_decl_p
#undef TARGET_BUILTIN_RECIPROCAL
#define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
@@ -5882,6 +5885,75 @@
return rs6000_got_symbol;
}
+/* AIX Thread-Local Address support. */
+
+static rtx
+rs6000_legitimize_tls_address_aix (rtx addr, enum tls_model model)
+{
+ rtx sym, mem, tocref, tlsreg, tmpreg, dest;
+
+ /* Place addr into TOC constant pool. */
+ sym = force_const_mem (GET_MODE (addr), addr);
+
+ /* Output the TOC entry and create the MEM referencing the value. */
+ if (constant_pool_expr_p (XEXP (sym, 0))
+ && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (XEXP
(sym, 0)), Pmode))
+ {
+ tocref = create_TOC_reference (XEXP (sym, 0), NULL_RTX);
+ mem = gen_const_mem (Pmode, tocref);
+ set_mem_alias_set (mem, get_TOC_alias_set ());
+ }
+ else
+ return sym;
+
+ /* Use global-dynamic for local-dynamic. */
+ if (model == TLS_MODEL_GLOBAL_DYNAMIC
+ || model == TLS_MODEL_LOCAL_DYNAMIC)
+ {
+ rtx module = gen_reg_rtx (Pmode);
+ /* Create new TOC reference for @m symbol. */
+ const char *name = XSTR (XVECEXP (XEXP (mem, 0), 0, 0), 0);
+ char *name2 = XALLOCAVEC (char, strlen (name) + 1);
+ strcpy (name2, "*LCM");
+ strcat (name2, name + 3);
+ tocref = create_TOC_reference (gen_rtx_SYMBOL_REF (Pmode,
+ ggc_alloc_string (name2,
+ strlen (name2))),
+ NULL_RTX);
+ rtx mem2 = gen_const_mem (Pmode, tocref);
+ set_mem_alias_set (mem2, get_TOC_alias_set ());
+
+ dest = gen_reg_rtx (Pmode);
+ tmpreg = gen_reg_rtx (Pmode);
+ emit_insn (gen_rtx_SET (VOIDmode, tmpreg, mem));
+ emit_insn (gen_rtx_SET (VOIDmode, module, mem2));
+ if (TARGET_32BIT)
+ emit_insn (gen_tls_get_addrsi (dest, module, tmpreg));
+ else
+ emit_insn (gen_tls_get_addrdi (dest, module, tmpreg));
+ return dest;
+ }
+ /* Obtain TLS pointer: 32 bit call or 64 bit GPR 13. */
+ else if (TARGET_32BIT)
+ {
+ tlsreg = gen_reg_rtx (SImode);
+ emit_insn (gen_tls_get_tpointer (tlsreg));
+ }
+ else
+ tlsreg = gen_rtx_REG (DImode, 13);
+
+ /* Load the TOC value into temporary register. */
+ tmpreg = gen_reg_rtx (Pmode);
+ emit_insn (gen_rtx_SET (VOIDmode, tmpreg, mem));
+ set_unique_reg_note (get_last_insn (), REG_EQUAL,
+ gen_rtx_MINUS (Pmode, addr, tlsreg));
+
+ /* Add TOC symbol value to TLS pointer. */
+ dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, tmpreg, tlsreg));
+
+ return dest;
+}
+
/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
this (thread-local) address. */
@@ -5890,6 +5962,9 @@
{
rtx dest, insn;
+ if (TARGET_XCOFF)
+ return rs6000_legitimize_tls_address_aix (addr, model);
+
dest = gen_reg_rtx (Pmode);
if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
{
@@ -6085,7 +6160,15 @@
&& GET_CODE (XEXP (x, 0)) == UNSPEC)
return true;
- return rs6000_tls_referenced_p (x);
+ /* A TLS symbol in the TOC cannot contain a sum. */
+ if (GET_CODE (x) == CONST
+ && GET_CODE (XEXP (x, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
+ && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) != 0)
+ return true;
+
+ /* Do not place an ELF TLS symbol in the constant pool. */
+ return TARGET_ELF && rs6000_tls_referenced_p (x);
}
/* Return 1 if *X is a thread-local symbol. This is the same as
@@ -6380,7 +6463,7 @@
&& INTVAL (XEXP (x, 1)) == -16)
x = XEXP (x, 0);
- if (RS6000_SYMBOL_REF_TLS_P (x))
+ if (TARGET_ELF && RS6000_SYMBOL_REF_TLS_P (x))
return 0;
if (legitimate_indirect_address_p (x, reg_ok_strict))
return 1;
@@ -15486,6 +15569,9 @@
static void
rs6000_assemble_visibility (tree decl, int vis)
{
+ if (TARGET_XCOFF)
+ return;
+
/* Functions need to have their entry point symbol visibility set as
well as their descriptor symbol visibility. */
if (DEFAULT_ABI == ABI_AIX
@@ -21934,6 +22020,20 @@
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
found)->labelno));
+
+#ifdef HAVE_AS_TLS
+ if (TARGET_XCOFF && GET_CODE (x) == SYMBOL_REF
+ && (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_GLOBAL_DYNAMIC
+ || SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC))
+ {
+ fputs ("\t.set ", file);
+ ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCM");
+ fprintf (file, "%d,", labelno);
+ ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCM");
+ fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
+ found)->labelno));
+ }
+#endif
return;
}
}
@@ -22206,6 +22306,29 @@
}
else
output_addr_const (file, x);
+
+#if HAVE_AS_TLS
+ if (TARGET_XCOFF && GET_CODE (base) == SYMBOL_REF)
+ {
+ if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_EXEC)
+ fputs ("[TL]@le", file);
+ else if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_INITIAL_EXEC)
+ fputs ("[TL]@ie", file);
+ /* Use global-dynamic for local-dynamic. */
+ else if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_GLOBAL_DYNAMIC
+ || SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_DYNAMIC)
+ {
+ fputs ("[TL]\n", file);
+ (*targetm.asm_out.internal_label) (file, "LCM", labelno);
+ fputs ("\t.tc .", file);
+ RS6000_OUTPUT_BASENAME (file, name);
+ fputs ("[TC],", file);
+ output_addr_const (file, x);
+ fputs ("[TL]@m", file);
+ }
+ }
+#endif
+
putc ('\n', file);
}
\f
@@ -24884,6 +25007,14 @@
{
return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
}
+
+/* Do not place thread-local symbols refs in the object blocks. */
+
+static bool
+rs6000_use_blocks_for_decl_p (const_tree decl)
+{
+ return !DECL_THREAD_LOCAL_P (decl);
+}
\f
/* Return a REG that occurs in ADDR with coefficient 1.
ADDR can be effectively incremented by incrementing REG.
@@ -25516,6 +25647,14 @@
XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
}
+static void
+rs6000_xcoff_output_tls_section_asm_op (const void *directive)
+{
+ fprintf (asm_out_file, "\t.csect %s[TL],%s\n",
+ *(const char *const *) directive,
+ XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
+}
+
/* A get_unnamed_section callback, used for switching to toc_section. */
static void
@@ -25553,6 +25692,11 @@
rs6000_xcoff_output_readwrite_section_asm_op,
&xcoff_private_data_section_name);
+ tls_data_section
+ = get_unnamed_section (SECTION_TLS,
+ rs6000_xcoff_output_tls_section_asm_op,
+ &xcoff_tls_data_section_name);
+
read_only_private_data_section
= get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
&xcoff_private_data_section_name);
@@ -25604,7 +25748,12 @@
}
else
{
- if (TREE_PUBLIC (decl))
+#if HAVE_AS_TLS
+ if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
+ return tls_data_section;
+ else
+#endif
+ if (TREE_PUBLIC (decl))
return data_section;
else
return private_data_section;
@@ -25700,6 +25849,8 @@
main_input_filename, ".bss_");
rs6000_gen_section_name (&xcoff_private_data_section_name,
main_input_filename, ".rw_");
+ rs6000_gen_section_name (&xcoff_tls_data_section_name,
+ main_input_filename, ".tls_");
rs6000_gen_section_name (&xcoff_read_only_section_name,
main_input_filename, ".ro_");
@@ -28164,7 +28315,7 @@
static bool
rs6000_legitimate_constant_p (enum machine_mode mode, rtx x)
{
- if (rs6000_tls_referenced_p (x))
+ if (TARGET_ELF && rs6000_tls_referenced_p (x))
return false;
return ((GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_VECTOR)
Index: config/rs6000/rs6000.md
===================================================================
--- config/rs6000/rs6000.md (revision 193917)
+++ config/rs6000/rs6000.md (working copy)
@@ -9983,8 +9983,51 @@
(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
UNSPEC_TLSTLS))]
- "HAVE_AS_TLS"
+ "TARGET_ELF && HAVE_AS_TLS"
"add %0,%1,%2@tls")
+
+(define_expand "tls_get_tpointer"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "")
+ (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
+ "TARGET_XCOFF && HAVE_AS_TLS"
+ "
+{
+ emit_insn (gen_tls_get_tpointer_internal ());
+ emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
+ DONE;
+}")
+
+(define_insn "tls_get_tpointer_internal"
+ [(set (reg:SI 3)
+ (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
+ (clobber (reg:SI LR_REGNO))]
+ "TARGET_XCOFF && HAVE_AS_TLS"
+ "bla __get_tpointer")
+
+(define_expand "tls_get_addr<mode>"
+ [(set (match_operand:P 0 "gpc_reg_operand" "")
+ (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
+ (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
+ "TARGET_XCOFF && HAVE_AS_TLS"
+ "
+{
+ emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
+ emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
+ emit_insn (gen_tls_get_addr_internal<mode> ());
+ emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
+ DONE;
+}")
+
+(define_insn "tls_get_addr_internal<mode>"
+ [(set (reg:P 3)
+ (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
+ (clobber (reg:P 0))
+ (clobber (reg:P 5))
+ (clobber (reg:P 11))
+ (clobber (reg:CC CR0_REGNO))
+ (clobber (reg:P LR_REGNO))]
+ "TARGET_XCOFF && HAVE_AS_TLS"
+ "bla __tls_get_addr")
\f
;; Next come insns related to the calling sequence.
;;
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-12-12 20:51 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-12 20:51 [PATCH] AIX native TLS support David Edelsohn
-- strict thread matches above, loose matches on Subject: below --
2012-11-29 2:55 David Edelsohn
2012-12-02 16:42 ` David Edelsohn
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).