PR c++/14607.
Backported from main.
* configure.ac (HAVE_GAS_NSUBSPA_COMDAT): Add check for .NSUBSPA
COMDAT support.
* configure. config.in: Rebuilt.
* config/pa/pa-protos.h (som_text_section_asm_op,
som_readonly_data_section, som_one_only_readonly_data_section,
som_one_only_data_section, forget_section): Declare.
* pa.c (override_options): Set init_machine_status to
pa_init_machine_status.
(pa_init_machine_status): New function.
(pa_output_function_epilogue): Call forget_section if TARGET_SOM and
TARGET_GAS.
(pa_asm_output_mi_thunk): Likewise.
(som_text_section_asm_op): New function.
(pa_select_section): Call som_one_only_readonly_data_section and
som_one_only_data_section when appropriate.
* pa.h (struct machine_function): Define.
(EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS,
SOM_READONLY_DATA_SECTION_FUNCTION,
SOM_ONE_ONLY_READONLY_DATA_SECTION_FUNCTION
SOM_ONE_ONLY_DATA_SECTION_FUNCTION, FORGET_SECTION_FUNCTION): New
macros.
* som.h (ASM_OUTPUT_FUNCTION_PREFIX): Delete.
(TEXT_SECTION_ASM_OP): Call som_text_section_asm_op.
(READONLY_DATA_ASM_OP, EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS): Delete.
(READONLY_DATA_SECTION): Call som_readonly_data_section when not PIC.
(SUPPORTS_SOM_COMDAT): New define.
(SUPPORTS_ONE_ONLY): True if SUPPORTS_WEAK or SUPPORTS_SOM_COMDAT.
(MAKE_DECL_ONE_ONLY): Rework common support.
From-SVN: r92660
+2004-12-27 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR c++/14607.
+ Backported from main.
+ * configure.ac (HAVE_GAS_NSUBSPA_COMDAT): Add check for .NSUBSPA
+ COMDAT support.
+ * configure. config.in: Rebuilt.
+ * config/pa/pa-protos.h (som_text_section_asm_op,
+ som_readonly_data_section, som_one_only_readonly_data_section,
+ som_one_only_data_section, forget_section): Declare.
+ * pa.c (override_options): Set init_machine_status to
+ pa_init_machine_status.
+ (pa_init_machine_status): New function.
+ (pa_output_function_epilogue): Call forget_section if TARGET_SOM and
+ TARGET_GAS.
+ (pa_asm_output_mi_thunk): Likewise.
+ (som_text_section_asm_op): New function.
+ (pa_select_section): Call som_one_only_readonly_data_section and
+ som_one_only_data_section when appropriate.
+ * pa.h (struct machine_function): Define.
+ (EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS,
+ SOM_READONLY_DATA_SECTION_FUNCTION,
+ SOM_ONE_ONLY_READONLY_DATA_SECTION_FUNCTION
+ SOM_ONE_ONLY_DATA_SECTION_FUNCTION, FORGET_SECTION_FUNCTION): New
+ macros.
+ * som.h (ASM_OUTPUT_FUNCTION_PREFIX): Delete.
+ (TEXT_SECTION_ASM_OP): Call som_text_section_asm_op.
+ (READONLY_DATA_ASM_OP, EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS): Delete.
+ (READONLY_DATA_SECTION): Call som_readonly_data_section when not PIC.
+ (SUPPORTS_SOM_COMDAT): New define.
+ (SUPPORTS_ONE_ONLY): True if SUPPORTS_WEAK or SUPPORTS_SOM_COMDAT.
+ (MAKE_DECL_ONE_ONLY): Rework common support.
+
2004-12-26 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR target/17643
skip when using the GAS .p2align command. */
#undef HAVE_GAS_MAX_SKIP_P2ALIGN
+/* Define if your assembler supports .nsubspa comdat option. */
+#undef HAVE_GAS_NSUBSPA_COMDAT
+
/* Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.
*/
#undef HAVE_GAS_SHF_MERGE
/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t
-/* Define as `__inline' if that's what the C compiler calls it, or to nothing
- if it is not supported. */
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
#undef inline
+#endif
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
extern void override_options (void);
extern void output_ascii (FILE *, const char *, int);
+extern const char * som_text_section_asm_op (void);
extern HOST_WIDE_INT compute_frame_size (HOST_WIDE_INT, int *);
extern int and_mask_p (unsigned HOST_WIDE_INT);
extern int cint_ok_for_move (HOST_WIDE_INT);
#endif
-
#ifdef TREE_CODE
extern int reloc_needed (tree);
#ifdef RTX_CODE
enum machine_mode,
tree, int);
#endif /* TREE_CODE */
+
+/* Functions in varasm.c used by pa.c. */
+extern void som_readonly_data_section (void);
+extern void som_one_only_readonly_data_section (void);
+extern void som_one_only_data_section (void);
+extern void forget_section (void);
#ifdef HPUX_LONG_DOUBLE_LIBRARY
static void pa_hpux_init_libfuncs (void);
#endif
+static struct machine_function * pa_init_machine_status (void);
/* Save the operands last given to a compare for use when we
generate a scc or bcc insn. */
targetm.asm_out.unaligned_op.si = NULL;
targetm.asm_out.unaligned_op.di = NULL;
}
+
+ init_machine_status = pa_init_machine_status;
}
static void
#endif
}
+/* Function to init struct machine_function.
+ This will be called, via a pointer variable,
+ from push_function_context. */
+
+static struct machine_function *
+pa_init_machine_status (void)
+{
+ return ggc_alloc_cleared (sizeof (machine_function));
+}
+
/* If FROM is a probable pointer register, mark TO as a probable
pointer register with the same pointer alignment as FROM. */
fputs ("\t.EXIT\n\t.PROCEND\n", file);
+ if (TARGET_SOM && TARGET_GAS)
+ {
+ /* We done with this subspace except possibly for some additional
+ debug information. Forget that we are in this subspace to ensure
+ that the next function is output in its own subspace. */
+ forget_section ();
+ }
+
if (INSN_ADDRESSES_SET_P ())
{
insn = get_last_nonnote_insn ();
fprintf (file, "\t.align 4\n");
ASM_OUTPUT_LABEL (file, label);
fprintf (file, "\t.word P'%s\n", fname);
- function_section (thunk_fndecl);
}
+ else if (TARGET_SOM && TARGET_GAS)
+ forget_section ();
current_thunk_number++;
nbytes = ((nbytes + FUNCTION_BOUNDARY / BITS_PER_UNIT - 1)
|| GET_CODE (op) == LEU));
}
+/* Return a string to output before text in the current function.
+
+ This function is only used with SOM. Because we don't support
+ named subspaces, we can only create a new subspace or switch back
+ to the default text subspace. */
+const char *
+som_text_section_asm_op (void)
+{
+ if (!TARGET_SOM)
+ return "";
+
+ if (TARGET_GAS)
+ {
+ if (cfun && !cfun->machine->in_nsubspa)
+ {
+ /* We only want to emit a .nsubspa directive once at the
+ start of the function. */
+ cfun->machine->in_nsubspa = 1;
+
+ /* Create a new subspace for the text. This provides
+ better stub placement and one-only functions. */
+ if (cfun->decl
+ && DECL_ONE_ONLY (cfun->decl)
+ && !DECL_WEAK (cfun->decl))
+ return
+ "\t.SPACE $TEXT$\n\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,SORT=24,COMDAT";
+
+ return "\t.SPACE $TEXT$\n\t.NSUBSPA $CODE$";
+ }
+ else
+ {
+ /* There isn't a current function or the body of the current
+ function has been completed. So, we are changing to the
+ text section to output debugging information. Do this in
+ the default text section. We need to forget that we are
+ in the text section so that the function text_section in
+ varasm.c will call us the next time around. */
+ forget_section ();
+ }
+ }
+
+ return "\t.SPACE $TEXT$\n\t.SUBSPA $CODE$";
+}
+
/* On hpux10, the linker will give an error if we have a reference
in the read-only data section to a symbol defined in a shared
library. Therefore, expressions that might require a reloc can
&& (DECL_INITIAL (exp) == error_mark_node
|| TREE_CONSTANT (DECL_INITIAL (exp)))
&& !reloc)
- readonly_data_section ();
+ {
+ if (TARGET_SOM
+ && DECL_ONE_ONLY (exp)
+ && !DECL_WEAK (exp))
+ som_one_only_readonly_data_section ();
+ else
+ readonly_data_section ();
+ }
else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c'
&& !(TREE_CODE (exp) == STRING_CST && flag_writable_strings)
&& !reloc)
readonly_data_section ();
+ else if (TARGET_SOM
+ && TREE_CODE (exp) == VAR_DECL
+ && DECL_ONE_ONLY (exp)
+ && !DECL_WEAK (exp))
+ som_one_only_data_section ();
else
data_section ();
}
#define CAN_DEBUG_WITHOUT_FP
\f
/* target machine storage layout */
+typedef struct machine_function GTY(())
+{
+ /* Flag indicating that a .NSUBSPA directive has been output for
+ this function. */
+ int in_nsubspa;
+} machine_function;
/* Define this macro if it is advisable to hold scalars in registers
in a wider mode than that declared by the program. In such cases,
goto LABEL
\f
#define TARGET_ASM_SELECT_SECTION pa_select_section
-
+
/* Return a nonzero value if DECL has a section attribute. */
#define IN_NAMED_SECTION_P(DECL) \
((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
&& DECL_SECTION_NAME (DECL) != NULL_TREE)
+/* The following extra sections and extra section functions are only used
+ for SOM, but they must be provided unconditionally because pa.c's calls
+ to the functions might not get optimized out when other object formats
+ are in use. */
+
+#define EXTRA_SECTIONS \
+ in_som_readonly_data, \
+ in_som_one_only_readonly_data, \
+ in_som_one_only_data
+
+#define EXTRA_SECTION_FUNCTIONS \
+ SOM_READONLY_DATA_SECTION_FUNCTION \
+ SOM_ONE_ONLY_READONLY_DATA_SECTION_FUNCTION \
+ SOM_ONE_ONLY_DATA_SECTION_FUNCTION \
+ FORGET_SECTION_FUNCTION
+
+/* SOM puts readonly data in the default $LIT$ subspace when PIC code
+ is not being generated. */
+#define SOM_READONLY_DATA_SECTION_FUNCTION \
+void \
+som_readonly_data_section (void) \
+{ \
+ if (!TARGET_SOM) \
+ return; \
+ if (in_section != in_som_readonly_data) \
+ { \
+ in_section = in_som_readonly_data; \
+ fputs ("\t.SPACE $TEXT$\n\t.SUBSPA $LIT$\n", asm_out_file); \
+ } \
+}
+
+/* When secondary definitions are not supported, SOM makes readonly data one
+ only by creating a new $LIT$ subspace in $TEXT$ with the comdat flag. */
+#define SOM_ONE_ONLY_READONLY_DATA_SECTION_FUNCTION \
+void \
+som_one_only_readonly_data_section (void) \
+{ \
+ if (!TARGET_SOM) \
+ return; \
+ in_section = in_som_one_only_readonly_data; \
+ fputs ("\t.SPACE $TEXT$\n" \
+ "\t.NSUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=0x2c,SORT=16,COMDAT\n",\
+ asm_out_file); \
+}
+
+/* When secondary definitions are not supported, SOM makes data one only by
+ creating a new $DATA$ subspace in $PRIVATE$ with the comdat flag. */
+#define SOM_ONE_ONLY_DATA_SECTION_FUNCTION \
+void \
+som_one_only_data_section (void) \
+{ \
+ if (!TARGET_SOM) \
+ return; \
+ in_section = in_som_one_only_data; \
+ fputs ("\t.SPACE $PRIVATE$\n" \
+ "\t.NSUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31,SORT=24,COMDAT\n", \
+ asm_out_file); \
+}
+
+#define FORGET_SECTION_FUNCTION \
+void \
+forget_section (void) \
+{ \
+ in_section = no_section; \
+}
+
/* Define this macro if references to a symbol must be treated
differently depending on something about the variable or
function named by the symbol (such as what section it is in).
/* Definitions for SOM assembler support.
- Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
#endif
\f
-/* NAME refers to the function's name. If we are placing each function into
- its own section, we need to switch to the section for this function. Note
- that the section name will have a "." prefix. */
-#define ASM_OUTPUT_FUNCTION_PREFIX(FILE, NAME) \
- { \
- const char *name = (*targetm.strip_name_encoding) (NAME); \
- if (TARGET_GAS && in_section == in_text) \
- fputs ("\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n", FILE); \
- else if (TARGET_GAS) \
- fprintf (FILE, \
- "\t.SUBSPA .%s\n", name); \
- }
-
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
do { tree fntype = TREE_TYPE (TREE_TYPE (DECL)); \
tree tree_type = TREE_TYPE (DECL); \
#define TARGET_ASM_FILE_START pa_som_file_start
-/* Output before code. */
-
-/* Supposedly the assembler rejects the command if there is no tab! */
-#define TEXT_SECTION_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $CODE$\n"
-
-/* Output before read-only data. */
-
-/* Supposedly the assembler rejects the command if there is no tab! */
-#define READONLY_DATA_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $LIT$\n"
+/* String to output before text. */
+#define TEXT_SECTION_ASM_OP som_text_section_asm_op ()
-#define EXTRA_SECTIONS in_readonly_data
+/* String to output before writable data. */
+#define DATA_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $DATA$\n"
-#define EXTRA_SECTION_FUNCTIONS \
-extern void readonly_data (void); \
-void \
-readonly_data (void) \
-{ \
- if (in_section != in_readonly_data) \
- { \
- in_section = in_readonly_data; \
- fprintf (asm_out_file, "%s\n", READONLY_DATA_ASM_OP); \
- } \
-}
+/* String to output before uninitialized data. */
+#define BSS_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $BSS$\n"
/* FIXME: HPUX ld generates incorrect GOT entries for "T" fixups
which reference data within the $TEXT$ space (for example constant
$TEXT$ space during PIC generation. Instead place all constant
data into the $PRIVATE$ subspace (this reduces sharing, but it
works correctly). */
-
-#define READONLY_DATA_SECTION (flag_pic ? data_section : readonly_data)
-
-/* Output before writable data. */
-
-/* Supposedly the assembler rejects the command if there is no tab! */
-#define DATA_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $DATA$\n"
-
-/* Output before uninitialized data. */
-
-#define BSS_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $BSS$\n"
+#define READONLY_DATA_SECTION \
+ (flag_pic ? data_section : som_readonly_data_section)
/* We must not have a reference to an external symbol defined in a
shared library in a readonly section, else the SOM linker will
#define SUPPORTS_WEAK 0
#endif
-/* We can support one only if we support weak. */
-#define SUPPORTS_ONE_ONLY SUPPORTS_WEAK
+/* CVS GAS as of 4/28/04 supports a comdat parameter for the .nsubspa
+ directive. This provides one-only linkage semantics even though we
+ don't have weak support. */
+#ifdef HAVE_GAS_NSUBSPA_COMDAT
+#define SUPPORTS_SOM_COMDAT (TARGET_GAS)
+#else
+#define SUPPORTS_SOM_COMDAT 0
+#endif
-/* Use weak (secondary definitions) to make one only declarations. */
-#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
+/* We can support one only if we support weak or comdat. */
+#define SUPPORTS_ONE_ONLY (SUPPORTS_WEAK || SUPPORTS_SOM_COMDAT)
+
+/* We use DECL_COMMON for uninitialized one-only variables as we don't
+ have linkonce .bss. We use SOM secondary definitions or comdat for
+ initialized variables and functions. */
+#define MAKE_DECL_ONE_ONLY(DECL) \
+ do { \
+ if (TREE_CODE (DECL) == VAR_DECL \
+ && (DECL_INITIAL (DECL) == 0 \
+ || DECL_INITIAL (DECL) == error_mark_node)) \
+ DECL_COMMON (DECL) = 1; \
+ else if (SUPPORTS_WEAK) \
+ DECL_WEAK (DECL) = 1; \
+ } while (0)
/* This is how we tell the assembler that a symbol is weak. The SOM
weak implementation uses the secondary definition (sdef) flag.
fi
+echo "$as_me:$LINENO: checking assembler for .nsubspa comdat" >&5
+echo $ECHO_N "checking assembler for .nsubspa comdat... $ECHO_C" >&6
+if test "${gcc_cv_as_nsubspa_comdat+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_nsubspa_comdat=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 15 \) \* 1000 + 91`
+ then gcc_cv_as_nsubspa_comdat=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo ' .SPACE $TEXT$
+ .NSUBSPA $CODE$,COMDAT' > conftest.s
+ if { ac_try='$gcc_cv_as -o conftest.o conftest.s >&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ then
+ gcc_cv_as_nsubspa_comdat=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_nsubspa_comdat" >&5
+echo "${ECHO_T}$gcc_cv_as_nsubspa_comdat" >&6
+if test $gcc_cv_as_nsubspa_comdat = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GAS_NSUBSPA_COMDAT 1
+_ACEOF
+
+fi
+
# .hidden needs to be supported in both the assembler and the linker,
# because GNU LD versions before 2.12.1 have buggy support for STV_HIDDEN.
# This is irritatingly difficult to feature test for; we have to check the
[ .weak foobar],,
[AC_DEFINE(HAVE_GAS_WEAK, 1, [Define if your assembler supports .weak.])])
+gcc_GAS_CHECK_FEATURE([.nsubspa comdat], gcc_cv_as_nsubspa_comdat,
+ [2,15,91],,
+ [ .SPACE $TEXT$
+ .NSUBSPA $CODE$,COMDAT],,
+[AC_DEFINE(HAVE_GAS_NSUBSPA_COMDAT, 1, [Define if your assembler supports .nsubspa comdat option.])])
+
# .hidden needs to be supported in both the assembler and the linker,
# because GNU LD versions before 2.12.1 have buggy support for STV_HIDDEN.
# This is irritatingly difficult to feature test for; we have to check the