OSDN Git Service

* som.h (SUPPORTS_WEAK, SUPPORTS_ONE_ONLY, MAKE_DECL_ONE_ONLY,
[pf3gnuchains/gcc-fork.git] / gcc / config / pa / som.h
index 1f8e5c7..577a67e 100644 (file)
@@ -1,11 +1,11 @@
 /* Definitions for SOM assembler support.
-   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
 GNU CC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 GNU CC is distributed in the hope that it will be useful,
@@ -19,7 +19,8 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 /* So we can conditionalize small amounts of code in pa.c or pa.md.  */
-#define OBJ_SOM
+#undef TARGET_SOM
+#define TARGET_SOM 1
 
 /* We do not use BINCL stabs in SOM.
    ??? If it does not hurt, we probably should to avoid useless divergence
@@ -42,7 +43,7 @@ Boston, MA 02111-1307, USA.  */
     last_function_decl = current_function_decl;                \
     sym_lineno += 1; }
 
-/* gdb needs a null N_SO at the end of each file for scattered loading. */
+/* gdb needs a null N_SO at the end of each file for scattered loading.  */
 
 #undef DBX_OUTPUT_MAIN_SOURCE_FILE_END
 #define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
@@ -51,26 +52,15 @@ Boston, MA 02111-1307, USA.  */
   fprintf (FILE,                                                       \
           "\t.stabs \"\",%d,0,0,L$text_end0000\nL$text_end0000:\n", N_SO)
 
-/* 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
-   not be placed in the read-only data section.  */
-#define SELECT_SECTION(EXP,RELOC) \
-  if (TREE_CODE (EXP) == VAR_DECL \
-      && TREE_READONLY (EXP) \
-      && !TREE_THIS_VOLATILE (EXP) \
-      && DECL_INITIAL (EXP) \
-      && (DECL_INITIAL (EXP) == error_mark_node \
-          || TREE_CONSTANT (DECL_INITIAL (EXP))) \
-      && !RELOC) \
-    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 \
-    data_section ();
-   
+/* Select a format to encode pointers in exception handling data.  CODE
+   is 0 for data, 1 for code labels, 2 for function pointers.  GLOBAL is
+   true if the symbol may be affected by dynamic relocations.  Because
+   the HP assembler does auto alignment, it is necessary to use
+   DW_EH_PE_aligned instead of the default DW_EH_PE_absptr.  */
+
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
+  (TARGET_GAS ? DW_EH_PE_absptr : DW_EH_PE_aligned)
+
 /* HPUX has a program 'chatr' to list the dependencies of dynamically
    linked executables and shared libraries.  */
 #define LDD_SUFFIX "chatr"
