aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/config/sparc/sparc.c114
2 files changed, 98 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 02be2ca..45a4634 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+2010-03-19 David S. Miller <davem@davemloft.net>
+
+ With help from Eric Botcazou.
+ * config/sparc/sparc.c: Include dwarf2out.h.
+ (emit_pic_helper): Delete.
+ (pic_helper_symbol_name): Delete.
+ (pic_helper_emitted_p): Delete.
+ (pic_helper_needed): New.
+ (USE_HIDDEN_LINKONCE): Define to '1' if HAVE_GAS_HIDDEN else '0'.
+ (get_pc_thunk_name): New.
+ (load_pic_register): Remove 'delay_pic_helper' arg. Use
+ get_thunk_pc_name and ggc_strdup to generate PIC thunk symbol.
+ Set pic_helper_needed to true. Don't call emit_pic_helper.
+ (sparc_expand_prologue): Update load_pic_register call.
+ (sparc_output_mi_thunk): Likewise.
+ (sparc_file_end): Emit a hidden comdat symbol for the PIC
+ thunk if possible. Output CFI information as needed.
+
2010-03-11 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
Jack Howarth <howarth@bromo.med.uc.edu>
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index e4ef862..38711d3 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "params.h"
#include "df.h"
+#include "dwarf2out.h"
/* Processor costs */
static const
@@ -362,8 +363,7 @@ static rtx sparc_builtin_saveregs (void);
static int epilogue_renumber (rtx *, int);
static bool sparc_assemble_integer (rtx, unsigned int, int);
static int set_extends (rtx);
-static void emit_pic_helper (void);
-static void load_pic_register (bool);
+static void load_pic_register (void);
static int save_or_restore_regs (int, int, rtx, int, int);
static void emit_save_or_restore_regs (int);
static void sparc_asm_function_prologue (FILE *, HOST_WIDE_INT);
@@ -2908,9 +2908,8 @@ sparc_cannot_force_const_mem (rtx x)
}
/* PIC support. */
-static GTY(()) char pic_helper_symbol_name[256];
+static GTY(()) bool pic_helper_needed = false;
static GTY(()) rtx pic_helper_symbol;
-static GTY(()) bool pic_helper_emitted_p = false;
static GTY(()) rtx global_offset_table;
/* Ensure that we are not using patterns that are not OK with PIC. */
@@ -3521,34 +3520,31 @@ sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
return x;
}
-/* Emit the special PIC helper function. */
+#ifdef HAVE_GAS_HIDDEN
+# define USE_HIDDEN_LINKONCE 1
+#else
+# define USE_HIDDEN_LINKONCE 0
+#endif
static void
-emit_pic_helper (void)
+get_pc_thunk_name (char name[32], unsigned int regno)
{
- const char *pic_name = reg_names[REGNO (pic_offset_table_rtx)];
- int align;
+ const char *pic_name = reg_names[regno];
- switch_to_section (text_section);
+ /* Skip the leading '%' as that cannot be used in a
+ symbol name. */
+ pic_name += 1;
- align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
- if (align > 0)
- ASM_OUTPUT_ALIGN (asm_out_file, align);
- ASM_OUTPUT_LABEL (asm_out_file, pic_helper_symbol_name);
- if (flag_delayed_branch)
- fprintf (asm_out_file, "\tjmp\t%%o7+8\n\t add\t%%o7, %s, %s\n",
- pic_name, pic_name);
+ if (USE_HIDDEN_LINKONCE)
+ sprintf (name, "__sparc_get_pc_thunk.%s", pic_name);
else
- fprintf (asm_out_file, "\tadd\t%%o7, %s, %s\n\tjmp\t%%o7+8\n\t nop\n",
- pic_name, pic_name);
-
- pic_helper_emitted_p = true;
+ ASM_GENERATE_INTERNAL_LABEL (name, "LADDPC", regno);
}
/* Emit code to load the PIC register. */
static void
-load_pic_register (bool delay_pic_helper)
+load_pic_register (void)
{
int orig_flag_pic = flag_pic;
@@ -3560,18 +3556,18 @@ load_pic_register (bool delay_pic_helper)
}
/* If we haven't initialized the special PIC symbols, do so now. */
- if (!pic_helper_symbol_name[0])
+ if (!pic_helper_needed)
{
- ASM_GENERATE_INTERNAL_LABEL (pic_helper_symbol_name, "LADDPC", 0);
- pic_helper_symbol = gen_rtx_SYMBOL_REF (Pmode, pic_helper_symbol_name);
+ char name[32];
+
+ pic_helper_needed = true;
+
+ get_pc_thunk_name (name, REGNO (pic_offset_table_rtx));
+ pic_helper_symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
+
global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
}
- /* If we haven't emitted the special PIC helper function, do so now unless
- we are requested to delay it. */
- if (!delay_pic_helper && !pic_helper_emitted_p)
- emit_pic_helper ();
-
flag_pic = 0;
if (TARGET_ARCH64)
emit_insn (gen_load_pcrel_symdi (pic_offset_table_rtx, global_offset_table,
@@ -4221,7 +4217,7 @@ sparc_expand_prologue (void)
/* Load the PIC register if needed. */
if (flag_pic && crtl->uses_pic_offset_table)
- load_pic_register (false);
+ load_pic_register ();
}
/* This function generates the assembly code for function entry, which boils
@@ -8882,7 +8878,7 @@ sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
start_sequence ();
/* Delay emitting the PIC helper function because it needs to
change the section and we are emitting assembly code. */
- load_pic_register (true); /* clobbers %o7 */
+ load_pic_register (); /* clobbers %o7 */
scratch = legitimize_pic_address (funexp, scratch);
seq = get_insns ();
end_sequence ();
@@ -9037,9 +9033,59 @@ sparc_output_dwarf_dtprel (FILE *file, int size, rtx x)
static void
sparc_file_end (void)
{
- /* If we haven't emitted the special PIC helper function, do so now. */
- if (pic_helper_symbol_name[0] && !pic_helper_emitted_p)
- emit_pic_helper ();
+ /* If need to emit the special PIC helper function, do so now. */
+ if (pic_helper_needed)
+ {
+ unsigned int regno = REGNO (pic_offset_table_rtx);
+ const char *pic_name = reg_names[regno];
+ char name[32];
+#ifdef DWARF2_UNWIND_INFO
+ bool do_cfi;
+#endif
+
+ get_pc_thunk_name (name, regno);
+ if (USE_HIDDEN_LINKONCE)
+ {
+ tree decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
+ get_identifier (name),
+ build_function_type (void_type_node,
+ void_list_node));
+ DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
+ NULL_TREE, void_type_node);
+ TREE_STATIC (decl) = 1;
+ make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ DECL_VISIBILITY_SPECIFIED (decl) = 1;
+ allocate_struct_function (decl, true);
+ current_function_decl = decl;
+ init_varasm_status ();
+ assemble_start_function (decl, name);
+ }
+ else
+ {
+ const int align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
+ switch_to_section (text_section);
+ if (align > 0)
+ ASM_OUTPUT_ALIGN (asm_out_file, align);
+ ASM_OUTPUT_LABEL (asm_out_file, name);
+ }
+
+#ifdef DWARF2_UNWIND_INFO
+ do_cfi = dwarf2out_do_cfi_asm ();
+ if (do_cfi)
+ fprintf (asm_out_file, "\t.cfi_startproc\n");
+#endif
+ if (flag_delayed_branch)
+ fprintf (asm_out_file, "\tjmp\t%%o7+8\n\t add\t%%o7, %s, %s\n",
+ pic_name, pic_name);
+ else
+ fprintf (asm_out_file, "\tadd\t%%o7, %s, %s\n\tjmp\t%%o7+8\n\t nop\n",
+ pic_name, pic_name);
+#ifdef DWARF2_UNWIND_INFO
+ if (do_cfi)
+ fprintf (asm_out_file, "\t.cfi_endproc\n");
+#endif
+ }
if (NEED_INDICATE_EXEC_STACK)
file_end_indicate_exec_stack ();