i386.md: Simplify certain comparisons of const_int.
[gcc.git] / gcc / varasm.c
index 73abd5edc8daeefa9b11bd0ef6e3abd717e0912f..e44d288dbc882b15f228fe33e32b2228026fc26d 100644 (file)
@@ -1,6 +1,6 @@
 /* Output variables, constants and external declarations, for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -114,11 +114,6 @@ struct varasm_status GTY(())
 
 static GTY(()) int const_labelno;
 
-/* Number for making the label on the next
-   static variable internal to a function.  */
-
-static GTY(()) int var_labelno;
-
 /* Carry information from ASM_DECLARE_OBJECT_NAME
    to ASM_FINISH_DECLARE_OBJECT.  */
 
@@ -140,51 +135,51 @@ tree last_assemble_variable_decl;
 
 static HOST_WIDE_INT const_alias_set;
 
-static const char *strip_reg_name      PARAMS ((const char *));
-static int contains_pointers_p         PARAMS ((tree));
-static void decode_addr_const          PARAMS ((tree, struct addr_const *));
-static hashval_t const_desc_hash       PARAMS ((const void *));
-static int const_desc_eq               PARAMS ((const void *, const void *));
-static hashval_t const_hash_1          PARAMS ((const tree));
-static int compare_constant            PARAMS ((const tree, const tree));
-static tree copy_constant              PARAMS ((tree));
-static void output_constant_def_contents  PARAMS ((rtx));
-static void decode_rtx_const           PARAMS ((enum machine_mode, rtx,
-                                              struct rtx_const *));
-static unsigned int const_hash_rtx     PARAMS ((enum machine_mode, rtx));
-static int compare_constant_rtx
-  PARAMS ((enum machine_mode, rtx, struct constant_descriptor_rtx *));
+static const char *strip_reg_name (const char *);
+static int contains_pointers_p (tree);
+#ifdef ASM_OUTPUT_EXTERNAL
+static bool incorporeal_function_p (tree);
+#endif
+static void decode_addr_const (tree, struct addr_const *);
+static hashval_t const_desc_hash (const void *);
+static int const_desc_eq (const void *, const void *);
+static hashval_t const_hash_1 (const tree);
+static int compare_constant (const tree, const tree);
+static tree copy_constant (tree);
+static void output_constant_def_contents (rtx);
+static void decode_rtx_const (enum machine_mode, rtx, struct rtx_const *);
+static unsigned int const_hash_rtx (enum machine_mode, rtx);
+static int compare_constant_rtx (enum machine_mode, rtx,
+                                struct constant_descriptor_rtx *);
 static struct constant_descriptor_rtx * record_constant_rtx
-  PARAMS ((enum machine_mode, rtx));
-static struct pool_constant *find_pool_constant PARAMS ((struct function *, rtx));
-static void mark_constant_pool         PARAMS ((void));
-static void mark_constants             PARAMS ((rtx));
-static int mark_constant               PARAMS ((rtx *current_rtx, void *data));
-static int output_addressed_constants  PARAMS ((tree));
-static unsigned HOST_WIDE_INT array_size_for_constructor PARAMS ((tree));
-static unsigned min_align              PARAMS ((unsigned, unsigned));
-static void output_constructor         PARAMS ((tree, unsigned HOST_WIDE_INT,
-                                                unsigned int));
-static void globalize_decl             PARAMS ((tree));
-static void maybe_assemble_visibility  PARAMS ((tree));
-static int in_named_entry_eq           PARAMS ((const void *, const void *));
-static hashval_t in_named_entry_hash   PARAMS ((const void *));
+  (enum machine_mode, rtx);
+static struct pool_constant *find_pool_constant (struct function *, rtx);
+static void mark_constant_pool (void);
+static void mark_constants (rtx);
+static int mark_constant (rtx *current_rtx, void *data);
+static void output_addressed_constants (tree);
+static unsigned HOST_WIDE_INT array_size_for_constructor (tree);
+static unsigned min_align (unsigned, unsigned);
+static void output_constructor (tree, unsigned HOST_WIDE_INT, unsigned int);
+static void globalize_decl (tree);
+static void maybe_assemble_visibility (tree);
+static int in_named_entry_eq (const void *, const void *);
+static hashval_t in_named_entry_hash (const void *);
 #ifdef ASM_OUTPUT_BSS
-static void asm_output_bss             PARAMS ((FILE *, tree, const char *,
-                                               unsigned HOST_WIDE_INT,
-                                               unsigned HOST_WIDE_INT));
+static void asm_output_bss (FILE *, tree, const char *,
+                           unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT);
 #endif
 #ifdef BSS_SECTION_ASM_OP
 #ifdef ASM_OUTPUT_ALIGNED_BSS
-static void asm_output_aligned_bss
-  PARAMS ((FILE *, tree, const char *,
-          unsigned HOST_WIDE_INT, int)) ATTRIBUTE_UNUSED;
+static void asm_output_aligned_bss (FILE *, tree, const char *,
+                                   unsigned HOST_WIDE_INT, int)
+     ATTRIBUTE_UNUSED;
 #endif
 #endif /* BSS_SECTION_ASM_OP */