@@ -136,66 +126,12 @@ do {                                                              \
 #endif
 
 \f
-/* 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).
-
-   The macro definition, if any, is executed immediately after the
-   rtl for DECL or other node is created.
-   The value of the rtl will be a `mem' whose address is a
-   `symbol_ref'.
-
-   The usual thing for this macro to do is to a flag in the
-   `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified
-   name string in the `symbol_ref' (if one bit is not enough
-   information).
-
-   On the HP-PA we use this to indicate if a symbol is in text or
-   data space.  Also, function labels need special treatment. */
-
-#define TEXT_SPACE_P(DECL)\
-  (TREE_CODE (DECL) == FUNCTION_DECL                                   \
-   || (TREE_CODE (DECL) == VAR_DECL                                    \
-       && TREE_READONLY (DECL) && ! TREE_SIDE_EFFECTS (DECL)           \
-       && (! DECL_INITIAL (DECL) || ! reloc_needed (DECL_INITIAL (DECL))) \
-       && !flag_pic)                                                   \
-   || (TREE_CODE_CLASS (TREE_CODE (DECL)) == 'c'                       \
-       && !(TREE_CODE (DECL) == STRING_CST && flag_writable_strings)))
-
-#define FUNCTION_NAME_P(NAME) \
-(*(NAME) == '@' || (*(NAME) == '*' && *((NAME) + 1) == '@'))
-
-#define ENCODE_SECTION_INFO(DECL)\
-do                                                     \
-  { if (TEXT_SPACE_P (DECL))                           \
-      {        rtx _rtl;                                       \
-       if (TREE_CODE (DECL) == FUNCTION_DECL           \
-           || TREE_CODE (DECL) == VAR_DECL)            \
-         _rtl = DECL_RTL (DECL);                       \
-       else                                            \
-         _rtl = TREE_CST_RTL (DECL);                   \
-       SYMBOL_REF_FLAG (XEXP (_rtl, 0)) = 1;           \
-       if (TREE_CODE (DECL) == FUNCTION_DECL)          \
-         hppa_encode_label (XEXP (DECL_RTL (DECL), 0), 0);\
-      }                                                        \
-  }                                                    \
-while (0)
-
-/* Store the user-specified part of SYMBOL_NAME in VAR.
-   This is sort of inverse to ENCODE_SECTION_INFO.  */
-
-#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME)   \
-  (VAR) = ((SYMBOL_NAME)  + ((SYMBOL_NAME)[0] == '*' ? \
-                            1 + (SYMBOL_NAME)[1] == '@'\
-                            : (SYMBOL_NAME)[0] == '@'))
-
 /* 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) \
   {                                                                    \
-    char *name;                                                                \
-    STRIP_NAME_ENCODING (name, 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)                                               \
@@ -209,7 +145,7 @@ while (0)
         tree parm;                                                     \
         int i;                                                         \
         if (TREE_PUBLIC (DECL) || TARGET_GAS)                          \
-          { extern int current_function_varargs;                       \
+          {                                                            \
             if (TREE_PUBLIC (DECL))                                    \
               {                                                        \
                 fputs ("\t.EXPORT ", FILE);                            \
@@ -220,6 +156,7 @@ while (0)
               {                                                        \
                 fputs ("\t.PARAM ", FILE);                             \
                 assemble_name (FILE, NAME);                            \
+                fputs (",PRIV_LEV=3", FILE);                           \
               }                                                        \
             for (parm = DECL_ARGUMENTS (DECL), i = 0; parm && i < 4;   \
                  parm = TREE_CHAIN (parm))                             \
@@ -261,10 +198,9 @@ while (0)
                   }                                                    \
               }                                                        \
             /* anonymous args */                                       \
-            if ((TYPE_ARG_TYPES (tree_type) != 0                       \
-                 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (tree_type)))\
-                     != void_type_node))                               \
-                || current_function_varargs)                           \
+            if (TYPE_ARG_TYPES (tree_type) != 0                        \
+                && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (tree_type)))\
+                    != void_type_node))                                \
               {                                                        \
                 for (; i < 4; i++)                                     \
                   fprintf (FILE, ",ARGW%d=GR", i);                     \
@@ -281,7 +217,14 @@ while (0)
 /* Output at beginning of assembler file.  */
 
 #define ASM_FILE_START(FILE) \
-do { fputs ("\t.SPACE $PRIVATE$\n\
+do {  \
+     if (TARGET_PA_20) \
+       fputs("\t.LEVEL 2.0\n", FILE); \
+     else if (TARGET_PA_11) \
+       fputs("\t.LEVEL 1.1\n", FILE); \
+     else \
+       fputs("\t.LEVEL 1.0\n", FILE); \
+     fputs ("\t.SPACE $PRIVATE$\n\
 \t.SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31\n\
 \t.SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82\n\
 \t.SPACE $TEXT$\n\
@@ -305,54 +248,19 @@ do { fputs ("\t.SPACE $PRIVATE$\n\
 /* Supposedly the assembler rejects the command if there is no tab!  */
 #define READONLY_DATA_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $LIT$\n"
 
-#define READONLY_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 the .bss section for ASM_OUTPUT_LOCAL to use. */
-
-#ifndef CTORS_SECTION_FUNCTION
 #define EXTRA_SECTIONS in_readonly_data
-#define CTORS_SECTION_FUNCTION
-#define DTORS_SECTION_FUNCTION
-#else
-#define EXTRA_SECTIONS in_readonly_data, in_ctors, in_dtors
-#endif
-
-/* Switch into a generic section.
-   This is currently only used to support section attributes.
 
-   We make the section read-only and executable for a function decl,
-   read-only for a const data decl, and writable for a non-const data decl.  */
-#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
-  if (DECL && TREE_CODE (DECL) == FUNCTION_DECL)               \
-    {                                                          \
-      fputs ("\t.SPACE $TEXT$\n", FILE);                       \
-      fprintf (FILE,                                           \
-              "\t.SUBSPA %s%s%s,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY,SORT=24\n",\
-              TARGET_GAS ? "" : "$", NAME, TARGET_GAS ? "" : "$"); \
-    }                                                          \
-  else if (DECL && DECL_READONLY_SECTION (DECL, RELOC))                \
-    {                                                          \
-      fputs ("\t.SPACE $TEXT$\n", FILE);                       \
-      fprintf (FILE,                                           \
-              "\t.SUBSPA %s%s%s,QUAD=0,ALIGN=8,ACCESS=44,SORT=16\n", \
-              TARGET_GAS ? "" : "$", NAME, TARGET_GAS ? "" : "$"); \
-    }                                                          \
-  else                                                         \
-    {                                                          \
-      fputs ("\t.SPACE $PRIVATE$\n", FILE);                    \
-      fprintf (FILE,                                           \
-              "\t.SUBSPA %s%s%s,QUAD=1,ALIGN=8,ACCESS=31,SORT=16\n", \
-              TARGET_GAS ? "" : "$", NAME, TARGET_GAS ? "" : "$"); \
-    }
+#define EXTRA_SECTION_FUNCTIONS                                                \
+extern void readonly_data PARAMS ((void));                             \
+void                                                                   \
+readonly_data ()                                                       \
+{                                                                      \
+  if (in_section != in_readonly_data)                                  \
+    {                                                                  \
+      in_section = in_readonly_data;                                   \
+      fprintf (asm_out_file, "%s\n", READONLY_DATA_ASM_OP);            \
+    }                                                                  \
+}
 
 /* FIXME: HPUX ld generates incorrect GOT entries for "T" fixups
    which reference data within the $TEXT$ space (for example constant
@@ -367,34 +275,40 @@ do { fputs ("\t.SPACE $PRIVATE$\n\
    data into the $PRIVATE$ subspace (this reduces sharing, but it
    works correctly).  */
 
-#define EXTRA_SECTION_FUNCTIONS                                                \
-void                                                                   \
-readonly_data ()                                                       \
-{                                                                      \
-  if (in_section != in_readonly_data)                                  \
-    {                                                                  \
-      if (flag_pic)                                                    \
-       fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);            \
-      else                                                             \
-       fprintf (asm_out_file, "%s\n", READONLY_DATA_ASM_OP);           \
-      in_section = in_readonly_data;                                   \
-    }                                                                  \
-}                                                                      \
-CTORS_SECTION_FUNCTION                                                 \
-DTORS_SECTION_FUNCTION
+#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"
+
+/* We must not have a reference to an external symbol defined in a
+   shared library in a readonly section, else the SOM linker will
+   complain.
+
+   So, we force exception information into the data section.  */
+#define TARGET_ASM_EXCEPTION_SECTION data_section
 
 /* This is how to output a command to make the user-level label named NAME
    defined for reference from other files.
 
    We call assemble_name, which in turn sets TREE_SYMBOL_REFERENCED.  This
    macro will restore the original value of TREE_SYMBOL_REFERENCED to avoid
-   placing useless function definitions in the output file.  */
+   placing useless function definitions in the output file.
+
+   Also note that the SOM based tools need the symbol imported as a CODE
+   symbol, while the ELF based tools require the symbol to be imported as
+   an ENTRY symbol.  What a crock.  */
 
 #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)  \
   do { int save_referenced;                                    \
        save_referenced = TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL)); \
-       fputs ("\t.IMPORT ", FILE);                                     \
-        assemble_name (FILE, NAME);                            \
+       fputs ("\t.IMPORT ", FILE);                             \
+       assemble_name (FILE, NAME);                             \
        if (FUNCTION_NAME_P (NAME))                                     \
         fputs (",CODE\n", FILE);                               \
        else                                                    \
@@ -406,46 +320,29 @@ DTORS_SECTION_FUNCTION
    "imported", even library calls. They look a bit different, so
    here's this macro.
 
-   Also note not all libcall names are passed to ENCODE_SECTION_INFO
+   Also note not all libcall names are passed to pa_encode_section_info
    (__main for example).  To make sure all libcall names have section
-   info recorded in them, we do it here.  */
+   info recorded in them, we do it here.  We must also ensure that
+   we don't import a libcall that has been previously exported since
+   the HP assembler may change an ENTRY symbol to a CODE symbol.  */
 
 #define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, RTL) \
-  do { fputs ("\t.IMPORT ", FILE);                                     \
+  do { const char *name;                                               \
+       tree id;                                                                \
+                                                                       \
        if (!function_label_operand (RTL, VOIDmode))                    \
-        hppa_encode_label (RTL, 1);                                    \
-       assemble_name (FILE, XSTR ((RTL), 0));                          \
-       fputs (",CODE\n", FILE);                                                \
+        hppa_encode_label (RTL);                                       \
+                                                                       \
+       name = (*targetm.strip_name_encoding) (XSTR ((RTL), 0));                \
+       id = maybe_get_identifier (name);                               \
+       if (! id || ! TREE_SYMBOL_REFERENCED (id))                      \
+        {                                                              \
+          fputs ("\t.IMPORT ", FILE);                                  \
+          assemble_name (FILE, XSTR ((RTL), 0));                       \
+          fputs (",CODE\n", FILE);                                     \
+        }                                                              \
      } while (0)
 
-#define ASM_GLOBALIZE_LABEL(FILE, NAME)                                        \
-  do {                                                                 \
-    /* We only handle DATA objects here, functions are globalized in   \
-       ASM_DECLARE_FUNCTION_NAME.  */                                  \
-    if (! FUNCTION_NAME_P (NAME))                                      \
-      {                                                                        \
-       fputs ("\t.EXPORT ", FILE);                                     \
-       assemble_name (FILE, NAME);                                     \
-       fputs (",DATA\n", FILE);                                        \
-      }                                                                        \
-  } while (0)
-
-#define ASM_FILE_END(FILE) output_deferred_plabels (FILE)
-
-/* This is how to output an assembler line defining an `int' constant. 
-
-   This is made more complicated by the fact that functions must be
-   prefixed by a P% as well as code label references for the exception
-   table -- otherwise the linker chokes.  */
-
-#define ASM_OUTPUT_INT(FILE,VALUE)  \
-{ fputs ("\t.word ", FILE);                    \
-  if (function_label_operand (VALUE, VOIDmode))        \
-    fputs ("P%", FILE);                                \
-  output_addr_const (FILE, (VALUE));           \
-  fputs ("\n", FILE);}
-
-
 /* We want __gcc_plt_call to appear in every program built by
    gcc, so we make a reference to it out of __main.
    We use the asm statement to fool the optimizer into not
@@ -461,3 +358,65 @@ do {                                               \
   for (p = __DTOR_LIST__ + 1; *p; )            \
     (*p++) ();                                 \
 } while (0)
+
+/* The .align directive in the HP assembler allows up to a 32 alignment.  */
+#define MAX_OFILE_ALIGNMENT 32768
+
+/* The SOM linker hardcodes paths into binaries.  As a result, dotdots
+   must be removed from library prefixes to prevent binaries from depending
+   on the location of the GCC tool directory.  The downside is GCC
+   cannot be moved after installation using a symlink.  */
+#define ALWAYS_STRIP_DOTDOT 1
+
+/* Aggregates with a single float or double field should be passed and
+   returned in the general registers.  */
+#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) (MODE==SFmode || MODE==DFmode)
+
+/* If GAS supports weak, we can support weak when we have working linker
+   support for secondary definitions and are generating code for GAS.  */
+#ifdef HAVE_GAS_WEAK
+#define SUPPORTS_WEAK (TARGET_SOM_SDEF && TARGET_GAS)
+#else
+#define SUPPORTS_WEAK 0
+#endif
+
+/* We can support one only if we support weak.  */
+#define SUPPORTS_ONE_ONLY SUPPORTS_WEAK
+
+/* Use weak (secondary definitions) to make one only declarations.  */
+#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
+
+/* This is how we tell the assembler that a symbol is weak.  The SOM
+   weak implementation uses the secondary definition (sdef) flag.
+
+   The behavior of sdef symbols is similar to ELF weak symbols in that
+   multiple definitions can occur without incurring a link error.
+   However, they differ in the following ways:
+     1) Undefined sdef symbols are not allowed.
+     2) The linker searches for undefined sdef symbols and will load an
+       archive library member to resolve an undefined sdef symbol.
+     3) The exported symbol from a shared library is a primary symbol
+        rather than a sdef symbol.  Thus, more care is needed in the
+       ordering of libraries.
+
+   It appears that the linker discards extra copies of "weak" functions
+   when linking shared libraries, independent of whether or not they
+   are in their own section.  In linking final executables, -Wl,-O can
+   be used to remove dead procedures.  Thus, support for named sections
+   is not needed and in previous testing caused problems with various
+   HP tools.  */
+#define ASM_WEAKEN_LABEL(FILE,NAME) \
+  do { fputs ("\t.weak\t", FILE);                              \
+       assemble_name (FILE, NAME);                             \
+       fputc ('\n', FILE);                                     \
+       if (! FUNCTION_NAME_P (NAME))                           \
+        {                                                      \
+          fputs ("\t.EXPORT ", FILE);                          \
+          assemble_name (FILE, NAME);                          \
+          fputs (",DATA\n", FILE);                             \
+        }                                                      \
+  } while (0)
+
+/* We can't handle weak aliases, and therefore can't support pragma weak.
+   Suppress the use of pragma weak in gthr-dce.h and gthr-posix.h.  */
+#define GTHREAD_USE_WEAK 0