diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-05-30 00:28:14 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-05-30 00:28:14 +0000 |
commit | a4d618bfc0e29d8a1d3c347b6332d023a11812b9 (patch) | |
tree | 9dafc5b96a11a677d8b1e4d4bef754e0501242b3 /gcc/config | |
parent | 1f2fe497158b7f8eb1d5b4b33c30d2f7933c774c (diff) | |
download | gcc-a4d618bfc0e29d8a1d3c347b6332d023a11812b9.tar.gz |
* config/i386/i386.c (USE_HIDDEN_LINKONCE): New.
(get_pc_thunk_name): New.
(output_set_got): Use it.
(ix86_asm_file_end): If USE_HIDDEN_LINKONCE, emit get_pc thunks
into linkonce sections.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@54031 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/i386/i386.c | 63 |
1 files changed, 52 insertions, 11 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index bea81e807ed..1715ca02a21 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -672,6 +672,7 @@ static rtx ix86_expand_int_compare PARAMS ((enum rtx_code, rtx, rtx)); static enum rtx_code ix86_prepare_fp_compare_args PARAMS ((enum rtx_code, rtx *, rtx *)); static rtx get_thread_pointer PARAMS ((void)); +static void get_pc_thunk_name PARAMS ((char [32], unsigned int)); static rtx gen_push PARAMS ((rtx)); static int memory_address_length PARAMS ((rtx addr)); static int ix86_flags_dependant PARAMS ((rtx, rtx, enum attr_type)); @@ -3898,8 +3899,29 @@ ix86_setup_frame_addresses () cfun->machine->accesses_prev_frame = 1; } +#if defined(HAVE_GAS_HIDDEN) && defined(SUPPORTS_ONE_ONLY) +# define USE_HIDDEN_LINKONCE 1 +#else +# define USE_HIDDEN_LINKONCE 0 +#endif + static int pic_labels_used; +/* Fills in the label name that should be used for a pc thunk for + the given register. */ + +static void +get_pc_thunk_name (name, regno) + char name[32]; + unsigned int regno; +{ + if (USE_HIDDEN_LINKONCE) + sprintf (name, "__i686.get_pc_thunk.%s", reg_names[regno]); + else + ASM_GENERATE_INTERNAL_LABEL (name, "LPR", regno); +} + + /* This function generates code for -fpic that loads %ebx with the return address of the caller and then returns. */ @@ -3912,18 +3934,37 @@ ix86_asm_file_end (file) for (regno = 0; regno < 8; ++regno) { + char name[32]; + if (! ((pic_labels_used >> regno) & 1)) continue; - text_section (); + get_pc_thunk_name (name, regno); + + if (USE_HIDDEN_LINKONCE) + { + tree decl; + + decl = build_decl (FUNCTION_DECL, get_identifier (name), + error_mark_node); + TREE_PUBLIC (decl) = 1; + TREE_STATIC (decl) = 1; + DECL_ONE_ONLY (decl) = 1; - /* This used to call ASM_DECLARE_FUNCTION_NAME() but since it's an - internal (non-global) label that's being emitted, it didn't make - sense to have .type information for local labels. This caused - the SCO OpenServer 5.0.4 ELF assembler grief (why are you giving - me debug info for a label that you're declaring non-global?) this - was changed to call ASM_OUTPUT_LABEL() instead. */ - ASM_OUTPUT_INTERNAL_LABEL (file, "LPR", regno); + (*targetm.asm_out.unique_section) (decl, 0); + named_section (decl, NULL, 0); + + ASM_GLOBALIZE_LABEL (file, name); + fputs ("\t.hidden\t", file); + assemble_name (file, name); + fputc ('\n', file); + ASM_DECLARE_FUNCTION_NAME (file, name, decl); + } + else + { + text_section (); + ASM_OUTPUT_LABEL (file, name); + } xops[0] = gen_rtx_REG (SImode, regno); xops[1] = gen_rtx_MEM (SImode, stack_pointer_rtx); @@ -3960,11 +4001,11 @@ output_set_got (dest) } else { - char pic_label_name[32]; - ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", REGNO (dest)); + char name[32]; + get_pc_thunk_name (name, REGNO (dest)); pic_labels_used |= 1 << REGNO (dest); - xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (pic_label_name)); + xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name)); xops[2] = gen_rtx_MEM (QImode, xops[2]); output_asm_insn ("call\t%X2", xops); } |