OSDN Git Service

2012-02-14 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / varasm.c
index b354846..8613467 100644 (file)
@@ -1198,16 +1198,23 @@ make_decl_rtl (tree decl)
   else if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
     {
       const char *asmspec = name+1;
+      enum machine_mode mode = DECL_MODE (decl);
       reg_number = decode_reg_name (asmspec);
       /* First detect errors in declaring global registers.  */
       if (reg_number == -1)
        error ("register name not specified for %q+D", decl);
       else if (reg_number < 0)
        error ("invalid register name for %q+D", decl);
-      else if (TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
+      else if (mode == BLKmode)
        error ("data type of %q+D isn%'t suitable for a register",
               decl);
-      else if (! HARD_REGNO_MODE_OK (reg_number, TYPE_MODE (TREE_TYPE (decl))))
+      else if (!in_hard_reg_set_p (accessible_reg_set, mode, reg_number))
+       error ("the register specified for %q+D cannot be accessed"
+              " by the current target", decl);
+      else if (!in_hard_reg_set_p (operand_reg_set, mode, reg_number))
+       error ("the register specified for %q+D is not general enough"
+              " to be used as a register variable", decl);
+      else if (!HARD_REGNO_MODE_OK (reg_number, mode))
        error ("register specified for %q+D isn%'t suitable for data type",
                decl);
       /* Now handle properly declared static register variables.  */
@@ -1230,7 +1237,7 @@ make_decl_rtl (tree decl)
             confused with that register and be eliminated.  This usage is
             somewhat suspect...  */
 
-         SET_DECL_RTL (decl, gen_rtx_raw_REG (DECL_MODE (decl), reg_number));
+         SET_DECL_RTL (decl, gen_rtx_raw_REG (mode, reg_number));
          ORIGINAL_REGNO (DECL_RTL (decl)) = reg_number;
          REG_USERVAR_P (DECL_RTL (decl)) = 1;
 
@@ -1242,7 +1249,7 @@ make_decl_rtl (tree decl)
              name = IDENTIFIER_POINTER (DECL_NAME (decl));
              ASM_DECLARE_REGISTER_GLOBAL (asm_out_file, decl, reg_number, name);
 #endif
-             nregs = hard_regno_nregs[reg_number][DECL_MODE (decl)];
+             nregs = hard_regno_nregs[reg_number][mode];
              while (nregs > 0)
                globalize_reg (decl, reg_number + --nregs);
            }
@@ -2109,7 +2116,9 @@ incorporeal_function_p (tree decl)
        return true;
 
       name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-      if (is_builtin_name (name))
+      /* Atomic or sync builtins which have survived this far will be
+        resolved externally and therefore are not incorporeal.  */
+      if (strncmp (name, "__builtin_", 10) == 0)
        return true;
     }
   return false;
@@ -5785,14 +5794,11 @@ void
 assemble_alias (tree decl, tree target)
 {
   tree target_decl;
-  bool is_weakref = false;
 
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
     {
       tree alias = DECL_ASSEMBLER_NAME (decl);
 
-      is_weakref = true;
-
       ultimate_transparent_alias_target (&target);
 
       if (alias == target)
@@ -5830,12 +5836,6 @@ assemble_alias (tree decl, tree target)
     }
   TREE_USED (decl) = 1;
 
-  /* A quirk of the initial implementation of aliases required that the user
-     add "extern" to all of them.  Which is silly, but now historical.  Do
-     note that the symbol is in fact locally defined.  */
-  if (! is_weakref)
-    DECL_EXTERNAL (decl) = 0;
-
   /* Allow aliases to aliases.  */
   if (TREE_CODE (decl) == FUNCTION_DECL)
     cgraph_get_create_node (decl)->alias = true;
@@ -5961,7 +5961,7 @@ dump_tm_clone_pairs (VEC(tm_alias_pair,heap) *tm_alias_pairs)
 
       if (!switched)
        {
-         switch_to_section (get_named_section (NULL, ".tm_clone_table", 3));
+         switch_to_section (targetm.asm_out.tm_clone_table_section ());
          assemble_align (POINTER_SIZE);
          switched = true;
        }
@@ -5973,6 +5973,14 @@ dump_tm_clone_pairs (VEC(tm_alias_pair,heap) *tm_alias_pairs)
     }
 }
 
+/* Provide a default for the tm_clone_table section.  */
+
+section *
+default_clone_table_section (void)
+{
+  return get_named_section (NULL, ".tm_clone_table", 3);
+}
+
 /* Helper comparison function for qsorting by the DECL_UID stored in
    alias_pair->emitted_diags.  */
 
@@ -6903,11 +6911,14 @@ default_binds_local_p_1 (const_tree exp, int shlib)
   /* A non-decl is an entry in the constant pool.  */
   if (!DECL_P (exp))
     local_p = true;
-  /* Weakrefs may not bind locally, even though the weakref itself is
-     always static and therefore local.
-     FIXME: We can resolve this more curefuly by looking at the weakref
-     alias.  */
-  else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp)))
+  /* Weakrefs may not bind locally, even though the weakref itself is always
+     static and therefore local.  Similarly, the resolver for ifunc functions
+     might resolve to a non-local function.
+     FIXME: We can resolve the weakref case more curefuly by looking at the
+     weakref alias.  */
+  else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
+          || (TREE_CODE (exp) == FUNCTION_DECL
+              && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp))))
     local_p = false;
   /* Static variables are always local.  */
   else if (! TREE_PUBLIC (exp))
@@ -7528,7 +7539,8 @@ default_elf_asm_output_limited_string (FILE *f, const char *s)
   int escape;
   unsigned char c;
 
-  fputs ("\t.string\t\"", f);
+  fputs (STRING_ASM_OP, f);
+  putc ('"', f);
   while (*s != '\0')
     {
       c = *s;
@@ -7632,19 +7644,6 @@ default_elf_asm_output_ascii (FILE *f, const char *s, unsigned int len)
 }
 #endif
 
-/* Default TARGET_ASM_INTERNAL_LABEL for ELF targets.  */
-
-void
-default_elf_internal_label (FILE *f, const char *prefix,
-                           unsigned long labelno)
-{
-  putc ('.', f);
-  fputs (prefix, f);
-  fprint_ul (f, labelno);
-  putc (':', f);
-  putc ('\n', f);
-}
-
 static GTY(()) section *elf_init_array_section;
 static GTY(()) section *elf_fini_array_section;