-static bool asm_emit_uninitialised     PARAMS ((tree, const char*,
-                                                unsigned HOST_WIDE_INT,
-                                                unsigned HOST_WIDE_INT));
-static void mark_weak                   PARAMS ((tree));
+static bool asm_emit_uninitialised (tree, const char*,
+                                   unsigned HOST_WIDE_INT,
+                                   unsigned HOST_WIDE_INT);
+static void mark_weak (tree);
 \f
 enum in_section { no_section, in_text, in_data, in_named
 #ifdef BSS_SECTION_ASM_OP
@@ -234,23 +229,19 @@ EXTRA_SECTION_FUNCTIONS
 /* Tell assembler to switch to text section.  */
 
 void
-text_section ()
+text_section (void)
 {
   if (in_section != in_text)
     {
       in_section = in_text;
-#ifdef TEXT_SECTION
-      TEXT_SECTION ();
-#else
       fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
-#endif
     }
 }
 
 /* Tell assembler to switch to data section.  */
 
 void
-data_section ()
+data_section (void)
 {
   if (in_section != in_data)
     {
@@ -272,7 +263,7 @@ data_section ()
    the text section.  */
 
 void
-readonly_data_section ()
+readonly_data_section (void)
 {
 #ifdef READONLY_DATA_SECTION
   READONLY_DATA_SECTION ();  /* Note this can call data_section.  */
@@ -293,7 +284,7 @@ readonly_data_section ()
 /* Determine if we're in the text section.  */
 
 int
-in_text_section ()
+in_text_section (void)
 {
   return in_section == in_text;
 }
@@ -301,7 +292,7 @@ in_text_section ()
 /* Determine if we're in the data section.  */
 
 int
-in_data_section ()
+in_data_section (void)
 {
   return in_section == in_data;
 }
@@ -309,9 +300,7 @@ in_data_section ()
 /* Helper routines for maintaining in_named_htab.  */
 
 static int
-in_named_entry_eq (p1, p2)
-     const void *p1;
-     const void *p2;
+in_named_entry_eq (const void *p1, const void *p2)
 {
   const struct in_named_entry *old = p1;
   const char *new = p2;
@@ -320,8 +309,7 @@ in_named_entry_eq (p1, p2)
 }
 
 static hashval_t
-in_named_entry_hash (p)
-     const void *p;
+in_named_entry_hash (const void *p)
 {
   const struct in_named_entry *old = p;
   return htab_hash_string (old->name);
@@ -333,8 +321,7 @@ in_named_entry_hash (p)
    has not been seen.  */
 
 unsigned int
-get_named_section_flags (section)
-     const char *section;
+get_named_section_flags (const char *section)
 {
   struct in_named_entry **slot;
 
@@ -350,8 +337,7 @@ get_named_section_flags (section)
    section will return false.  */
 
 bool
-named_section_first_declaration (name)
-     const char *name;
+named_section_first_declaration (const char *name)
 {
   struct in_named_entry **slot;
 
@@ -374,9 +360,7 @@ named_section_first_declaration (name)
    different set of flags, return false.  */
 
 bool
-set_named_section_flags (section, flags)
-     const char *section;
-     unsigned int flags;
+set_named_section_flags (const char *section, unsigned int flags)
 {
   struct in_named_entry **slot, *entry;
 
@@ -387,7 +371,7 @@ set_named_section_flags (section, flags)
 
   if (!entry)
     {
-      entry = (struct in_named_entry *) ggc_alloc (sizeof (*entry));
+      entry = ggc_alloc (sizeof (*entry));
       *slot = entry;
       entry->name = ggc_strdup (section);
       entry->flags = flags;
@@ -402,9 +386,7 @@ set_named_section_flags (section, flags)
 /* Tell assembler to change to section NAME with attributes FLAGS.  */
 
 void
-named_section_flags (name, flags)
-     const char *name;
-     unsigned int flags;
+named_section_flags (const char *name, unsigned int flags)
 {
   if (in_section != in_named || strcmp (name, in_named_name) != 0)
     {
@@ -429,10 +411,7 @@ named_section_flags (name, flags)
    If RELOC is 1, the initializer for DECL contains relocs.  */
 
 void
-named_section (decl, name, reloc)
-     tree decl;
-     const char *name;
-     int reloc;
+named_section (tree decl, const char *name, int reloc)
 {
   unsigned int flags;
 
@@ -452,7 +431,7 @@ named_section (decl, name, reloc)
     {
       flags = get_named_section_flags (name);
       if ((flags & SECTION_OVERRIDE) == 0)
-       error_with_decl (decl, "%s causes a section type conflict");
+       error ("%J%D causes a section type conflict", decl, decl);
     }
 
   named_section_flags (name, flags);
@@ -461,10 +440,8 @@ named_section (decl, name, reloc)
 /* If required, set DECL_SECTION_NAME to a unique name.  */
 
 void
-resolve_unique_section (decl, reloc, flag_function_or_data_sections)
-     tree decl;
-     int reloc ATTRIBUTE_UNUSED;
-     int flag_function_or_data_sections;
+resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED,
+                       int flag_function_or_data_sections)
 {
   if (DECL_SECTION_NAME (decl) == NULL_TREE
       && targetm.have_named_sections
@@ -478,17 +455,11 @@ resolve_unique_section (decl, reloc, flag_function_or_data_sections)
 /* Tell the assembler to switch to the bss section.  */
 
 void
-bss_section ()
+bss_section (void)
 {
   if (in_section != in_bss)
     {
-#ifdef SHARED_BSS_SECTION_ASM_OP
-      if (flag_shared_data)
-       fprintf (asm_out_file, "%s\n", SHARED_BSS_SECTION_ASM_OP);
-      else
-#endif
-       fprintf (asm_out_file, "%s\n", BSS_SECTION_ASM_OP);
-
+      fprintf (asm_out_file, "%s\n", BSS_SECTION_ASM_OP);
       in_section = in_bss;
     }
 }
@@ -501,11 +472,10 @@ bss_section ()
    support is localized here.  */
 
 static void
-asm_output_bss (file, decl, name, size, rounded)
-     FILE *file;
-     tree decl ATTRIBUTE_UNUSED;
-     const char *name;
-     unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED, rounded;
+asm_output_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
+               const char *name,
+               unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED,
+               unsigned HOST_WIDE_INT rounded)
 {
   (*targetm.asm_out.globalize_label) (file, name);
   bss_section ();
@@ -529,12 +499,9 @@ asm_output_bss (file, decl, name, size, rounded)
    support is localized here.  */
 
 static void
-asm_output_aligned_bss (file, decl, name, size, align)
-     FILE *file;
-     tree decl ATTRIBUTE_UNUSED;
-     const char *name;
-     unsigned HOST_WIDE_INT size;
-     int align;
+asm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
+                       const char *name, unsigned HOST_WIDE_INT size,
+                       int align)
 {
   bss_section ();
   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
@@ -559,8 +526,7 @@ asm_output_aligned_bss (file, decl, name, size, align)
    safer to handle it.  */
 
 void
-function_section (decl)
-     tree decl;
+function_section (tree decl)
 {
   if (decl != NULL_TREE
       && DECL_SECTION_NAME (decl) != NULL_TREE)
@@ -573,9 +539,7 @@ function_section (decl)
    argument to SELECT_SECTION.  */
 
 void
-variable_section (decl, reloc)
-     tree decl;
-     int reloc;
+variable_section (tree decl, int reloc)
 {
   if (IN_NAMED_SECTION (decl))
     named_section (decl, NULL, reloc);
@@ -586,13 +550,11 @@ variable_section (decl, reloc)
 /* Tell assembler to switch to the section for string merging.  */
 
 void
-mergeable_string_section (decl, align, flags)
-     tree decl ATTRIBUTE_UNUSED;
-     unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
-     unsigned int flags ATTRIBUTE_UNUSED;
+mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
+                         unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED,
+                         unsigned int flags ATTRIBUTE_UNUSED)
 {
-#ifdef HAVE_GAS_SHF_MERGE
-  if (flag_merge_constants
+  if (HAVE_GAS_SHF_MERGE && flag_merge_constants
       && TREE_CODE (decl) == STRING_CST
       && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
       && align <= 256
@@ -654,22 +616,20 @@ mergeable_string_section (decl, align, flags)
            }
        }
     }
-#endif
+
   readonly_data_section ();
 }
 
 /* Tell assembler to switch to the section for constant merging.  */
 
 void
-mergeable_constant_section (mode, align, flags)
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-     unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
-     unsigned int flags ATTRIBUTE_UNUSED;
+mergeable_constant_section (enum machine_mode mode ATTRIBUTE_UNUSED,
+                           unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED,
+                           unsigned int flags ATTRIBUTE_UNUSED)
 {
-#ifdef HAVE_GAS_SHF_MERGE
   unsigned int modesize = GET_MODE_BITSIZE (mode);
 
-  if (flag_merge_constants
+  if (HAVE_GAS_SHF_MERGE && flag_merge_constants
       && mode != VOIDmode
       && mode != BLKmode
       && modesize <= align
@@ -684,15 +644,14 @@ mergeable_constant_section (mode, align, flags)
       named_section_flags (name, flags);
       return;
     }
-#endif
+
   readonly_data_section ();
 }
 \f
 /* Given NAME, a putative register name, discard any customary prefixes.  */
 
 static const char *
-strip_reg_name (name)
-     const char *name;
+strip_reg_name (const char *name)
 {
 #ifdef REGISTER_PREFIX
   if (!strncmp (name, REGISTER_PREFIX, strlen (REGISTER_PREFIX)))
@@ -712,8 +671,7 @@ strip_reg_name (name)
    Prefixes such as % are optional.  */
 
 int
-decode_reg_name (asmspec)
-     const char *asmspec;
+decode_reg_name (const char *asmspec)
 {
   if (asmspec != 0)
     {
@@ -776,13 +734,9 @@ decode_reg_name (asmspec)
    This is never called for PARM_DECL nodes.  */
 
 void
-make_decl_rtl (decl, asmspec)
-     tree decl;
-     const char *asmspec;
+make_decl_rtl (tree decl, const char *asmspec)
 {
-  int top_level = (DECL_CONTEXT (decl) == NULL_TREE);
   const char *name = 0;
-  const char *new_name = 0;
   int reg_number;
   rtx x;
 
@@ -822,8 +776,6 @@ make_decl_rtl (decl, asmspec)
       return;
     }
 
-  new_name = name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-
   reg_number = decode_reg_name (asmspec);
   if (reg_number == -2)
     {
@@ -832,22 +784,24 @@ make_decl_rtl (decl, asmspec)
       char *starred = alloca (strlen (asmspec) + 2);
       starred[0] = '*';
       strcpy (starred + 1, asmspec);
-      new_name = starred;
+      change_decl_assembler_name (decl, get_identifier (starred));
     }
 
+  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
   if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
     {
       /* First detect errors in declaring global registers.  */
       if (reg_number == -1)
-       error_with_decl (decl, "register name not specified for `%s'");
+       error ("%Jregister name not specified for '%D'", decl, decl);
       else if (reg_number < 0)
-       error_with_decl (decl, "invalid register name for `%s'");
+       error ("%Jinvalid register name for '%D'", decl, decl);
       else if (TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
-       error_with_decl (decl,
-                        "data type of `%s' isn't suitable for a register");
+       error ("%Jdata type of '%D' isn't suitable for a register",
+              decl, decl);
       else if (! HARD_REGNO_MODE_OK (reg_number, TYPE_MODE (TREE_TYPE (decl))))
-       error_with_decl (decl,
-                        "register specified for `%s' isn't suitable for data type");
+       error ("%Jregister specified for '%D' isn't suitable for data type",
+               decl, decl);
       /* Now handle properly declared static register variables.  */
       else
        {
@@ -891,8 +845,7 @@ make_decl_rtl (decl, asmspec)
      Also handle vars declared register invalidly.  */
 
   if (reg_number >= 0 || reg_number == -3)
-    error_with_decl (decl,
-                    "register name given for non-register variable `%s'");
+    error ("%Jregister name given for non-register variable '%D'", decl, decl);
 
   /* Specifying a section attribute on a variable forces it into a
      non-.bss section, and thus it cannot be common.  */
@@ -906,32 +859,10 @@ make_decl_rtl (decl, asmspec)
   if (TREE_CODE (decl) == VAR_DECL && DECL_WEAK (decl))
     DECL_COMMON (decl) = 0;
 
-  /* Can't use just the variable's own name for a variable
-     whose scope is less than the whole file, unless it's a member
-     of a local class (which will already be unambiguous).
-     Concatenate a distinguishing number.  */
-  if (!top_level && !TREE_PUBLIC (decl)
-      && ! (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
-      && asmspec == 0
-      && name == IDENTIFIER_POINTER (DECL_NAME (decl)))
-    {
-      char *label;
-
-      ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
-      var_labelno++;
-      new_name = label;
-    }
-
-  if (name != new_name)
-    {
-      SET_DECL_ASSEMBLER_NAME (decl, get_identifier (new_name));
-      name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-    }
-
   x = gen_rtx_SYMBOL_REF (Pmode, name);
   SYMBOL_REF_WEAK (x) = DECL_WEAK (decl);
   SYMBOL_REF_DECL (x) = decl;
-  
+
   x = gen_rtx_MEM (DECL_MODE (decl), x);
   if (TREE_CODE (decl) != FUNCTION_DECL)
     set_mem_attributes (x, decl, 1);
@@ -948,8 +879,7 @@ make_decl_rtl (decl, asmspec)
    Use this only for static variables.  */
 
 void
-make_var_volatile (var)
-     tree var;
+make_var_volatile (tree var)
 {
   if (GET_CODE (DECL_RTL (var)) != MEM)
     abort ();
@@ -961,8 +891,7 @@ make_var_volatile (var)
    for an `asm' keyword used between functions.  */
 
 void
-assemble_asm (string)
-     tree string;
+assemble_asm (tree string)
 {
   app_enable ();
 
@@ -977,9 +906,7 @@ assemble_asm (string)
    between 0 and MAX_INIT_PRIORITY.  */
 
 void
-default_stabs_asm_out_destructor (symbol, priority)
-     rtx symbol;
-     int priority ATTRIBUTE_UNUSED;
+default_stabs_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
   /* Tell GNU LD that this is part of the static destructor set.
      This will work for any system that uses stabs, most usefully
@@ -990,9 +917,7 @@ default_stabs_asm_out_destructor (symbol, priority)
 }
 
 void
-default_named_section_asm_out_destructor (symbol, priority)
-     rtx symbol;
-     int priority;
+default_named_section_asm_out_destructor (rtx symbol, int priority)
 {
   const char *section = ".dtors";
   char buf[16];
@@ -1015,7 +940,7 @@ default_named_section_asm_out_destructor (symbol, priority)
 
 #ifdef DTORS_SECTION_ASM_OP
 void
-dtors_section ()
+dtors_section (void)
 {
   if (in_section != in_dtors)
     {
@@ -1026,9 +951,8 @@ dtors_section ()
 }
 
 void
-default_dtor_section_asm_out_destructor (symbol, priority)
-     rtx symbol;
-     int priority ATTRIBUTE_UNUSED;
+default_dtor_section_asm_out_destructor (rtx symbol,
+                                        int priority ATTRIBUTE_UNUSED)
 {
   dtors_section ();
   assemble_align (POINTER_SIZE);
@@ -1039,9 +963,7 @@ default_dtor_section_asm_out_destructor (symbol, priority)
 /* Likewise for global constructors.  */
 
 void
-default_stabs_asm_out_constructor (symbol, priority)
-     rtx symbol;
-     int priority ATTRIBUTE_UNUSED;
+default_stabs_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
   /* Tell GNU LD that this is part of the static destructor set.
      This will work for any system that uses stabs, most usefully
@@ -1052,9 +974,7 @@ default_stabs_asm_out_constructor (symbol, priority)
 }
 
 void
-default_named_section_asm_out_constructor (symbol, priority)
-     rtx symbol;
-     int priority;
+default_named_section_asm_out_constructor (rtx symbol, int priority)
 {
   const char *section = ".ctors";
   char buf[16];
@@ -1077,7 +997,7 @@ default_named_section_asm_out_constructor (symbol, priority)
 
 #ifdef CTORS_SECTION_ASM_OP
 void
-ctors_section ()
+ctors_section (void)
 {
   if (in_section != in_ctors)
     {
@@ -1088,9 +1008,8 @@ ctors_section ()
 }
 
 void
-default_ctor_section_asm_out_constructor (symbol, priority)
-     rtx symbol;
-     int priority ATTRIBUTE_UNUSED;
+default_ctor_section_asm_out_constructor (rtx symbol,
+                                         int priority ATTRIBUTE_UNUSED)
 {
   ctors_section ();
   assemble_align (POINTER_SIZE);
@@ -1108,15 +1027,51 @@ default_ctor_section_asm_out_constructor (symbol, priority)
 #define CONSTANT_POOL_BEFORE_FUNCTION 1
 #endif
 
+/* DECL is an object (either VAR_DECL or FUNCTION_DECL) which is going
+   to be output to assembler.
+   Set first_global_object_name and weak_global_object_name as appropriate.  */
+
+void
+notice_global_symbol (tree decl)
+{
+  const char **type = &first_global_object_name;
+
+  if (first_global_object_name
+      || !TREE_PUBLIC (decl) || DECL_EXTERNAL (decl)
+      || !DECL_NAME (decl)
+      || (TREE_CODE (decl) != FUNCTION_DECL
+         && (TREE_CODE (decl) != VAR_DECL
+             || (DECL_COMMON (decl)
+                 && (DECL_INITIAL (decl) == 0
+                     || DECL_INITIAL (decl) == error_mark_node))))
+      || GET_CODE (DECL_RTL (decl)) != MEM)
+    return;
+
+  /* We win when global object is found, but it is usefull to know about weak
+     symbol as well so we can produce nicer unique names.  */
+  if (DECL_WEAK (decl) || DECL_ONE_ONLY (decl))
+    type = &weak_global_object_name;
+
+  if (!*type)
+    {
+      const char *p;
+      char *name;
+      rtx decl_rtl = DECL_RTL (decl);
+
+      p = (* targetm.strip_name_encoding) (XSTR (XEXP (decl_rtl, 0), 0));
+      name = xstrdup (p);
+
+      *type = name;
+    }
+}
+
 /* Output assembler code for the constant pool of a function and associated
    with defining the name of the function.  DECL describes the function.
    NAME is the function's name.  For the constant pool, we use the current
    constant pool data.  */
 
 void
-assemble_start_function (decl, fnname)
-     tree decl;
-     const char *fnname;
+assemble_start_function (tree decl, const char *fnname)
 {
   int align;
 
@@ -1163,26 +1118,14 @@ assemble_start_function (decl, fnname)
 
   if (TREE_PUBLIC (decl))
     {
-      if (! first_global_object_name)
-       {
-         const char *p;
-         char *name;
-
-         p = (* targetm.strip_name_encoding) (fnname);
-         name = xstrdup (p);
-
-         if (! DECL_WEAK (decl) && ! DECL_ONE_ONLY (decl))
-           first_global_object_name = name;
-         else
-           weak_global_object_name = name;
-       }
+      notice_global_symbol (decl);
 
       globalize_decl (decl);
 
       maybe_assemble_visibility (decl);
     }
 
-  /* Do any machine/system dependent processing of the function name */
+  /* Do any machine/system dependent processing of the function name */
 #ifdef ASM_DECLARE_FUNCTION_NAME
   ASM_DECLARE_FUNCTION_NAME (asm_out_file, fnname, current_function_decl);
 #else
@@ -1195,9 +1138,7 @@ assemble_start_function (decl, fnname)
    function.  DECL describes the function.  NAME is the function's name.  */
 
 void
-assemble_end_function (decl, fnname)
-     tree decl;
-     const char *fnname;
+assemble_end_function (tree decl, const char *fnname)
 {
 #ifdef ASM_DECLARE_FUNCTION_SIZE
   ASM_DECLARE_FUNCTION_SIZE (asm_out_file, fnname, decl);
@@ -1212,8 +1153,7 @@ assemble_end_function (decl, fnname)
 /* Assemble code to leave SIZE bytes of zeros.  */
 
 void
-assemble_zeros (size)
-     unsigned HOST_WIDE_INT size;
+assemble_zeros (unsigned HOST_WIDE_INT size)
 {
   /* Do no output if -fsyntax-only.  */
   if (flag_syntax_only)
@@ -1237,8 +1177,7 @@ assemble_zeros (size)
 /* Assemble an alignment pseudo op for an ALIGN-bit boundary.  */
 
 void
-assemble_align (align)
-     int align;
+assemble_align (int align)
 {
   if (align > BITS_PER_UNIT)
     {
@@ -1249,9 +1188,7 @@ assemble_align (align)
 /* Assemble a string constant with the specified C string as contents.  */
 
 void
-assemble_string (p, size)
-     const char *p;
-     int size;
+assemble_string (const char *p, int size)
 {
   int pos = 0;
   int maximum = 2000;
@@ -1311,11 +1248,9 @@ assemble_string (p, size)
 #endif
 
 static bool
-asm_emit_uninitialised (decl, name, size, rounded)
-     tree decl;
-     const char *name;
-     unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED;
-     unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED;
+asm_emit_uninitialised (tree decl, const char *name,
+                       unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED,
+                       unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED)
 {
   enum
   {
@@ -1398,11 +1333,8 @@ asm_emit_uninitialised (decl, name, size, rounded)
    initial value (that will be done by the caller).  */
 
 void
-assemble_variable (decl, top_level, at_end, dont_output_data)
-     tree decl;
-     int top_level ATTRIBUTE_UNUSED;
-     int at_end ATTRIBUTE_UNUSED;
-     int dont_output_data;
+assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
+                  int at_end ATTRIBUTE_UNUSED, int dont_output_data)
 {
   const char *name;
   unsigned int align;
@@ -1445,9 +1377,7 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
 
   if (!dont_output_data && DECL_SIZE (decl) == 0)
     {
-      error ("%Hstorage size of `%s' isn't known",
-             &DECL_SOURCE_LOCATION (decl),
-             IDENTIFIER_POINTER (DECL_NAME (decl)));
+      error ("%Jstorage size of `%D' isn't known", decl, decl);
       TREE_ASM_WRITTEN (decl) = 1;
       return;
     }
@@ -1475,25 +1405,13 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
   if (! dont_output_data
       && ! host_integerp (DECL_SIZE_UNIT (decl), 1))
     {
-      error_with_decl (decl, "size of variable `%s' is too large");
+      error ("%Jsize of variable '%D' is too large", decl, decl);
       return;
     }
 
   name = XSTR (XEXP (decl_rtl, 0), 0);
-  if (TREE_PUBLIC (decl) && DECL_NAME (decl)
-      && ! first_global_object_name
-      && ! (DECL_COMMON (decl) && (DECL_INITIAL (decl) == 0
-                                  || DECL_INITIAL (decl) == error_mark_node))
-      && ! DECL_WEAK (decl)
-      && ! DECL_ONE_ONLY (decl))
-    {
-      const char *p;
-      char *xname;
-
-      p = (* targetm.strip_name_encoding) (name);
-      xname = xstrdup (p);
-      first_global_object_name = xname;
-    }
+  if (TREE_PUBLIC (decl) && DECL_NAME (decl))
+    notice_global_symbol (decl);
 
   /* Compute the alignment of this data.  */
 
@@ -1513,9 +1431,9 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
 #endif
   if (align > MAX_OFILE_ALIGNMENT)
     {
-      warning_with_decl (decl,
-       "alignment of `%s' is greater than maximum object file alignment. Using %d",
-                        MAX_OFILE_ALIGNMENT/BITS_PER_UNIT);
+      warning ("%Jalignment of '%D' is greater than maximum object "
+               "file alignment.  Using %d", decl, decl,
+              MAX_OFILE_ALIGNMENT/BITS_PER_UNIT);
       align = MAX_OFILE_ALIGNMENT;
     }
 
@@ -1543,7 +1461,10 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
   if (DECL_INITIAL (decl) == error_mark_node)
     reloc = contains_pointers_p (TREE_TYPE (decl)) ? 3 : 0;
   else if (DECL_INITIAL (decl))
-    reloc = output_addressed_constants (DECL_INITIAL (decl));
+    {
+      reloc = compute_reloc_for_constant (DECL_INITIAL (decl));
+      output_addressed_constants (DECL_INITIAL (decl));
+    }
   resolve_unique_section (decl, reloc, flag_data_sections);
 
   /* Handle uninitialized definitions.  */
@@ -1581,8 +1502,8 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
 
 #if !defined(ASM_OUTPUT_ALIGNED_COMMON) && !defined(ASM_OUTPUT_ALIGNED_DECL_COMMON) && !defined(ASM_OUTPUT_ALIGNED_BSS)
       if ((unsigned HOST_WIDE_INT) DECL_ALIGN (decl) / BITS_PER_UNIT > rounded)
-       warning_with_decl
-         (decl, "requested alignment for %s is greater than implemented alignment of %d",rounded);
+       warning ("%Jrequested alignment for '%D' is greater than "
+                 "implemented alignment of %d", decl, decl, rounded);
 #endif
 
       /* If the target cannot output uninitialized but not common global data
@@ -1638,8 +1559,7 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
 /* Return 1 if type TYPE contains any pointers.  */
 
 static int
-contains_pointers_p (type)
-     tree type;
+contains_pointers_p (tree type)
 {
   switch (TREE_CODE (type))
     {
@@ -1672,13 +1592,35 @@ contains_pointers_p (type)
     }
 }
 
+#ifdef ASM_OUTPUT_EXTERNAL
+/* True if DECL is a function decl for which no out-of-line copy exists.
+   It is assumed that DECL's assembler name has been set.  */
+
+static bool
+incorporeal_function_p (tree decl)
+{
+  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl))
+    {
+      const char *name;
+
+      if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
+         && DECL_FUNCTION_CODE (decl) == BUILT_IN_ALLOCA)
+       return true;
+
+      name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+      if (strncmp (name, "__builtin_", strlen ("__builtin_")) == 0)
+       return true;
+    }
+  return false;
+}
+#endif
+
 /* Output something to declare an external symbol to the assembler.
    (Most assemblers don't need this, so we normally output nothing.)
    Do nothing if DECL is not external.  */
 
 void
-assemble_external (decl)
-     tree decl ATTRIBUTE_UNUSED;
+assemble_external (tree decl ATTRIBUTE_UNUSED)
 {
   /* Because most platforms do not define ASM_OUTPUT_EXTERNAL, the
      main body of this code is only rarely exercised.  To provide some
@@ -1693,7 +1635,8 @@ assemble_external (decl)
       rtx rtl = DECL_RTL (decl);
 
       if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
-         && ! SYMBOL_REF_USED (XEXP (rtl, 0)))
+         && !SYMBOL_REF_USED (XEXP (rtl, 0))
+         && !incorporeal_function_p (decl))
        {
          /* Some systems do require some output.  */
          SYMBOL_REF_USED (XEXP (rtl, 0)) = 1;
@@ -1706,28 +1649,47 @@ assemble_external (decl)
 /* Similar, for calling a library function FUN.  */
 
 void
-assemble_external_libcall (fun)
-     rtx fun ATTRIBUTE_UNUSED;
+assemble_external_libcall (rtx fun)
 {
-#ifdef ASM_OUTPUT_EXTERNAL_LIBCALL
   /* Declare library function name external when first used, if nec.  */
   if (! SYMBOL_REF_USED (fun))
     {
       SYMBOL_REF_USED (fun) = 1;
-      ASM_OUTPUT_EXTERNAL_LIBCALL (asm_out_file, fun);
+      (*targetm.asm_out.external_libcall) (fun);
     }
-#endif
 }
 
 /* Assemble a label named NAME.  */
 
 void
-assemble_label (name)
-     const char *name;
+assemble_label (const char *name)
 {
   ASM_OUTPUT_LABEL (asm_out_file, name);
 }
 
+/* Set the symbol_referenced flag for ID and notify callgraph code.  */
+void
+mark_referenced (tree id)
+{
+  if (!TREE_SYMBOL_REFERENCED (id))
+    {
+      struct cgraph_node *node;
+      struct cgraph_varpool_node *vnode;
+
+      if (!cgraph_global_info_ready)
+       {
+         node = cgraph_node_for_identifier (id);
+         if (node)
+           cgraph_mark_needed_node (node);
+       }
+
+      vnode = cgraph_varpool_node_for_identifier (id);
+      if (vnode)
+       cgraph_varpool_mark_needed_node (vnode);
+    }
+  TREE_SYMBOL_REFERENCED (id) = 1;
+}
+
 /* Output to FILE a reference to the assembler name of a C-level name NAME.
    If NAME starts with a *, the rest of NAME is output verbatim.
    Otherwise NAME is transformed in an implementation-defined way
@@ -1735,9 +1697,7 @@ assemble_label (name)
    Many macros in the tm file are defined to call this function.  */
 
 void
-assemble_name (file, name)
-     FILE *file;
-     const char *name;
+assemble_name (FILE *file, const char *name)
 {
   const char *real_name;
   tree id;
@@ -1746,22 +1706,7 @@ assemble_name (file, name)
 
   id = maybe_get_identifier (real_name);
   if (id)
-    {
-      if (!TREE_SYMBOL_REFERENCED (id)
-         && !cgraph_global_info_ready)
-       {
-         struct cgraph_node *node = cgraph_node_for_identifier (id);
-         struct cgraph_varpool_node *vnode;
-         
-         if (node)
-           cgraph_mark_needed_node (node, 1);
-
-         vnode = cgraph_varpool_node_for_identifier (id);
-         if (vnode)
-           cgraph_varpool_mark_needed_node (vnode);
-       }
-      TREE_SYMBOL_REFERENCED (id) = 1;
-    }
+    mark_referenced (id);
 
   if (name[0] == '*')
     fputs (&name[1], file);
@@ -1773,8 +1718,7 @@ assemble_name (file, name)
    and return an RTX to refer to its address.  */
 
 rtx
-assemble_static_space (size)
-     unsigned HOST_WIDE_INT size;
+assemble_static_space (unsigned HOST_WIDE_INT size)
 {
   char name[12];
   const char *namestring;
@@ -1820,7 +1764,7 @@ assemble_static_space (size)
 
 #ifdef TRAMPOLINE_TEMPLATE
 rtx
-assemble_trampoline_template ()
+assemble_trampoline_template (void)
 {
   char label[256];
   const char *name;
@@ -1859,8 +1803,7 @@ assemble_trampoline_template ()
    that may be assumed after adding the two together.  */
 
 static inline unsigned
-min_align (a, b)
-     unsigned int a, b;
+min_align (unsigned int a, unsigned int b)
 {
   return (a | b) & -(a | b);
 }
@@ -1874,9 +1817,7 @@ min_align (a, b)
    be followed immediately by the object's initial value.  */
 
 const char *
-integer_asm_op (size, aligned_p)
-     int size;
-     int aligned_p;
+integer_asm_op (int size, int aligned_p)
 {
   struct asm_int_op *ops;
 
@@ -1906,9 +1847,7 @@ integer_asm_op (size, aligned_p)
    start of the line, followed immediately by the value of X.  */
 
 void
-assemble_integer_with_op (op, x)
-     const char *op;
-     rtx x;
+assemble_integer_with_op (const char *op, rtx x)
 {
   fputs (op, asm_out_file);
   output_addr_const (asm_out_file, x);
@@ -1918,10 +1857,9 @@ assemble_integer_with_op (op, x)
 /* The default implementation of the asm_out.integer target hook.  */
 
 bool
-default_assemble_integer (x, size, aligned_p)
-     rtx x ATTRIBUTE_UNUSED;
-     unsigned int size ATTRIBUTE_UNUSED;
-     int aligned_p ATTRIBUTE_UNUSED;
+default_assemble_integer (rtx x ATTRIBUTE_UNUSED,
+                         unsigned int size ATTRIBUTE_UNUSED,
+                         int aligned_p ATTRIBUTE_UNUSED)
 {
   const char *op = integer_asm_op (size, aligned_p);
   return op && (assemble_integer_with_op (op, x), true);
@@ -1933,11 +1871,7 @@ default_assemble_integer (x, size, aligned_p)
    the constant.  */
 
 bool
-assemble_integer (x, size, align, force)
-     rtx x;
-     unsigned int size;
-     unsigned int align;
-     int force;
+assemble_integer (rtx x, unsigned int size, unsigned int align, int force)
 {
   int aligned_p;
 
@@ -1982,83 +1916,42 @@ assemble_integer (x, size, align, force)
 }
 \f
 void
-assemble_real (d, mode, align)
-     REAL_VALUE_TYPE d;
-     enum machine_mode mode;
-     unsigned int align;
+assemble_real (REAL_VALUE_TYPE d, enum machine_mode mode, unsigned int align)
 {
   long data[4];
-  long l;
-  unsigned int nalign = min_align (align, 32);
+  int i;
+  int bitsize, nelts, nunits, units_per;
 
-  switch (BITS_PER_UNIT)
-    {
-    case 8:
-      switch (mode)
-       {
-       case SFmode:
-         REAL_VALUE_TO_TARGET_SINGLE (d, l);
-         assemble_integer (GEN_INT (l), 4, align, 1);
-         break;
-       case DFmode:
-         REAL_VALUE_TO_TARGET_DOUBLE (d, data);
-         assemble_integer (GEN_INT (data[0]), 4, align, 1);
-         assemble_integer (GEN_INT (data[1]), 4, nalign, 1);
-         break;
-       case XFmode:
-         REAL_VALUE_TO_TARGET_LONG_DOUBLE (d, data);
-         assemble_integer (GEN_INT (data[0]), 4, align, 1);
-         assemble_integer (GEN_INT (data[1]), 4, nalign, 1);
-         assemble_integer (GEN_INT (data[2]), 4, nalign, 1);
-         break;
-       case TFmode:
-         REAL_VALUE_TO_TARGET_LONG_DOUBLE (d, data);
-         assemble_integer (GEN_INT (data[0]), 4, align, 1);
-         assemble_integer (GEN_INT (data[1]), 4, nalign, 1);
-         assemble_integer (GEN_INT (data[2]), 4, nalign, 1);
-         assemble_integer (GEN_INT (data[3]), 4, nalign, 1);
-         break;
-       default:
-         abort ();
-       }
-      break;
+  /* This is hairy.  We have a quantity of known size.  real_to_target
+     will put it into an array of *host* longs, 32 bits per element
+     (even if long is more than 32 bits).  We need to determine the
+     number of array elements that are occupied (nelts) and the number
+     of *target* min-addressable units that will be occupied in the
+     object file (nunits).  We cannot assume that 32 divides the
+     mode's bitsize (size * BITS_PER_UNIT) evenly.
 
-    case 16:
-      switch (mode)
-       {
-       case HFmode:
-         REAL_VALUE_TO_TARGET_SINGLE (d, l);
-         assemble_integer (GEN_INT (l), 2, align, 1);
-         break;
-       case TQFmode:
-         REAL_VALUE_TO_TARGET_DOUBLE (d, data);
-         assemble_integer (GEN_INT (data[0]), 2, align, 1);
-         assemble_integer (GEN_INT (data[1]), 1, nalign, 1);
-         break;
-       default:
-         abort ();
-       }
-      break;
+     size * BITS_PER_UNIT is used here to make sure that padding bits
+     (which might appear at either end of the value; real_to_target
+     will include the padding bits in its output array) are included.  */
 
-    case 32:
-      switch (mode)
-       {
-       case QFmode:
-         REAL_VALUE_TO_TARGET_SINGLE (d, l);
-         assemble_integer (GEN_INT (l), 1, align, 1);
-         break;
-       case HFmode:
-         REAL_VALUE_TO_TARGET_DOUBLE (d, data);
-         assemble_integer (GEN_INT (data[0]), 1, align, 1);
-         assemble_integer (GEN_INT (data[1]), 1, nalign, 1);
-         break;
-       default:
-         abort ();
-       }
-      break;
+  nunits = GET_MODE_SIZE (mode);
+  bitsize = nunits * BITS_PER_UNIT;
+  nelts = CEIL (bitsize, 32);
+  units_per = 32 / BITS_PER_UNIT;
 
-    default:
-      abort ();
+  real_to_target (data, &d, mode);
+
+  /* Put out the first word with the specified alignment.  */
+  assemble_integer (GEN_INT (data[0]), MIN (nunits, units_per), align, 1);
+  nunits -= units_per;
+
+  /* Subsequent words need only 32-bit alignment.  */
+  align = min_align (align, 32);
+
+  for (i = 1; i < nelts; i++)
+    {
+      assemble_integer (GEN_INT (data[i]), MIN (nunits, units_per), align, 1);
+      nunits -= units_per;
     }
 }
 \f
@@ -2074,9 +1967,7 @@ struct addr_const GTY(())
 };
 
 static void
-decode_addr_const (exp, value)
-     tree exp;
-     struct addr_const *value;
+decode_addr_const (tree exp, struct addr_const *value)
 {
   tree target = TREE_OPERAND (exp, 0);
   int offset = 0;
@@ -2180,22 +2071,19 @@ struct constant_descriptor_tree GTY(())
 static GTY((param_is (struct constant_descriptor_tree)))
      htab_t const_desc_htab;
 
-static struct constant_descriptor_tree * build_constant_desc PARAMS ((tree));
-static void maybe_output_constant_def_contents
-    PARAMS ((struct constant_descriptor_tree *, int));
+static struct constant_descriptor_tree * build_constant_desc (tree);
+static void maybe_output_constant_def_contents (struct constant_descriptor_tree *, int);
 
 /* Compute a hash code for a constant expression.  */
 
 static hashval_t
-const_desc_hash (ptr)
-     const void *ptr;
+const_desc_hash (const void *ptr)
 {
   return const_hash_1 (((struct constant_descriptor_tree *)ptr)->value);
 }
 
 static hashval_t
-const_hash_1 (exp)
-     const tree exp;
+const_hash_1 (const tree exp)
 {
   const char *p;
   hashval_t hi;
@@ -2229,7 +2117,7 @@ const_hash_1 (exp)
          char *tmp;
 
          len = int_size_in_bytes (TREE_TYPE (exp));
-         tmp = (char *) alloca (len);
+         tmp = alloca (len);
          get_set_constructor_bytes (exp, (unsigned char *) tmp, len);
          p = tmp;
          break;
@@ -2284,7 +2172,7 @@ const_hash_1 (exp)
       return code;
     }
 
-  /* Compute hashing function */
+  /* Compute hashing function */
   hi = len;
   for (i = 0; i < len; i++)
     hi = ((hi * 613) + (unsigned) (p[i]));
@@ -2294,9 +2182,7 @@ const_hash_1 (exp)
 
 /* Wrapper of compare_constant, for the htab interface.  */
 static int
-const_desc_eq (p1, p2)
-     const void *p1;
-     const void *p2;
+const_desc_eq (const void *p1, const void *p2)
 {
   return compare_constant (((struct constant_descriptor_tree *)p1)->value,
                           ((struct constant_descriptor_tree *)p2)->value);
@@ -2306,9 +2192,7 @@ const_desc_eq (p1, p2)
    the same bit pattern on output.  */
 
 static int
-compare_constant (t1, t2)
-     const tree t1;
-     const tree t2;
+compare_constant (const tree t1, const tree t2)
 {
   enum tree_code typecode;
 
@@ -2363,15 +2247,15 @@ compare_constant (t1, t2)
          if (int_size_in_bytes (TREE_TYPE (t1)) != len)
            return 0;
 
-         tmp1 = (unsigned char *) alloca (len);
-         tmp2 = (unsigned char *) alloca (len);
+         tmp1 = alloca (len);
+         tmp2 = alloca (len);
 
          if (get_set_constructor_bytes (t1, tmp1, len) != NULL_TREE)
            return 0;
          if (get_set_constructor_bytes (t2, tmp2, len) != NULL_TREE)
            return 0;
 
-         return memcmp (tmp1, tmp2, len) != 0;
+         return memcmp (tmp1, tmp2, len) == 0;
        }
       else
        {
@@ -2460,8 +2344,7 @@ compare_constant (t1, t2)
    handles the same types of nodes that compare_constant handles.  */
 
 static tree
-copy_constant (exp)
-     tree exp;
+copy_constant (tree exp)
 {
   switch (TREE_CODE (exp))
     {
@@ -2533,8 +2416,7 @@ copy_constant (exp)
    Caller is responsible for updating the hash table.  */
 
 static struct constant_descriptor_tree *
-build_constant_desc (exp)
-     tree exp;
+build_constant_desc (tree exp)
 {
   rtx symbol;
   rtx rtl;
@@ -2587,9 +2469,7 @@ build_constant_desc (exp)
    The const_hash_table records which constants already have label strings.  */
 
 rtx
-output_constant_def (exp, defer)
-     tree exp;
-     int defer;
+output_constant_def (tree exp, int defer)
 {
   struct constant_descriptor_tree *desc;
   struct constant_descriptor_tree key;
@@ -2614,9 +2494,8 @@ output_constant_def (exp, defer)
 /* Subroutine of output_constant_def: Decide whether or not we need to
    output the constant DESC now, and if so, do it.  */
 static void
-maybe_output_constant_def_contents (desc, defer)
-     struct constant_descriptor_tree *desc;
-     int defer;
+maybe_output_constant_def_contents (struct constant_descriptor_tree *desc,
+                                   int defer)
 {
   rtx symbol = XEXP (desc->rtl, 0);
   tree exp = desc->value;
@@ -2648,15 +2527,15 @@ maybe_output_constant_def_contents (desc, defer)
 /* We must output the constant data referred to by SYMBOL; do so.  */
 
 static void
-output_constant_def_contents (symbol)
-     rtx symbol;
+output_constant_def_contents (rtx symbol)
 {
   tree exp = SYMBOL_REF_DECL (symbol);
   const char *label = XSTR (symbol, 0);
+  HOST_WIDE_INT size;
 
   /* Make sure any other constants whose addresses appear in EXP
      are assigned label numbers.  */
-  int reloc = output_addressed_constants (exp);
+  int reloc = compute_reloc_for_constant (exp);
 
   /* Align the location counter as required by EXP's data type.  */
   int align = TYPE_ALIGN (TREE_TYPE (exp));
@@ -2664,6 +2543,8 @@ output_constant_def_contents (symbol)
   align = CONSTANT_ALIGNMENT (exp, align);
 #endif
 
+  output_addressed_constants (exp);
+
   /* We are no longer deferring this constant.  */
   TREE_ASM_WRITTEN (exp) = 1;
 
@@ -2677,27 +2558,45 @@ output_constant_def_contents (symbol)
       ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
     }
 
-  /* Output the label itself.  */
+  size = int_size_in_bytes (TREE_TYPE (exp));
+  if (TREE_CODE (exp) == STRING_CST)
+    size = MAX (TREE_STRING_LENGTH (exp), size);
+
+  /* Do any machine/system dependent processing of the constant.  */
+#ifdef ASM_DECLARE_CONSTANT_NAME
+  ASM_DECLARE_CONSTANT_NAME (asm_out_file, label, exp, size);
+#else
+  /* Standard thing is just output label for the constant.  */
   ASM_OUTPUT_LABEL (asm_out_file, label);
+#endif /* ASM_DECLARE_CONSTANT_NAME */
 
   /* Output the value of EXP.  */
-  output_constant (exp,
-                  (TREE_CODE (exp) == STRING_CST
-                   ? MAX (TREE_STRING_LENGTH (exp),
-                          int_size_in_bytes (TREE_TYPE (exp)))
-                   : int_size_in_bytes (TREE_TYPE (exp))),
-                  align);
-
+  output_constant (exp, size, align);
 }
 
 /* A constant which was deferred in its original location has been
    inserted by the RTL inliner into a different function.  The
    current function's deferred constant count must be incremented.  */
 void
-notice_rtl_inlining_of_deferred_constant ()
+notice_rtl_inlining_of_deferred_constant (void)
 {
   n_deferred_constants++;
 }
+
+/* Look up EXP in the table of constant descriptors.  Return the rtl
+   if it has been emitted, else null.  */
+
+rtx
+lookup_constant_def (tree exp)
+{
+  struct constant_descriptor_tree *desc;
+  struct constant_descriptor_tree key;
+
+  key.value = exp;
+  desc = htab_find (const_desc_htab, &key);
+
+  return (desc ? desc->rtl : NULL_RTX);
+}
 \f
 /* Used in the hash tables to avoid outputting the same constant
    twice.  Unlike 'struct constant_descriptor_tree', RTX constants
@@ -2742,20 +2641,17 @@ struct pool_constant GTY(())
 /* Initialize constant pool hashing for a new function.  */
 
 void
-init_varasm_status (f)
-     struct function *f;
+init_varasm_status (struct function *f)
 {
   struct varasm_status *p;
-  p = (struct varasm_status *) ggc_alloc (sizeof (struct varasm_status));
+  p = ggc_alloc (sizeof (struct varasm_status));
   f->varasm = p;
   p->x_const_rtx_hash_table
-    = ((struct constant_descriptor_rtx **)
-       ggc_alloc_cleared (MAX_RTX_HASH_TABLE
-                         * sizeof (struct constant_descriptor_rtx *)));
+    = ggc_alloc_cleared (MAX_RTX_HASH_TABLE
+                        * sizeof (struct constant_descriptor_rtx *));
   p->x_const_rtx_sym_hash_table
-    = ((struct pool_constant **)
-       ggc_alloc_cleared (MAX_RTX_HASH_TABLE
-                         * sizeof (struct pool_constant *)));
+    = ggc_alloc_cleared (MAX_RTX_HASH_TABLE
+                        * sizeof (struct pool_constant *));
 
   p->x_first_pool = p->x_last_pool = 0;
   p->x_pool_offset = 0;
@@ -2768,10 +2664,7 @@ init_varasm_status (f)
    They are stored into VALUE.  */
 
 static void
-decode_rtx_const (mode, x, value)
-     enum machine_mode mode;
-     rtx x;
-     struct rtx_const *value;
+decode_rtx_const (enum machine_mode mode, rtx x, struct rtx_const *value)
 {
   /* Clear the whole structure, including any gaps.  */
   memset (value, 0, sizeof (struct rtx_const));
@@ -2801,7 +2694,7 @@ decode_rtx_const (mode, x, value)
              break;
            case rvc_normal:
              value->un.du.exp = r->exp;
-             /* FALLTHRU */
+             /* Fall through.  */
            case rvc_nan:
              memcpy (value->un.du.sig, r->sig, sizeof (r->sig));
              break;
@@ -2861,7 +2754,7 @@ decode_rtx_const (mode, x, value)
                    break;
                  case rvc_normal:
                    d->exp = r->exp;
-                   /* FALLTHRU */
+                   /* Fall through.  */
                  case rvc_nan:
                    memcpy (d->sig, r->sig, sizeof (r->sig));
                    break;
@@ -2949,8 +2842,7 @@ decode_rtx_const (mode, x, value)
    include the same symbol.  */
 
 rtx
-simplify_subtraction (x)
-     rtx x;
+simplify_subtraction (rtx x)
 {
   struct rtx_const val0, val1;
 
@@ -2969,9 +2861,7 @@ simplify_subtraction (x)
 /* Compute a hash code for a constant RTL expression.  */
 
 static unsigned int
-const_hash_rtx (mode, x)
-     enum machine_mode mode;
-     rtx x;
+const_hash_rtx (enum machine_mode mode, rtx x)
 {
   union {
     struct rtx_const value;
@@ -2983,7 +2873,7 @@ const_hash_rtx (mode, x)
 
   decode_rtx_const (mode, x, &u.value);
 
-  /* Compute hashing function */
+  /* Compute hashing function */
   hi = 0;
   for (i = 0; i < ARRAY_SIZE (u.data); i++)
     hi = hi * 613 + u.data[i];
@@ -2995,10 +2885,8 @@ const_hash_rtx (mode, x)
    Return 1 if DESC describes a constant with the same value as X.  */
 
 static int
-compare_constant_rtx (mode, x, desc)
-     enum machine_mode mode;
-     rtx x;
-     struct constant_descriptor_rtx *desc;
+compare_constant_rtx (enum machine_mode mode, rtx x,
+                     struct constant_descriptor_rtx *desc)
 {
   struct rtx_const value;
 
@@ -3012,43 +2900,21 @@ compare_constant_rtx (mode, x, desc)
    It is up to the caller to enter the descriptor in the hash table.  */
 
 static struct constant_descriptor_rtx *
-record_constant_rtx (mode, x)
-     enum machine_mode mode;
-     rtx x;
+record_constant_rtx (enum machine_mode mode, rtx x)
 {
   struct constant_descriptor_rtx *ptr;
 
-  ptr = (struct constant_descriptor_rtx *) ggc_alloc (sizeof (*ptr));
+  ptr = ggc_alloc (sizeof (*ptr));
   decode_rtx_const (mode, x, &ptr->value);
 
   return ptr;
 }
 \f
-/* Given a constant rtx X, return a MEM for the location in memory at which
-   this constant has been placed.  Return 0 if it not has been placed yet.  */
-
-rtx
-mem_for_const_double (x)
-     rtx x;
-{
-  enum machine_mode mode = GET_MODE (x);
-  struct constant_descriptor_rtx *desc;
-
-  for (desc = const_rtx_hash_table[const_hash_rtx (mode, x)]; desc;
-       desc = desc->next)
-    if (compare_constant_rtx (mode, x, desc))
-      return desc->rtl;
-
-  return 0;
-}
-
 /* Given a constant rtx X, make (or find) a memory constant for its value
    and return a MEM rtx to refer to it in memory.  */
 
 rtx
-force_const_mem (mode, x)
-     enum machine_mode mode;
-     rtx x;
+force_const_mem (enum machine_mode mode, rtx x)
 {
   int hash;
   struct constant_descriptor_rtx *desc;
@@ -3066,7 +2932,7 @@ force_const_mem (mode, x)
   hash = const_hash_rtx (mode, x);
   for (desc = const_rtx_hash_table[hash]; desc; desc = desc->next)
     if (compare_constant_rtx (mode, x, desc))
-      return desc->rtl;
+      return copy_rtx (desc->rtl);
 
   /* No constant equal to X is known to have been output.
      Make a constant descriptor to enter X in the hash table
@@ -3092,7 +2958,7 @@ force_const_mem (mode, x)
     LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
 
   /* Allocate a pool constant descriptor, fill it in, and chain it in.  */
-  pool = (struct pool_constant *) ggc_alloc (sizeof (struct pool_constant));
+  pool = ggc_alloc (sizeof (struct pool_constant));
   pool->desc = desc;
   pool->constant = x;
   pool->mode = mode;
@@ -3134,16 +3000,14 @@ force_const_mem (mode, x)
   SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL;
   current_function_uses_const_pool = 1;
 
-  return def;
+  return copy_rtx (def);
 }
 \f
 /* Given a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true, return a pointer to
    the corresponding pool_constant structure.  */
 
 static struct pool_constant *
-find_pool_constant (f, addr)
-     struct function *f;
-     rtx addr;
+find_pool_constant (struct function *f, rtx addr)
 {
   struct pool_constant *pool;
   const char *label = XSTR (addr, 0);
@@ -3159,8 +3023,7 @@ find_pool_constant (f, addr)
 /* Given a constant pool SYMBOL_REF, return the corresponding constant.  */
 
 rtx
-get_pool_constant (addr)
-     rtx addr;
+get_pool_constant (rtx addr)
 {
   return (find_pool_constant (cfun, addr))->constant;
 }
@@ -3169,9 +3032,7 @@ get_pool_constant (addr)
    and whether it has been output or not.  */
 
 rtx
-get_pool_constant_mark (addr, pmarked)
-     rtx addr;
-     bool *pmarked;
+get_pool_constant_mark (rtx addr, bool *pmarked)
 {
   struct pool_constant *pool = find_pool_constant (cfun, addr);
   *pmarked = (pool->mark != 0);
@@ -3181,9 +3042,7 @@ get_pool_constant_mark (addr, pmarked)
 /* Likewise, but for the constant pool of a specific function.  */
 
 rtx
-get_pool_constant_for_function (f, addr)
-     struct function *f;
-     rtx addr;
+get_pool_constant_for_function (struct function *f, rtx addr)
 {
   return (find_pool_constant (f, addr))->constant;
 }
@@ -3191,16 +3050,13 @@ get_pool_constant_for_function (f, addr)
 /* Similar, return the mode.  */
 
 enum machine_mode
-get_pool_mode (addr)
-     rtx addr;
+get_pool_mode (rtx addr)
 {
   return (find_pool_constant (cfun, addr))->mode;
 }
 
 enum machine_mode
-get_pool_mode_for_function (f, addr)
-     struct function *f;
-     rtx addr;
+get_pool_mode_for_function (struct function *f, rtx addr)
 {
   return (find_pool_constant (f, addr))->mode;
 }
@@ -3208,8 +3064,7 @@ get_pool_mode_for_function (f, addr)
 /* Similar, return the offset in the constant pool.  */
 
 int
-get_pool_offset (addr)
-     rtx addr;
+get_pool_offset (rtx addr)
 {
   return (find_pool_constant (cfun, addr))->offset;
 }
@@ -3217,7 +3072,7 @@ get_pool_offset (addr)
 /* Return the size of the constant pool.  */
 
 int
-get_pool_size ()
+get_pool_size (void)
 {
   return pool_offset;
 }
@@ -3225,9 +3080,8 @@ get_pool_size ()
 /* Write all the constants in the constant pool.  */
 
 void
-output_constant_pool (fnname, fndecl)
-     const char *fnname ATTRIBUTE_UNUSED;
-     tree fndecl ATTRIBUTE_UNUSED;
+output_constant_pool (const char *fnname ATTRIBUTE_UNUSED,
+                     tree fndecl ATTRIBUTE_UNUSED)
 {
   struct pool_constant *pool;
   rtx x;
@@ -3268,7 +3122,7 @@ output_constant_pool (fnname, fndecl)
              || GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
            break;
          tmp = XEXP (XEXP (x, 0), 0);
-         /* FALLTHRU */
+         /* Fall through.  */
 
        case LABEL_REF:
          tmp = XEXP (x, 0);
@@ -3381,7 +3235,7 @@ output_constant_pool (fnname, fndecl)
    deferred constants which have indeed been used.  */
 
 static void
-mark_constant_pool ()
+mark_constant_pool (void)
 {
   rtx insn;
   rtx link;
@@ -3414,8 +3268,7 @@ mark_constant_pool ()
    deferred strings that are used.  */
 
 static void
-mark_constants (x)
-     rtx x;
+mark_constants (rtx x)
 {
   int i;
   const char *format_ptr;
@@ -3479,9 +3332,7 @@ mark_constants (x)
    be used with for_each_rtx to mark all SYMBOL_REFs in an rtx.  */
 
 static int
-mark_constant (current_rtx, data)
-     rtx *current_rtx;
-     void *data ATTRIBUTE_UNUSED;
+mark_constant (rtx *current_rtx, void *data ATTRIBUTE_UNUSED)
 {
   rtx x = *current_rtx;
 
@@ -3514,13 +3365,10 @@ mark_constant (current_rtx, data)
   return 0;
 }
 \f
-/* Find all the constants whose addresses are referenced inside of EXP,
-   and make sure assembler code with a label has been output for each one.
-   Indicate whether an ADDR_EXPR has been encountered.  */
+/* Determine what kind of relocations EXP may need.  */
 
-static int
-output_addressed_constants (exp)
-     tree exp;
+int
+compute_reloc_for_constant (tree exp)
 {
   int reloc = 0, reloc2;
   tree tem;
@@ -3540,10 +3388,6 @@ output_addressed_constants (exp)
           tem = TREE_OPERAND (tem, 0))
        ;
 
-      if (TREE_CODE_CLASS (TREE_CODE (tem)) == 'c'
-         || TREE_CODE (tem) == CONSTRUCTOR)
-       output_constant_def (tem, 0);
-
       if (TREE_PUBLIC (tem))
        reloc |= 2;
       else
@@ -3551,13 +3395,13 @@ output_addressed_constants (exp)
       break;
 
     case PLUS_EXPR:
-      reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
-      reloc |= output_addressed_constants (TREE_OPERAND (exp, 1));
+      reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
+      reloc |= compute_reloc_for_constant (TREE_OPERAND (exp, 1));
       break;
 
     case MINUS_EXPR:
-      reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
-      reloc2 = output_addressed_constants (TREE_OPERAND (exp, 1));
+      reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
+      reloc2 = compute_reloc_for_constant (TREE_OPERAND (exp, 1));
       /* The difference of two local labels is computable at link time.  */
       if (reloc == 1 && reloc2 == 1)
        reloc = 0;
@@ -3568,13 +3412,13 @@ output_addressed_constants (exp)
     case NOP_EXPR:
     case CONVERT_EXPR:
     case NON_LVALUE_EXPR:
-      reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
+      reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
       break;
 
     case CONSTRUCTOR:
       for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem))
        if (TREE_VALUE (tem) != 0)
-         reloc |= output_addressed_constants (TREE_VALUE (tem));
+         reloc |= compute_reloc_for_constant (TREE_VALUE (tem));
 
       break;
 
@@ -3583,6 +3427,58 @@ output_addressed_constants (exp)
     }
   return reloc;
 }
+
+/* Find all the constants whose addresses are referenced inside of EXP,
+   and make sure assembler code with a label has been output for each one.
+   Indicate whether an ADDR_EXPR has been encountered.  */
+
+static void
+output_addressed_constants (tree exp)
+{
+  tree tem;
+
+  /* Give the front-end a chance to convert VALUE to something that
+     looks more like a constant to the back-end.  */
+  exp = (*lang_hooks.expand_constant) (exp);
+
+  switch (TREE_CODE (exp))
+    {
+    case ADDR_EXPR:
+    case FDESC_EXPR:
+      /* Go inside any operations that get_inner_reference can handle and see
+        if what's inside is a constant: no need to do anything here for
+        addresses of variables or functions.  */
+      for (tem = TREE_OPERAND (exp, 0); handled_component_p (tem);
+          tem = TREE_OPERAND (tem, 0))
+       ;
+
+      if (TREE_CODE_CLASS (TREE_CODE (tem)) == 'c'
+         || TREE_CODE (tem) == CONSTRUCTOR)
+       output_constant_def (tem, 0);
+      break;
+
+    case PLUS_EXPR:
+    case MINUS_EXPR:
+      output_addressed_constants (TREE_OPERAND (exp, 1));
+      /* Fall through.  */
+
+    case NOP_EXPR:
+    case CONVERT_EXPR:
+    case NON_LVALUE_EXPR:
+      output_addressed_constants (TREE_OPERAND (exp, 0));
+      break;
+
+    case CONSTRUCTOR:
+      for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem))
+       if (TREE_VALUE (tem) != 0)
+         output_addressed_constants (TREE_VALUE (tem));
+
+      break;
+
+    default:
+      break;
+    }
+}
 \f
 /* Return nonzero if VALUE is a valid constant-valued expression
    for use in initializing a static variable; one that can be an
@@ -3595,9 +3491,7 @@ output_addressed_constants (exp)
    arithmetic-combinations of integers.  */
 
 tree
-initializer_constant_valid_p (value, endtype)
-     tree value;
-     tree endtype;
+initializer_constant_valid_p (tree value, tree endtype)
 {
   /* Give the front-end a chance to convert VALUE to something that
      looks more like a constant to the back-end.  */
@@ -3610,11 +3504,27 @@ initializer_constant_valid_p (value, endtype)
           || TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE)
          && TREE_CONSTANT (value)
          && CONSTRUCTOR_ELTS (value))
-       return
-         initializer_constant_valid_p (TREE_VALUE (CONSTRUCTOR_ELTS (value)),
-                                       endtype);
+       {
+         tree elt;
+         bool absolute = true;
+
+         for (elt = CONSTRUCTOR_ELTS (value); elt; elt = TREE_CHAIN (elt))
+           {
+             tree reloc;
+             value = TREE_VALUE (elt);
+             reloc = initializer_constant_valid_p (value, TREE_TYPE (value));
+             if (!reloc)
+               return NULL_TREE;
+             if (reloc != null_pointer_node)
+               absolute = false;
+           }
+         /* For a non-absolute relocation, there is no single
+            variable that can be "the variable that determines the
+            relocation."  */
+         return absolute ? null_pointer_node : error_mark_node;
+       }
 
-      return TREE_STATIC (value) ? null_pointer_node : 0;
+      return TREE_STATIC (value) ? null_pointer_node : NULL_TREE;
 
     case INTEGER_CST:
     case VECTOR_CST:
@@ -3672,7 +3582,8 @@ initializer_constant_valid_p (value, endtype)
 
       /* Likewise conversions from int to pointers, but also allow
         conversions from 0.  */
-      if (POINTER_TYPE_P (TREE_TYPE (value))
+      if ((POINTER_TYPE_P (TREE_TYPE (value))
+          || TREE_CODE (TREE_TYPE (value)) == OFFSET_TYPE)
          && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))))
        {
          if (integer_zerop (TREE_OPERAND (value, 0)))
@@ -3804,10 +3715,7 @@ initializer_constant_valid_p (value, endtype)
    ALIGN is the alignment of the data in bits.  */
 
 void
-output_constant (exp, size, align)
-     tree exp;
-     unsigned HOST_WIDE_INT size;
-     unsigned int align;
+output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
 {
   enum tree_code code;
   unsigned HOST_WIDE_INT thissize;
@@ -3860,6 +3768,7 @@ output_constant (exp, size, align)
     case ENUMERAL_TYPE:
     case POINTER_TYPE:
     case REFERENCE_TYPE:
+    case OFFSET_TYPE:
       if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode,
                                           EXPAND_INITIALIZER),
                              size, align, 0))
@@ -3870,9 +3779,7 @@ output_constant (exp, size, align)
       if (TREE_CODE (exp) != REAL_CST)
        error ("initializer for floating value is not a floating constant");
 
-      assemble_real (TREE_REAL_CST (exp),
-                    mode_for_size (size * BITS_PER_UNIT, MODE_FLOAT, 0),
-                    align);
+      assemble_real (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)), align);
       break;
 
     case COMPLEX_TYPE:
@@ -3930,7 +3837,7 @@ output_constant (exp, size, align)
                          thissize, align, 1);
       else if (TREE_CODE (exp) == CONSTRUCTOR)
        {
-         unsigned char *buffer = (unsigned char *) alloca (thissize);
+         unsigned char *buffer = alloca (thissize);
          if (get_set_constructor_bytes (exp, buffer, thissize))
            abort ();
          assemble_string ((char *) buffer, thissize);
@@ -3956,8 +3863,7 @@ output_constant (exp, size, align)
    type with an unspecified upper bound.  */
 
 static unsigned HOST_WIDE_INT
-array_size_for_constructor (val)
-     tree val;
+array_size_for_constructor (tree val)
 {
   tree max_index, i;
 
@@ -3997,10 +3903,8 @@ array_size_for_constructor (val)
    Generate at least SIZE bytes, padding if necessary.  */
 
 static void
-output_constructor (exp, size, align)
-     tree exp;
-     unsigned HOST_WIDE_INT size;
-     unsigned int align;
+output_constructor (tree exp, unsigned HOST_WIDE_INT size,
+                   unsigned int align)
 {
   tree type = TREE_TYPE (exp);
   tree link, field = 0;
@@ -4049,6 +3953,15 @@ output_constructor (exp, size, align)
       else if (TREE_CODE (type) == ARRAY_TYPE)
        index = TREE_PURPOSE (link);
 
+#ifdef ASM_COMMENT_START
+      if (field && flag_verbose_asm)
+       fprintf (asm_out_file, "%s %s:\n",
+                ASM_COMMENT_START, 
+                DECL_NAME (field) 
+                ? IDENTIFIER_POINTER (DECL_NAME (field))
+                : "<anonymous>");
+#endif
+
       /* Eliminate the marker that makes a cast not be an lvalue.  */
       if (val != 0)
        STRIP_NOPS (val);
@@ -4306,8 +4219,7 @@ static GTY(()) tree weak_decls;
 /* Mark DECL as weak.  */
 
 static void
-mark_weak (decl)
-     tree decl;
+mark_weak (tree decl)
 {
   DECL_WEAK (decl) = 1;
 
@@ -4321,9 +4233,7 @@ mark_weak (decl)
 /* Merge weak status between NEWDECL and OLDDECL.  */
 
 void
-merge_weak (newdecl, olddecl)
-     tree newdecl;
-     tree olddecl;
+merge_weak (tree newdecl, tree olddecl)
 {
   if (DECL_WEAK (newdecl) == DECL_WEAK (olddecl))
     return;
@@ -4339,15 +4249,16 @@ merge_weak (newdecl, olddecl)
         declare_weak because the NEWDECL and OLDDECL was not yet
         been merged; therefore, TREE_ASM_WRITTEN was not set.  */
       if (TREE_ASM_WRITTEN (olddecl))
-       error_with_decl (newdecl,
-                        "weak declaration of `%s' must precede definition");
+       error ("%Jweak declaration of '%D' must precede definition",
+              newdecl, newdecl);
 
       /* If we've already generated rtl referencing OLDDECL, we may
         have done so in a way that will not function properly with
         a weak symbol.  */
       else if (TREE_USED (olddecl)
               && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (olddecl)))
-       warning_with_decl (newdecl, "weak declaration of `%s' after first use results in unspecified behavior");
+       warning ("%Jweak declaration of '%D' after first use results "
+                 "in unspecified behavior", newdecl, newdecl);
 
       if (SUPPORTS_WEAK)
        {
@@ -4377,20 +4288,19 @@ merge_weak (newdecl, olddecl)
 /* Declare DECL to be a weak symbol.  */
 
 void
-declare_weak (decl)
-     tree decl;
+declare_weak (tree decl)
 {
   if (! TREE_PUBLIC (decl))
-    error_with_decl (decl, "weak declaration of `%s' must be public");
+    error ("%Jweak declaration of '%D' must be public", decl, decl);
   else if (TREE_CODE (decl) == FUNCTION_DECL && TREE_ASM_WRITTEN (decl))
-    error_with_decl (decl, "weak declaration of `%s' must precede definition");
+    error ("%Jweak declaration of '%D' must precede definition", decl, decl);
   else if (SUPPORTS_WEAK)
     {
       if (! DECL_WEAK (decl))
        weak_decls = tree_cons (NULL, decl, weak_decls);
     }
   else
-    warning_with_decl (decl, "weak declaration of `%s' not supported");
+    warning ("%Jweak declaration of '%D' not supported", decl, decl);
 
   mark_weak (decl);
 }
@@ -4398,7 +4308,7 @@ declare_weak (decl)
 /* Emit any pending weak declarations.  */
 
 void
-weak_finish ()
+weak_finish (void)
 {
   tree t;
 
@@ -4430,8 +4340,7 @@ weak_finish ()
 /* Emit the assembly bits to indicate that DECL is globally visible.  */
 
 static void
-globalize_decl (decl)
-     tree decl;
+globalize_decl (tree decl)
 {
   const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
 
@@ -4466,8 +4375,7 @@ globalize_decl (decl)
    the symbol for TARGET.  */
 
 void
-assemble_alias (decl, target)
-     tree decl, target ATTRIBUTE_UNUSED;
+assemble_alias (tree decl, tree target ATTRIBUTE_UNUSED)
 {
   const char *name;
 
@@ -4493,14 +4401,26 @@ assemble_alias (decl, target)
 #endif
 #else /* !ASM_OUTPUT_DEF */
 #if defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL)
-  if (DECL_WEAK (decl))
-    warning ("only weak aliases are supported in this configuration");
-
+  if (DECL_WEAK (decl))
+    {
+      tree *p, t;
 #ifdef ASM_WEAKEN_DECL
-  ASM_WEAKEN_DECL (asm_out_file, decl, name, IDENTIFIER_POINTER (target));
+      ASM_WEAKEN_DECL (asm_out_file, decl, name, IDENTIFIER_POINTER (target));
 #else
-  ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
+      ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
 #endif
+      /* Remove this function from the pending weak list so that
+        we do not emit multiple .weak directives for it.  */
+      for (p = &weak_decls; (t = *p) ; )
+       if (DECL_ASSEMBLER_NAME (decl)
+           == DECL_ASSEMBLER_NAME (TREE_VALUE (t)))
+         *p = TREE_CHAIN (t);
+       else
+         p = &TREE_CHAIN (t);
+    }
+  else
+    warning ("only weak aliases are supported in this configuration");
+
 #else
   warning ("alias definitions not supported in this configuration; ignored");
 #endif
@@ -4515,9 +4435,7 @@ assemble_alias (decl, target)
    the visibility type VIS, which must not be VISIBILITY_DEFAULT.  */
 
 void
-default_assemble_visibility (decl, vis)
-     tree decl;
-     int vis;
+default_assemble_visibility (tree decl, int vis)
 {
   static const char * const visibility_types[] = {
     NULL, "internal", "hidden", "protected"
@@ -4540,10 +4458,9 @@ default_assemble_visibility (decl, vis)
 /* A helper function to call assemble_visibility when needed for a decl.  */
 
 static void
-maybe_assemble_visibility (decl)
-     tree decl;
+maybe_assemble_visibility (tree decl)
 {
-  enum symbol_visibility vis = decl_visibility (decl);
+  enum symbol_visibility vis = DECL_VISIBILITY (decl);
 
   if (vis != VISIBILITY_DEFAULT)
     (* targetm.asm_out.visibility) (decl, vis);
@@ -4555,7 +4472,7 @@ maybe_assemble_visibility (decl)
    a target-specific mechanism for having duplicates discarded.  */
 
 int
-supports_one_only ()
+supports_one_only (void)
 {
   if (SUPPORTS_ONE_ONLY)
     return 1;
@@ -4566,8 +4483,7 @@ supports_one_only ()
    translation units without generating a linker error.  */
 
 void
-make_decl_one_only (decl)
-     tree decl;
+make_decl_one_only (tree decl)
 {
   if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
     abort ();
@@ -4591,7 +4507,7 @@ make_decl_one_only (decl)
 }
 
 void
-init_varasm_once ()
+init_varasm_once (void)
 {
   in_named_htab = htab_create_ggc (31, in_named_entry_hash,
                                   in_named_entry_eq, NULL);
@@ -4602,8 +4518,7 @@ init_varasm_once ()
 }
 
 enum tls_model
-decl_tls_model (decl)
-     tree decl;
+decl_tls_model (tree decl)
 {
   enum tls_model kind;
   tree attr = lookup_attribute ("tls_model", DECL_ATTRIBUTES (decl));
@@ -4647,31 +4562,6 @@ decl_tls_model (decl)
   return kind;
 }
 
-enum symbol_visibility
-decl_visibility (decl)
-     tree decl;
-{
-  tree attr = lookup_attribute ("visibility", DECL_ATTRIBUTES (decl));
-
-  if (attr)
-    {
-      const char *which = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
-
-      if (strcmp (which, "default") == 0)
-       return VISIBILITY_DEFAULT;
-      if (strcmp (which, "internal") == 0)
-       return VISIBILITY_INTERNAL;
-      if (strcmp (which, "hidden") == 0)
-       return VISIBILITY_HIDDEN;
-      if (strcmp (which, "protected") == 0)
-       return VISIBILITY_PROTECTED;
-
-      abort ();
-    }
-
-  return VISIBILITY_DEFAULT;
-}
-
 /* Select a set of attributes for section NAME based on the properties
    of DECL and whether or not RELOC indicates that DECL's initializer
    might contain runtime relocations.
@@ -4680,20 +4570,14 @@ decl_visibility (decl)
    read-only for a const data decl, and writable for a non-const data decl.  */
 
 unsigned int
-default_section_type_flags (decl, name, reloc)
-     tree decl;
-     const char *name;
-     int reloc;
+default_section_type_flags (tree decl, const char *name, int reloc)
 {
   return default_section_type_flags_1 (decl, name, reloc, flag_pic);
 }
 
 unsigned int
-default_section_type_flags_1 (decl, name, reloc, shlib)
-     tree decl;
-     const char *name;
-     int reloc;
-     int shlib;
+default_section_type_flags_1 (tree decl, const char *name, int reloc,
+                             int shlib)
 {
   unsigned int flags;
 
@@ -4744,9 +4628,8 @@ default_section_type_flags_1 (decl, name, reloc, shlib)
    Four variants for common object file formats.  */
 
 void
-default_no_named_section (name, flags)
-     const char *name ATTRIBUTE_UNUSED;
-     unsigned int flags ATTRIBUTE_UNUSED;
+default_no_named_section (const char *name ATTRIBUTE_UNUSED,
+                         unsigned int flags ATTRIBUTE_UNUSED)
 {
   /* Some object formats don't support named sections at all.  The
      front-end should already have flagged this as an error.  */
@@ -4754,9 +4637,7 @@ default_no_named_section (name, flags)
 }
 
 void
-default_elf_asm_named_section (name, flags)
-     const char *name;
-     unsigned int flags;
+default_elf_asm_named_section (const char *name, unsigned int flags)
 {
   char flagchars[10], *f = flagchars;
 
@@ -4803,9 +4684,7 @@ default_elf_asm_named_section (name, flags)
 }
 
 void
-default_coff_asm_named_section (name, flags)
-     const char *name;
-     unsigned int flags;
+default_coff_asm_named_section (const char *name, unsigned int flags)
 {
   char flagchars[8], *f = flagchars;
 
@@ -4819,9 +4698,7 @@ default_coff_asm_named_section (name, flags)
 }
 
 void
-default_pe_asm_named_section (name, flags)
-     const char *name;
-     unsigned int flags;
+default_pe_asm_named_section (const char *name, unsigned int flags)
 {
   default_coff_asm_named_section (name, flags);
 
@@ -4835,40 +4712,11 @@ default_pe_asm_named_section (name, flags)
     }
 }
 \f
-/* Used for vtable gc in GNU binutils.  Record that the pointer at OFFSET
-   from SYMBOL is used in all classes derived from SYMBOL.  */
-
-void
-assemble_vtable_entry (symbol, offset)
-     rtx symbol;
-     HOST_WIDE_INT offset;
-{
-  fputs ("\t.vtable_entry ", asm_out_file);
-  output_addr_const (asm_out_file, symbol);
-  fprintf (asm_out_file, ", " HOST_WIDE_INT_PRINT_DEC "\n", offset);
-}
-
-/* Used for vtable gc in GNU binutils.  Record the class hierarchy by noting
-   that the vtable symbol CHILD is derived from the vtable symbol PARENT.  */
-
-void
-assemble_vtable_inherit (child, parent)
-     rtx child, parent;
-{
-  fputs ("\t.vtable_inherit ", asm_out_file);
-  output_addr_const (asm_out_file, child);
-  fputs (", ", asm_out_file);
-  output_addr_const (asm_out_file, parent);
-  fputc ('\n', asm_out_file);
-}
-\f
 /* The lame default section selector.  */
 
 void
-default_select_section (decl, reloc, align)
-     tree decl;
-     int reloc;
-     unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+default_select_section (tree decl, int reloc,
+                       unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
 {
   bool readonly = false;
 
@@ -4934,13 +4782,10 @@ enum section_category
 };
 
 static enum section_category
-categorize_decl_for_section PARAMS ((tree, int, int));
+categorize_decl_for_section (tree, int, int);
 
 static enum section_category
-categorize_decl_for_section (decl, reloc, shlib)
-     tree decl;
-     int reloc;
-     int shlib;
+categorize_decl_for_section (tree decl, int reloc, int shlib)
 {
   enum section_category ret;
 
@@ -5019,18 +4864,13 @@ categorize_decl_for_section (decl, reloc, shlib)
 }
 
 bool
-decl_readonly_section (decl, reloc)
-     tree decl;
-     int reloc;
+decl_readonly_section (tree decl, int reloc)
 {
   return decl_readonly_section_1 (decl, reloc, flag_pic);
 }
 
 bool
-decl_readonly_section_1 (decl, reloc, shlib)
-     tree decl;
-     int reloc;
-     int shlib;
+decl_readonly_section_1 (tree decl, int reloc, int shlib)
 {
   switch (categorize_decl_for_section (decl, reloc, shlib))
     {
@@ -5050,20 +4890,15 @@ decl_readonly_section_1 (decl, reloc, shlib)
 /* Select a section based on the above categorization.  */
 
 void
-default_elf_select_section (decl, reloc, align)
-     tree decl;
-     int reloc;
-     unsigned HOST_WIDE_INT align;
+default_elf_select_section (tree decl, int reloc,
+                           unsigned HOST_WIDE_INT align)
 {
   default_elf_select_section_1 (decl, reloc, align, flag_pic);
 }
 
 void
-default_elf_select_section_1 (decl, reloc, align, shlib)
-     tree decl;
-     int reloc;
-     unsigned HOST_WIDE_INT align;
-     int shlib;
+default_elf_select_section_1 (tree decl, int reloc,
+                             unsigned HOST_WIDE_INT align, int shlib)
 {
   switch (categorize_decl_for_section (decl, reloc, shlib))
     {
@@ -5128,18 +4963,13 @@ default_elf_select_section_1 (decl, reloc, align, shlib)
    categorization performed above.  */
 
 void
-default_unique_section (decl, reloc)
-     tree decl;
-     int reloc;
+default_unique_section (tree decl, int reloc)
 {
   default_unique_section_1 (decl, reloc, flag_pic);
 }
 
 void
-default_unique_section_1 (decl, reloc, shlib)
-     tree decl;
-     int reloc;
-     int shlib;
+default_unique_section_1 (tree decl, int reloc, int shlib)
 {
   bool one_only = DECL_ONE_ONLY (decl);
   const char *prefix, *name;
@@ -5199,10 +5029,9 @@ default_unique_section_1 (decl, reloc, shlib)
 }
 
 void
-default_select_rtx_section (mode, x, align)
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-     rtx x;
-     unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+default_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
+                           rtx x,
+                           unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
 {
   if (flag_pic)
     switch (GET_CODE (x))
@@ -5221,10 +5050,8 @@ default_select_rtx_section (mode, x, align)
 }
 
 void
-default_elf_select_rtx_section (mode, x, align)
-     enum machine_mode mode;
-     rtx x;
-     unsigned HOST_WIDE_INT align;
+default_elf_select_rtx_section (enum machine_mode mode, rtx x,
+                               unsigned HOST_WIDE_INT align)
 {
   /* ??? Handle small data here somehow.  */
 
@@ -5250,10 +5077,7 @@ default_elf_select_rtx_section (mode, x, align)
 /* Set the generally applicable flags on the SYMBOL_REF for EXP.  */
 
 void
-default_encode_section_info (decl, rtl, first)
-     tree decl;
-     rtx rtl;
-     int first ATTRIBUTE_UNUSED;
+default_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
 {
   rtx symbol;
   int flags;
@@ -5287,8 +5111,7 @@ default_encode_section_info (decl, rtl, first)
    do anything but discard the '*' marker.  */
 
 const char *
-default_strip_name_encoding (str)
-     const char *str;
+default_strip_name_encoding (const char *str)
 {
   return str + (*str == '*');
 }
@@ -5297,16 +5120,13 @@ default_strip_name_encoding (str)
    wrt cross-module name binding.  */
 
 bool
-default_binds_local_p (exp)
-     tree exp;
+default_binds_local_p (tree exp)
 {
   return default_binds_local_p_1 (exp, flag_shlib);
 }
 
 bool
-default_binds_local_p_1 (exp, shlib)
-     tree exp;
-     int shlib;
+default_binds_local_p_1 (tree exp, int shlib)
 {
   bool local_p;
 
@@ -5317,7 +5137,7 @@ default_binds_local_p_1 (exp, shlib)
   else if (! TREE_PUBLIC (exp))
     local_p = true;
   /* A variable is local if the user tells us so.  */
-  else if (decl_visibility (exp) != VISIBILITY_DEFAULT)
+  else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
     local_p = true;
   /* Otherwise, variables defined outside this object may not be local.  */
   else if (DECL_EXTERNAL (exp))
@@ -5346,8 +5166,7 @@ default_binds_local_p_1 (exp, shlib)
 /* Determine whether or not a pointer mode is valid. Assume defaults
    of ptr_mode or Pmode - can be overridden.  */
 bool
-default_valid_pointer_mode (mode)
-     enum machine_mode mode;
+default_valid_pointer_mode (enum machine_mode mode)
 {
   return (mode == ptr_mode || mode == Pmode);
 }
@@ -5357,24 +5176,20 @@ default_valid_pointer_mode (mode)
    globalize a label.  */
 #ifdef GLOBAL_ASM_OP
 void
-default_globalize_label (stream, name)
-     FILE * stream;
-     const char *name;
+default_globalize_label (FILE * stream, const char *name)
 {
   fputs (GLOBAL_ASM_OP, stream);
   assemble_name (stream, name);
   putc ('\n', stream);
 }
 #endif /* GLOBAL_ASM_OP */
-  
+
 /* This is how to output an internal numbered label where PREFIX is
    the class of label and LABELNO is the number within the class.  */
 
 void
-default_internal_label (stream, prefix, labelno)
-     FILE *stream;
-     const char *prefix;
-     unsigned long labelno;
+default_internal_label (FILE *stream, const char *prefix,
+                       unsigned long labelno)
 {
   char *const buf = alloca (40 + strlen (prefix));
   ASM_GENERATE_INTERNAL_LABEL (buf, prefix, labelno);
@@ -5384,7 +5199,7 @@ default_internal_label (stream, prefix, labelno)
 /* This is the default behavior at the beginning of a file.  It's
    controlled by two other target-hook toggles.  */
 void
-default_file_start ()
+default_file_start (void)
 {
   if (targetm.file_start_app_off && !flag_verbose_asm)
     fputs (ASM_APP_OFF, asm_out_file);
@@ -5398,7 +5213,7 @@ default_file_start ()
    not this object file needs an executable stack.  This is primarily
    a GNU extension to ELF but could be used on other targets.  */
 void
-file_end_indicate_exec_stack ()
+file_end_indicate_exec_stack (void)
 {
   unsigned int flags = SECTION_DEBUG;
   if (trampolines_created)