OSDN Git Service

(arm_gen_constant, case IOR,XOR): Don't invert a constant if loading
[pf3gnuchains/gcc-fork.git] / gcc / varasm.c
index 08399f2..a8c15df 100644 (file)
@@ -33,6 +33,7 @@ Boston, MA 02111-1307, USA.  */
 #include "rtl.h"
 #include "tree.h"
 #include "flags.h"
+#include "except.h"
 #include "function.h"
 #include "expr.h"
 #include "output.h"
@@ -224,7 +225,7 @@ readonly_data_section ()
 #endif
 }
 
-/* Determine if we're in the text section. */
+/* Determine if we're in the text section.  */
 
 int
 in_text_section ()
@@ -232,7 +233,7 @@ in_text_section ()
   return in_section == in_text;
 }
 
-/* Determine if we're in the data section. */
+/* Determine if we're in the data section.  */
 
 int
 in_data_section ()
@@ -277,7 +278,7 @@ named_section (decl, name)
 /* Tell the assembler to switch to the bss section.  */
 
 void
-bss_section (decl, name)
+bss_section ()
 {
   if (in_section != in_bss)
     {
@@ -349,7 +350,7 @@ asm_output_aligned_bss (file, decl, name, size, align)
   /* Standard thing is just output label for the object.  */
   ASM_OUTPUT_LABEL (file, name);
 #endif /* ASM_DECLARE_OBJECT_NAME */
-  ASM_OUTPUT_SKIP (file, size);
+  ASM_OUTPUT_SKIP (file, size ? size : 1);
 }
 
 #endif
@@ -414,6 +415,26 @@ variable_section (decl, reloc)
 #endif
     }
 }
+
+/* Tell assembler to switch to the section for the exception handling
+   table.  */
+
+void
+exception_section ()
+{
+#ifdef ASM_OUTPUT_SECTION_NAME
+  named_section (NULL_TREE, ".gcc_except_table");
+#else
+  if (flag_pic)
+    data_section ();
+  else
+#if defined (EXCEPTION_SECTION)
+    EXCEPTION_SECTION ();
+#else
+    readonly_data_section ();
+#endif
+#endif
+}
 \f
 /* Create the rtl to represent a function, for a function definition.
    DECL is a FUNCTION_DECL node which describes which function.
@@ -685,23 +706,13 @@ make_decl_rtl (decl, asmspec, top_level)
                globalize_reg (reg_number + --nregs);
            }
        }
-      /* Specifying a section attribute on an uninitialized variable does not
-        (and cannot) cause it to be put in the given section.  The linker
-        can only put initialized objects in specific sections, everything
-        else goes in bss for the linker to sort out later (otherwise the
-        linker would give a duplicate definition error for each compilation
-        unit that behaved thusly).  So warn the user.  */
+      /* Specifying a section attribute on a variable forces it into a
+         non-.bss section, and thus it cannot be common. */
       else if (TREE_CODE (decl) == VAR_DECL
               && DECL_SECTION_NAME (decl) != NULL_TREE
               && DECL_INITIAL (decl) == NULL_TREE
               && DECL_COMMON (decl))
-       {
-         warning_with_decl (decl,
-                            "section attribute ignored for uninitialized variable `%s'");
-         /* Remove the section name so subsequent declarations won't see it.
-            We are ignoring it, remember.  */
-         DECL_SECTION_NAME (decl) = NULL_TREE;
-       }
+          DECL_COMMON (decl) = 0;
 
       /* Now handle ordinary static variables and functions (in memory).
         Also handle vars declared register invalidly.  */
