diff options
author | dje <dje@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-21 17:25:57 +0000 |
---|---|---|
committer | dje <dje@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-21 17:25:57 +0000 |
commit | 35f719486dc3060e599d0b147ff6486f1e03d5b2 (patch) | |
tree | d7e15d93310c71b4b50fe76638218798e8d4132f /gcc/config/rs6000 | |
parent | 9f434e121978b38926bdc6270ad1b666160b513f (diff) | |
download | gcc-35f719486dc3060e599d0b147ff6486f1e03d5b2.tar.gz |
* varasm.c (bss_initializer_p): Remove static.
* output.h (bss_initializer_p): Declare.
* 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_data_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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194675 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 70 | ||||
-rw-r--r-- | gcc/config/rs6000/xcoff.h | 7 |
2 files changed, 67 insertions, 10 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index d25c63c4310..668566eb228 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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,33 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) 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 (bss_initializer_p (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 +25716,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 +25774,18 @@ 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 (bss_initializer_p (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 +25884,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_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_tls_data_section_name, + main_input_filename, ".tls_"); + 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 +25915,31 @@ rs6000_xcoff_file_end (void) ? "\t.long _section_.text\n" : "\t.llong _section_.text\n", asm_out_file); } + +#ifdef HAVE_AS_TLS +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 /* HAVE_AS_TLS */ #endif /* TARGET_XCOFF */ /* Compute a (partial) cost for rtx X. Return true if the complete diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h index 15f8bbf5e3e..4c12e1f4671 100644 --- a/gcc/config/rs6000/xcoff.h +++ b/gcc/config/rs6000/xcoff.h @@ -98,6 +98,9 @@ #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 +#ifdef HAVE_AS_TLS +#define TARGET_ENCODE_SECTION_INFO rs6000_xcoff_encode_section_info +#endif /* FP save and restore routines. */ #define SAVE_FP_PREFIX "._savef" @@ -308,8 +311,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 |