+2016-11-06 David Edelsohn <dje.gcc@gmail.com>
+
+ * configure.ac (.hidden): Change to conftest_s string. Provide string
+ for AIX assembler.
+ (gcc_cv_ld_hidden): Yes for AIX.
+ * configure: Regenerate.
+
+ * dwarf2asm.c (USE_LINKONCE_INDIRECT): Don't set for AIX (XCOFF).
+
+ * config/rs6000/rs6000-protos.h (rs6000_asm_weaken_decl): Declare
+ (rs6000_xcoff_asm_output_aligned_decl_common): Declare.
+ * config/rs6000/xcoff.h (TARGET_ASM_GLOBALIZE_DECL_NAME): Define.
+ (ASM_OUTPUT_ALIGNED_DECL_COMMON): Define.
+ (ASM_OUTPUT_ALIGNED_COMMON): Delete.
+ * config/rs6000/rs6000.c (rs6000_init_builtins): Change clog rename
+ from #if to if.
+ (rs6000_xcoff_visibility): New.
+ (rs6000_xcoff_declare_function_name): Add visibility support.
+ (rs6000_xcoff_asm_globalize_decl_name): New.
+ (rs6000_xcoff_asm_output_aligned_decl_common): New.
+ (rs6000_asm_weaken_decl): New.
+ (rs6000_code_end): Disable HIDDEN_LINKONCE on XCOFF.
+ config/rs6000/rs6000.h (ASM_WEAKEN_DECL): Change definition to
+ reference function.
+
2016-11-06 Jack Howarth <howarth.at.gcc@gmail.com>
PR driver/78206
extern rtx rs6000_va_arg (tree, tree);
extern int function_ok_for_sibcall (tree);
extern int rs6000_reg_parm_stack_space (tree, bool);
+extern void rs6000_asm_weaken_decl (FILE *, tree, const char *, const char *);
extern void rs6000_xcoff_declare_function_name (FILE *, const char *, tree);
extern void rs6000_xcoff_declare_object_name (FILE *, const char *, tree);
+extern void rs6000_xcoff_asm_output_aligned_decl_common (FILE *, tree,
+ const char *,
+ unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT);
extern void rs6000_elf_declare_function_name (FILE *, const char *, tree);
extern bool rs6000_elf_in_small_data_p (const_tree);
#ifdef ARGS_SIZE_RTX
def_builtin ("__builtin_cpu_is", ftype, RS6000_BUILTIN_CPU_IS);
def_builtin ("__builtin_cpu_supports", ftype, RS6000_BUILTIN_CPU_SUPPORTS);
-#if TARGET_XCOFF
/* AIX libm provides clog as __clog. */
- if ((tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
+ if (TARGET_XCOFF &&
+ (tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
set_user_assembler_name (tdecl, "__clog");
-#endif
#ifdef SUBTARGET_INIT_BUILTINS
SUBTARGET_INIT_BUILTINS;
return false;
}
+
+#ifdef HAVE_GAS_HIDDEN
+/* Helper function to calculate visibility of a DECL
+ and return the value as a const string. */
+
+static const char *
+rs6000_xcoff_visibility (tree decl)
+{
+ static const char * const visibility_types[] = {
+ "", ",protected", ",hidden", ",internal"
+ };
+
+ enum symbol_visibility vis = DECL_VISIBILITY (decl);
+
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && cgraph_node::get (decl)
+ && cgraph_node::get (decl)->instrumentation_clone
+ && cgraph_node::get (decl)->instrumented_version)
+ vis = DECL_VISIBILITY (cgraph_node::get (decl)->instrumented_version->decl);
+
+ return visibility_types[vis];
+}
+#endif
+
+
/* This macro produces the initial definition of a function name.
On the RS/6000, we need to place an extra '.' in the function name and
output the function descriptor.
}
fputs ("\t.globl .", file);
RS6000_OUTPUT_BASENAME (file, buffer);
+#ifdef HAVE_GAS_HIDDEN
+ fputs (rs6000_xcoff_visibility (decl), file);
+#endif
putc ('\n', file);
}
}
return;
}
+
+/* Output assembly language to globalize a symbol from a DECL,
+ possibly with visibility. */
+
+void
+rs6000_xcoff_asm_globalize_decl_name (FILE *stream, tree decl)
+{
+ const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+ fputs (GLOBAL_ASM_OP, stream);
+ RS6000_OUTPUT_BASENAME (stream, name);
+#ifdef HAVE_GAS_HIDDEN
+ fputs (rs6000_xcoff_visibility (decl), stream);
+#endif
+ putc ('\n', stream);
+}
+
+/* Output assembly language to define a symbol as COMMON from a DECL,
+ possibly with visibility. */
+
+void
+rs6000_xcoff_asm_output_aligned_decl_common (FILE *stream,
+ tree decl ATTRIBUTE_UNUSED,
+ const char *name,
+ unsigned HOST_WIDE_INT size,
+ unsigned HOST_WIDE_INT align)
+{
+ unsigned HOST_WIDE_INT align2 = 2;
+
+ 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);
+
+ fprintf (stream,
+ "," HOST_WIDE_INT_PRINT_UNSIGNED "," HOST_WIDE_INT_PRINT_UNSIGNED,
+ size, align2);
+
+#ifdef HAVE_GAS_HIDDEN
+ fputs (rs6000_xcoff_visibility (decl), stream);
+#endif
+ putc ('\n', stream);
+}
+
/* This macro produces the initial definition of a object (variable) name.
Because AIX assembler's .set command has unexpected semantics, we output
all aliases as alternative labels in front of the definition. */
#endif /* HAVE_AS_TLS */
#endif /* TARGET_XCOFF */
+void
+rs6000_asm_weaken_decl (FILE *stream, tree decl,
+ const char *name, const char *val)
+{
+ fputs ("\t.weak\t", stream);
+ RS6000_OUTPUT_BASENAME (stream, name);
+ if (decl && TREE_CODE (decl) == FUNCTION_DECL
+ && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS)
+ {
+ if (TARGET_XCOFF)
+ fputs ("[DS]", stream);
+#if HAVE_GAS_HIDDEN
+ if (TARGET_XCOFF)
+ fputs (rs6000_xcoff_visibility (decl), stream);
+#endif
+ fputs ("\n\t.weak\t.", stream);
+ RS6000_OUTPUT_BASENAME (stream, name);
+ }
+#if HAVE_GAS_HIDDEN
+ if (TARGET_XCOFF)
+ fputs (rs6000_xcoff_visibility (decl), stream);
+#endif
+ fputc ('\n', stream);
+ if (val)
+ {
+ ASM_OUTPUT_DEF (stream, name, val);
+ if (decl && TREE_CODE (decl) == FUNCTION_DECL
+ && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS)
+ {
+ fputs ("\t.set\t.", stream);
+ RS6000_OUTPUT_BASENAME (stream, name);
+ fputs (",.", stream);
+ RS6000_OUTPUT_BASENAME (stream, val);
+ fputc ('\n', stream);
+ }
+ }
+}
+
+
/* Return true if INSN should not be copied. */
static bool
TREE_STATIC (decl) = 1;
#if RS6000_WEAK
- if (USE_HIDDEN_LINKONCE)
+ if (USE_HIDDEN_LINKONCE && !TARGET_XCOFF)
{
cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
targetm.asm_out.unique_section (decl, 0);
#if RS6000_WEAK
/* Used in lieu of ASM_WEAKEN_LABEL. */
-#define ASM_WEAKEN_DECL(FILE, DECL, NAME, VAL) \
- do \
- { \
- fputs ("\t.weak\t", (FILE)); \
- RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
- if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL \
- && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS) \
- { \
- if (TARGET_XCOFF) \
- fputs ("[DS]", (FILE)); \
- fputs ("\n\t.weak\t.", (FILE)); \
- RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
- } \
- fputc ('\n', (FILE)); \
- if (VAL) \
- { \
- ASM_OUTPUT_DEF ((FILE), (NAME), (VAL)); \
- if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL \
- && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS) \
- { \
- fputs ("\t.set\t.", (FILE)); \
- RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
- fputs (",.", (FILE)); \
- RS6000_OUTPUT_BASENAME ((FILE), (VAL)); \
- fputc ('\n', (FILE)); \
- } \
- } \
- } \
- while (0)
+#define ASM_WEAKEN_DECL(FILE, DECL, NAME, VAL) \
+ rs6000_asm_weaken_decl ((FILE), (DECL), (NAME), (VAL))
#endif
#if HAVE_GAS_WEAKREF
#undef TARGET_DEBUG_UNWIND_INFO
#define TARGET_DEBUG_UNWIND_INFO rs6000_xcoff_debug_unwind_info
#define TARGET_ASM_OUTPUT_ANCHOR rs6000_xcoff_asm_output_anchor
+#define TARGET_ASM_GLOBALIZE_DECL_NAME rs6000_xcoff_asm_globalize_decl_name
#define TARGET_ASM_GLOBALIZE_LABEL rs6000_xcoff_asm_globalize_label
#define TARGET_ASM_INIT_SECTIONS rs6000_xcoff_asm_init_sections
#define TARGET_ASM_RELOC_RW_MASK rs6000_xcoff_reloc_rw_mask
#ifdef HAVE_AS_TLS
#define TARGET_ENCODE_SECTION_INFO rs6000_xcoff_encode_section_info
#endif
+#define ASM_OUTPUT_ALIGNED_DECL_COMMON rs6000_xcoff_asm_output_aligned_decl_common
/* FP save and restore routines. */
#define SAVE_FP_PREFIX "._savef"
#define COMMON_ASM_OP "\t.comm "
-#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
- do { fputs (COMMON_ASM_OP, (FILE)); \
- RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
- if ((ALIGN) > 32) \
- fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", (SIZE), \
- floor_log2 ((ALIGN) / BITS_PER_UNIT)); \
- else if ((SIZE) > 4) \
- fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",3\n", (SIZE)); \
- else \
- fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)); \
- } while (0)
-
/* 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.
# ld, we don't know its patchlevel version, so we set the baseline at 2.13
# to be safe.
# The gcc_GAS_CHECK_FEATURE call just sets a cache variable.
+case "${target}" in
+ *-*-aix*)
+ conftest_s=' .globl foobar,hidden'
+ ;;
+ *)
+ conftest_s=' .hidden foobar
+foobar:'
+ ;;
+esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .hidden" >&5
$as_echo_n "checking assembler for .hidden... " >&6; }
if test "${gcc_cv_as_hidden+set}" = set; then :
then gcc_cv_as_hidden=yes
fi
elif test x$gcc_cv_as != x; then
- $as_echo ' .hidden foobar
-foobar:' > conftest.s
+ $as_echo "$conftest_s" > conftest.s
if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
fi
else
case "${target}" in
+ *-*-aix[789]*)
+ gcc_cv_ld_hidden=yes
+ ;;
*-*-darwin*)
# Darwin ld has some visibility support.
gcc_cv_ld_hidden=yes
# ld, we don't know its patchlevel version, so we set the baseline at 2.13
# to be safe.
# The gcc_GAS_CHECK_FEATURE call just sets a cache variable.
+case "${target}" in
+ *-*-aix*)
+ conftest_s=' .globl foobar,hidden'
+ ;;
+ *)
+ conftest_s=' .hidden foobar
+foobar:'
+ ;;
+esac
gcc_GAS_CHECK_FEATURE([.hidden], gcc_cv_as_hidden,
- [elf,2,13,0],,
-[ .hidden foobar
-foobar:])
+ [elf,2,13,0],, [$conftest_s])
case "${target}" in
*-*-darwin*)
# Darwin as has some visibility support, though with a different syntax.
fi
else
case "${target}" in
+ *-*-aix[789]*)
+ gcc_cv_ld_hidden=yes
+ ;;
*-*-darwin*)
# Darwin ld has some visibility support.
gcc_cv_ld_hidden=yes
static GTY(()) int dw2_const_labelno;
-#if defined(HAVE_GAS_HIDDEN)
+#if defined(HAVE_GAS_HIDDEN) && !defined(XCOFF_DEBUGGING_INFO)
# define USE_LINKONCE_INDIRECT (SUPPORTS_ONE_ONLY)
#else
# define USE_LINKONCE_INDIRECT 0