@@ -955,7 +966,8 @@ assemble_start_function (decl, fnname)
 
   if (TREE_PUBLIC (decl))
     {
-      if (!first_global_object_name)
+      if (!first_global_object_name && ! DECL_WEAK (decl)
+         && ! DECL_ONE_ONLY (decl))
        {
          char *p;
 
@@ -1227,7 +1239,7 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
 
       /* This is better than explicit arithmetic, since it avoids overflow.  */
       size_tree = size_binop (CEIL_DIV_EXPR,
-                         DECL_SIZE (decl), size_int (BITS_PER_UNIT));
+                             DECL_SIZE (decl), size_int (BITS_PER_UNIT));
 
       if (TREE_INT_CST_HIGH (size_tree) != 0)
        {
@@ -1238,6 +1250,20 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
 
   name = XSTR (XEXP (DECL_RTL (decl), 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))
+    {
+      char *p;
+
+      STRIP_NAME_ENCODING (p, name);
+      first_global_object_name = permalloc (strlen (p) + 1);
+      strcpy (first_global_object_name, p);
+    }
+
   /* Handle uninitialized definitions.  */
 
   if ((DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node)
@@ -1366,15 +1392,6 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
   /* First make the assembler name(s) global if appropriate.  */
   if (TREE_PUBLIC (decl) && DECL_NAME (decl))
     {
-      if (!first_global_object_name)
-       {
-         char *p;
-
-         STRIP_NAME_ENCODING (p, name);
-         first_global_object_name = permalloc (strlen (p) + 1);
-         strcpy (first_global_object_name, p);
-       }
-
 #ifdef ASM_WEAKEN_LABEL
       if (DECL_WEAK (decl))
        ASM_WEAKEN_LABEL (asm_out_file, name);
@@ -1563,7 +1580,7 @@ contains_pointers_p (type)
     }
 }
 
-/* Output text storage for constructor CONSTR. */
+/* Output text storage for constructor CONSTR.  */
 
 void
 bc_output_constructor (constr, size)
@@ -1573,7 +1590,7 @@ bc_output_constructor (constr, size)
   int i;
 
   /* Must always be a literal; non-literal constructors are handled
-     differently. */
+     differently.  */
 
   if (!TREE_CONSTANT (constr))
     abort ();
@@ -1592,7 +1609,7 @@ bc_output_constructor (constr, size)
   output_constant (constr, size);
 }
 
-/* Create storage for constructor CONSTR. */
+/* Create storage for constructor CONSTR.  */
 
 void
 bc_output_data_constructor (constr)
@@ -1608,7 +1625,7 @@ bc_output_data_constructor (constr)
   if (i > 0)
     BC_OUTPUT_ALIGN (asm_out_file, i);
 
-  /* The constructor is filled in at runtime. */
+  /* The constructor is filled in at runtime.  */
   BC_OUTPUT_SKIP (asm_out_file, int_size_in_bytes (TREE_TYPE (constr)));
 }
 
