static rtx
rs6000_legitimize_tls_address_aix (rtx addr, enum tls_model model)
{
- rtx sym, mem, tocref, tlsreg, tmpreg, dest, tlsaddr;
+ rtx sym, mem, tocref, tlsreg, tmpreg, dest;
const char *name;
char *tlsname;
- name = XSTR (addr, 0);
- /* Append TLS CSECT qualifier, unless the symbol already is qualified
- or the symbol will be in TLS private data section. */
- if (name[strlen (name) - 1] != ']'
- && (TREE_PUBLIC (SYMBOL_REF_DECL (addr))
- || bss_initializer_p (SYMBOL_REF_DECL (addr))))
- {
- tlsname = XALLOCAVEC (char, strlen (name) + 4);
- strcpy (tlsname, name);
- strcat (tlsname,
- bss_initializer_p (SYMBOL_REF_DECL (addr)) ? "[UL]" : "[TL]");
- tlsaddr = copy_rtx (addr);
- XSTR (tlsaddr, 0) = ggc_strdup (tlsname);
- }
- else
- tlsaddr = addr;
-
/* Place addr into TOC constant pool. */
- sym = force_const_mem (GET_MODE (tlsaddr), tlsaddr);
+ 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))
tree decl ATTRIBUTE_UNUSED)
{
int smclass;
- static const char * const suffix[5] = { "PR", "RO", "RW", "TL", "XO" };
+ static const char * const suffix[7]
+ = { "PR", "RO", "RW", "BS", "TL", "UL", "XO" };
if (flags & SECTION_EXCLUDE)
- smclass = 4;
+ smclass = 6;
else if (flags & SECTION_DEBUG)
{
fprintf (asm_out_file, "\t.dwsect %s\n", name);
else if (flags & SECTION_CODE)
smclass = 0;
else if (flags & SECTION_TLS)
- smclass = 3;
+ {
+ if (flags & SECTION_BSS)
+ smclass = 5;
+ else
+ smclass = 4;
+ }
else if (flags & SECTION_WRITE)
- smclass = 2;
+ {
+ if (flags & SECTION_BSS)
+ smclass = 3;
+ else
+ smclass = 2;
+ }
else
smclass = 1;
if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
{
if (bss_initializer_p (decl))
- {
- /* Convert to COMMON to emit in BSS. */
- DECL_COMMON (decl) = 1;
- return tls_comm_section;
- }
+ return tls_comm_section;
else if (TREE_PUBLIC (decl))
return tls_data_section;
else
{
const char *name;
- /* Use select_section for private data and uninitialized data with
- alignment <= BIGGEST_ALIGNMENT. */
- if (!TREE_PUBLIC (decl)
- || DECL_COMMON (decl)
- || (DECL_INITIAL (decl) == NULL_TREE
- && DECL_ALIGN (decl) <= BIGGEST_ALIGNMENT)
- || DECL_INITIAL (decl) == error_mark_node
- || (flag_zero_initialized_in_bss
- && initializer_zerop (DECL_INITIAL (decl))))
- return;
-
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
name = (*targetm.strip_name_encoding) (name);
set_decl_section_name (decl, name);
unsigned int align;
unsigned int flags = default_section_type_flags (decl, name, reloc);
+ if (decl && DECL_P (decl) && VAR_P (decl) && bss_initializer_p (decl))
+ flags |= SECTION_BSS;
+
/* Align to at least UNIT size. */
if ((flags & SECTION_CODE) != 0 || !decl || !DECL_P (decl))
align = MIN_UNITS_PER_WORD;
{
const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
fputs (GLOBAL_ASM_OP, stream);
- RS6000_OUTPUT_BASENAME (stream, name);
+ assemble_name (stream, name);
#ifdef HAVE_GAS_HIDDEN
fputs (rs6000_xcoff_visibility (decl), stream);
#endif
tree decl ATTRIBUTE_UNUSED,
const char *name,
unsigned HOST_WIDE_INT size,
- unsigned HOST_WIDE_INT align)
+ unsigned int align)
{
- unsigned HOST_WIDE_INT align2 = 2;
+ unsigned int align2 = 2;
+
+ if (align == 0)
+ align = DATA_ABI_ALIGNMENT (TREE_TYPE (decl), DECL_ALIGN (decl));
if (align > 32)
align2 = floor_log2 (align / BITS_PER_UNIT);
else if (size > 4)
align2 = 3;
- fputs (COMMON_ASM_OP, stream);
- RS6000_OUTPUT_BASENAME (stream, name);
+ if (! DECL_COMMON (decl))
+ {
+ /* Forget section. */
+ in_section = NULL;
+
+ /* Globalize TLS BSS. */
+ if (TREE_PUBLIC (decl) && DECL_THREAD_LOCAL_P (decl))
+ fprintf (stream, "\t.globl %s\n", name);
- fprintf (stream,
- "," HOST_WIDE_INT_PRINT_UNSIGNED "," HOST_WIDE_INT_PRINT_UNSIGNED,
- size, align2);
+ /* Switch to section and skip space. */
+ fprintf (stream, "\t.csect %s,%u\n", name, align2);
+ ASM_DECLARE_OBJECT_NAME (stream, name, decl);
+ ASM_OUTPUT_SKIP (stream, size ? size : 1);
+ return;
+ }
+
+ if (TREE_PUBLIC (decl))
+ {
+ fprintf (stream,
+ "\t.comm %s," HOST_WIDE_INT_PRINT_UNSIGNED ",%u" ,
+ name, size, align2);
#ifdef HAVE_GAS_HIDDEN
- if (decl != NULL)
- fputs (rs6000_xcoff_visibility (decl), stream);
+ if (decl != NULL)
+ fputs (rs6000_xcoff_visibility (decl), stream);
#endif
- putc ('\n', stream);
+ putc ('\n', stream);
+ }
+ else
+ fprintf (stream,
+ "\t.lcomm %s," HOST_WIDE_INT_PRINT_UNSIGNED ",%s,%u\n",
+ (*targetm.strip_name_encoding) (name), size, name, align2);
}
/* This macro produces the initial definition of a object (variable) name.
SYMBOL_REF_FLAGS (symbol) = flags;
- /* Append mapping class to extern decls. */
symname = XSTR (symbol, 0);
- if (decl /* sync condition with assemble_external () */
- && DECL_P (decl) && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
- && ((TREE_CODE (decl) == VAR_DECL && !DECL_THREAD_LOCAL_P (decl))
- || TREE_CODE (decl) == FUNCTION_DECL)
+
+ /* Append CSECT mapping class, unless the symbol already is qualified. */
+ if (decl
+ && DECL_P (decl)
+ && VAR_OR_FUNCTION_DECL_P (decl)
+ && lookup_attribute ("alias", DECL_ATTRIBUTES (decl)) == NULL_TREE
&& symname[strlen (symname) - 1] != ']')
{
- char *newname = (char *) alloca (strlen (symname) + 5);
- strcpy (newname, symname);
- strcat (newname, (TREE_CODE (decl) == FUNCTION_DECL
- ? "[DS]" : "[UA]"));
- XSTR (symbol, 0) = ggc_strdup (newname);
+ const char *smclass = NULL;
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ if (DECL_EXTERNAL (decl))
+ smclass = "[DS]";
+ }
+ else if (DECL_THREAD_LOCAL_P (decl))
+ {
+ if (bss_initializer_p (decl))
+ smclass = "[UL]";
+ else if (flag_data_sections)
+ smclass = "[TL]";
+ }
+ else if (DECL_EXTERNAL (decl))
+ smclass = "[UA]";
+ else if (bss_initializer_p (decl))
+ smclass = "[BS]";
+ else if (flag_data_sections)
+ {
+ /* This must exactly match the logic of select section. */
+ if (decl_readonly_section (decl, compute_reloc_for_var (decl)))
+ smclass = "[RO]";
+ else
+ smclass = "[RW]";
+ }
+
+ if (smclass != NULL)
+ {
+ char *newname = XALLOCAVEC (char, strlen (symname) + 5);
+
+ strcpy (newname, symname);
+ strcat (newname, smclass);
+ XSTR (symbol, 0) = ggc_strdup (newname);
+ }
}
}
#endif /* HAVE_AS_TLS */
const char *name, const char *val)
{
fputs ("\t.weak\t", stream);
- RS6000_OUTPUT_BASENAME (stream, name);
+ assemble_name (stream, name);
if (decl && TREE_CODE (decl) == FUNCTION_DECL
&& DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS)
{
- if (TARGET_XCOFF)
+ if (TARGET_XCOFF && name[strlen (name) - 1] != ']')
fputs ("[DS]", stream);
#if TARGET_XCOFF && HAVE_GAS_HIDDEN
if (TARGET_XCOFF)
#define TARGET_ENCODE_SECTION_INFO rs6000_xcoff_encode_section_info
#endif
#define ASM_OUTPUT_ALIGNED_DECL_COMMON rs6000_xcoff_asm_output_aligned_decl_common
+#define ASM_OUTPUT_ALIGNED_DECL_LOCAL rs6000_xcoff_asm_output_aligned_decl_common
+#define ASM_OUTPUT_ALIGNED_BSS rs6000_xcoff_asm_output_aligned_decl_common
/* FP save and restore routines. */
#define SAVE_FP_PREFIX "._savef"
to define a global common symbol. */
#define COMMON_ASM_OP "\t.comm "
-
-/* This says how to output an assembler line
- to define a local common symbol.
- The assembler in AIX 6.1 and later supports an alignment argument.
- For earlier releases of AIX, we try to maintain
- alignment after preceding TOC section if it was aligned
- for 64-bit mode. */
-
#define LOCAL_COMMON_ASM_OP "\t.lcomm "
-#if TARGET_AIX_VERSION >= 61
-#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
- do { fputs (LOCAL_COMMON_ASM_OP, (FILE)); \
- RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
- if ((ALIGN) > 32) \
- fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",%s%u_,%u\n", \
- (SIZE), xcoff_bss_section_name, \
- floor_log2 ((ALIGN) / BITS_PER_UNIT), \
- floor_log2 ((ALIGN) / BITS_PER_UNIT)); \
- else if ((SIZE) > 4) \
- fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",%s3_,3\n", \
- (SIZE), xcoff_bss_section_name); \
- else \
- fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",%s,2\n", \
- (SIZE), xcoff_bss_section_name); \
- } while (0)
-#endif
-
-#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
- do { fputs (LOCAL_COMMON_ASM_OP, (FILE)); \
- RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
- fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",%s\n", \
- (TARGET_32BIT ? (SIZE) : (ROUNDED)), \
- xcoff_bss_section_name); \
- } while (0)
-
#ifdef HAVE_AS_TLS
-#define ASM_OUTPUT_TLS_COMMON(FILE, DECL, NAME, SIZE) \
- do { fputs (COMMON_ASM_OP, (FILE)); \
- RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
- fprintf ((FILE), "[UL]," HOST_WIDE_INT_PRINT_UNSIGNED"\n", \
- (SIZE)); \
+#define ASM_OUTPUT_TLS_COMMON(FILE, DECL, NAME, SIZE) \
+ do { \
+ rs6000_xcoff_asm_output_aligned_decl_common ((FILE), (DECL), (NAME), (SIZE), 0); \
} while (0)
#endif