@@ -1692,15 +1709,13 @@ assemble_name (file, name)
      char *name;
 {
   char *real_name;
-  int save_warn_id_clash = warn_id_clash;
+  tree id;
 
   STRIP_NAME_ENCODING (real_name, name);
 
-  /* Don't warn about an identifier name length clash on this name, since
-     it can be a user symbol suffixed by a number.  */
-  warn_id_clash = 0;
-  TREE_SYMBOL_REFERENCED (get_identifier (real_name)) = 1;
-  warn_id_clash = save_warn_id_clash;
+  id = maybe_get_identifier (real_name);
+  if (id)
+    TREE_SYMBOL_REFERENCED (id) = 1;
 
   if (name[0] == '*')
     {
@@ -1819,7 +1834,7 @@ assemble_integer (x, size, force)
      int force;
 {
   /* First try to use the standard 1, 2, 4, 8, and 16 byte
-     ASM_OUTPUT... macros. */
+     ASM_OUTPUT... macros.  */
 
   switch (size)
     {
@@ -2263,6 +2278,7 @@ decode_addr_const (exp, value)
     case STRING_CST:
     case COMPLEX_CST:
     case CONSTRUCTOR:
+    case INTEGER_CST:
       x = TREE_CST_RTL (target);
       break;
 
@@ -2329,7 +2345,7 @@ const_hash (exp)
   else if (code == CONSTRUCTOR && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
     {
       len = int_size_in_bytes (TREE_TYPE (exp));
-      p = (char*) alloca (len);
+      p = (char *) alloca (len);
       get_set_constructor_bytes (exp, (unsigned char *) p, len);
     }
   else if (code == CONSTRUCTOR)
@@ -2366,7 +2382,7 @@ const_hash (exp)
          hi = value.offset;
          p = XSTR (value.base, 0);
          for (i = 0; p[i] != 0; i++)
-           hi = ((hi * 613) + (unsigned)(p[i]));
+           hi = ((hi * 613) + (unsigned) (p[i]));
        }
       else if (GET_CODE (value.base) == LABEL_REF)
        hi = value.offset + CODE_LABEL_NUMBER (XEXP (value.base, 0)) * 13;
@@ -2384,7 +2400,7 @@ const_hash (exp)
   /* Compute hashing function */
   hi = len;
   for (i = 0; i < len; i++)
-    hi = ((hi * 613) + (unsigned)(p[i]));
+    hi = ((hi * 613) + (unsigned) (p[i]));
 
   hi &= (1 << HASHBITS) - 1;
   hi %= MAX_HASH_TABLE;
@@ -2460,7 +2476,7 @@ compare_constant_1 (exp, p)
   else if (code == CONSTRUCTOR && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
     {
       int xlen = len = int_size_in_bytes (TREE_TYPE (exp));
-      strp = (char*) alloca (len);
+      strp = (char *) alloca (len);
       get_set_constructor_bytes (exp, (unsigned char *) strp, len);
       if (bcmp ((char *) &xlen, p, sizeof xlen))
        return 0;
@@ -2768,7 +2784,8 @@ copy_constant (exp)
       return copy_node (exp);
 
     case COMPLEX_CST:
-      return build_complex (copy_constant (TREE_REALPART (exp)),
+      return build_complex (TREE_TYPE (exp),
+                           copy_constant (TREE_REALPART (exp)),
                            copy_constant (TREE_IMAGPART (exp)));
 
     case PLUS_EXPR:
@@ -2825,9 +2842,6 @@ output_constant_def (exp)
   int reloc;
   register rtx def;
 
-  if (TREE_CODE (exp) == INTEGER_CST)
-    abort ();                  /* No TREE_CST_RTL slot in these.  */
-
   if (TREE_CST_RTL (exp))
     return TREE_CST_RTL (exp);
 
@@ -3113,7 +3127,7 @@ decode_rtx_const (mode, x, value)
       *p++ = 0;
   }
 
-  value->kind = RTX_INT;       /* Most usual kind. */
+  value->kind = RTX_INT;       /* Most usual kind.  */
   value->mode = mode;
 
   switch (GET_CODE (x))
@@ -3342,7 +3356,7 @@ force_const_mem (mode, x)
         copy of X that is in the saveable obstack in case we are being
         called from combine or some other phase that discards memory
         it allocates.  We need only do this if it is a CONST, since
-        no other RTX should be allocated in this situation. */
+        no other RTX should be allocated in this situation.  */
       if (rtl_obstack != saveable_obstack
          && GET_CODE (x) == CONST)
        {
@@ -3737,7 +3751,7 @@ output_constant (exp, size)
     assemble_zeros (size);
 }
 
-/* Bytecode specific code to output assembler for integer. */
+/* Bytecode specific code to output assembler for integer.  */
 
 static void
 bc_assemble_integer (exp, size)
@@ -4123,6 +4137,7 @@ output_constructor (exp, size)
 }
 
 /* Output asm to handle ``#pragma weak'' */
+
 void
 handle_pragma_weak (what, name, value)
      enum pragma_state what;
@@ -4190,12 +4205,12 @@ void
 assemble_alias (decl, target)
      tree decl, target;
 {
-#ifdef ASM_OUTPUT_DEF
   char *name;
 
-  make_decl_rtl (decl, (char*)0, 1);
+  make_decl_rtl (decl, (char *) 0, 1);
   name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
 
+#ifdef ASM_OUTPUT_DEF
   /* Make name accessible from other files, if appropriate.  */
 
   if (TREE_PUBLIC (decl))
@@ -4214,6 +4229,64 @@ assemble_alias (decl, target)
   ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
   TREE_ASM_WRITTEN (decl) = 1;
 #else
-  warning ("alias definitions not supported in this configuration");
+#ifdef ASM_OUTPUT_WEAK_ALIAS
+  if (! DECL_WEAK (decl))
+    warning ("only weak aliases are supported in this configuration");
+
+  ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
+  TREE_ASM_WRITTEN (decl) = 1;
+#else
+  warning ("alias definitions not supported in this configuration; ignored");
+#endif
+#endif
+}
+
+/* This determines whether or not we support link-once semantics.  */
+#ifndef SUPPORTS_ONE_ONLY
+#ifdef MAKE_DECL_ONE_ONLY
+#define SUPPORTS_ONE_ONLY 1
+#else
+#define SUPPORTS_ONE_ONLY 0
+#endif
+#endif
+
+/* Returns 1 if the target configuration supports defining public symbols
+   so that one of them will be chosen at link time instead of generating a
+   multiply-defined symbol error, whether through the use of weak symbols or
+   a target-specific mechanism for having duplicates discarded.  */
+
+int
+supports_one_only ()
+{
+  if (SUPPORTS_ONE_ONLY)
+    return 1;
+  return SUPPORTS_WEAK;
+}
+
+/* Set up DECL as a public symbol that can be defined in multiple
+   translation units without generating a linker error.  */
+
+void
+make_decl_one_only (decl)
+     tree decl;
+{
+  if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
+    abort ();
+
+  TREE_PUBLIC (decl) = 1;
+
+  if (TREE_CODE (decl) == VAR_DECL
+      && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
+    DECL_COMMON (decl) = 1;
+  else if (SUPPORTS_ONE_ONLY)
+    {
+#ifdef MAKE_DECL_ONE_ONLY
+      MAKE_DECL_ONE_ONLY (decl);
 #endif
+      DECL_ONE_ONLY (decl) = 1;
+    }
+  else if (SUPPORTS_WEAK)
+    DECL_WEAK (decl) = 1;
+  else
+    abort ();
 }