diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-06-23 20:52:14 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-06-23 20:52:14 +0000 |
commit | d7bec69564aeb974895eb7c9f882fd0563fc5145 (patch) | |
tree | d7c9b0e8e53eafd5f6f0295ca3b1bf6241af32c5 /gcc | |
parent | 36bbd884655900e4ac3ebe9303e8a049ec81b9bc (diff) | |
download | gcc-d7bec69564aeb974895eb7c9f882fd0563fc5145.tar.gz |
* config/i386/i386.c (x86_output_mi_thunk): Don't pass MEM to %P0,
just SYMBOL_REF.
* config/s390/s390.c (s390_output_mi_thunk): Avoid .plt in -m31
mode, as it requires pic register loaded.
* varasm.c (resolve_unique_section): Remove prototype. No longer
static.
* tree.h (resolve_unique_section): New prototype.
cp/
* method.c (thunk_labelno): New variable.
(make_alias_for_thunk): New function.
(use_thunk): Use it if defined ASM_OUTPUT_DEF. Put the thunk
into the same section as the function it is calling.
Include gt-cp-method.h.
* Make-lang.in (gt-cp-method.h): Depend on s-gtype.
(cp/method.o): Depend on gt-cp-method.h.
* config-lang.in (gtfiles): Add $(srcdir)/cp/method.c.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@68389 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 5 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 37 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/Make-lang.in | 4 | ||||
-rw-r--r-- | gcc/cp/config-lang.in | 2 | ||||
-rw-r--r-- | gcc/cp/method.c | 78 | ||||
-rw-r--r-- | gcc/tree.h | 1 | ||||
-rw-r--r-- | gcc/varasm.c | 3 |
9 files changed, 137 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 727e1f5657b..bb5a5ec1f60 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2003-06-23 Jakub Jelinek <jakub@redhat.com> + + * config/i386/i386.c (x86_output_mi_thunk): Don't pass MEM to %P0, + just SYMBOL_REF. + * config/s390/s390.c (s390_output_mi_thunk): Avoid .plt in -m31 + mode, as it requires pic register loaded. + + * varasm.c (resolve_unique_section): Remove prototype. No longer + static. + * tree.h (resolve_unique_section): New prototype. + 2003-06-23 Andreas Schwab <schwab@suse.de> PR debug/9905 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 479c4c91435..f08e80cd949 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -15496,15 +15496,14 @@ x86_output_mi_thunk (file, thunk, delta, vcall_offset, function) output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops); } - xops[0] = DECL_RTL (function); + xops[0] = XEXP (DECL_RTL (function), 0); if (TARGET_64BIT) { if (!flag_pic || (*targetm.binds_local_p) (function)) output_asm_insn ("jmp\t%P0", xops); else { - tmp = XEXP (xops[0], 0); - tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, tmp), UNSPEC_GOTPCREL); + tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, xops[0]), UNSPEC_GOTPCREL); tmp = gen_rtx_CONST (Pmode, tmp); tmp = gen_rtx_MEM (QImode, tmp); xops[0] = tmp; diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 9ca394f8dd6..4f0dd02542c 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -6480,13 +6480,16 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function) HOST_WIDE_INT vcall_offset; tree function; { - rtx op[9]; + rtx op[10]; + int nonlocal = 0; /* Operand 0 is the target function. */ op[0] = XEXP (DECL_RTL (function), 0); if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0])) { - op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]), 113); + nonlocal = 1; + op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]), + TARGET_64BIT ? 113 : flag_pic == 2 ? 112 : 110); op[0] = gen_rtx_CONST (Pmode, op[0]); } @@ -6511,6 +6514,9 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function) op[7] = NULL_RTX; op[8] = NULL_RTX; + /* Operand 9 can be used for temporary register. */ + op[9] = NULL_RTX; + /* Generate code. */ if (TARGET_64BIT) { @@ -6641,14 +6647,39 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function) /* Jump to target. */ op[8] = gen_label_rtx (); + if (!flag_pic) output_asm_insn ("l\t%4,%8-%5(%4)", op); - else + else if (!nonlocal) output_asm_insn ("a\t%4,%8-%5(%4)", op); + /* We cannot call through .plt, since .plt requires %r12 loaded. */ + else if (flag_pic == 1) + { + output_asm_insn ("a\t%4,%8-%5(%4)", op); + output_asm_insn ("l\t%4,%0(%4)", op); + } + else if (flag_pic == 2) + { + op[9] = gen_rtx_REG (Pmode, 0); + output_asm_insn ("l\t%9,%8-4-%5(%4)", op); + output_asm_insn ("a\t%4,%8-%5(%4)", op); + output_asm_insn ("ar\t%4,%9", op); + output_asm_insn ("l\t%4,0(%4)", op); + } + output_asm_insn ("br\t%4", op); /* Output literal pool. */ output_asm_insn (".align\t4", op); + + if (nonlocal && flag_pic == 2) + output_asm_insn (".long\t%0", op); + if (nonlocal) + { + op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); + SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL; + } + (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (op[8])); if (!flag_pic) output_asm_insn (".long\t%0", op); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 641b4a29863..ee9027446b8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2003-06-23 Jakub Jelinek <jakub@redhat.com> + + * method.c (thunk_labelno): New variable. + (make_alias_for_thunk): New function. + (use_thunk): Use it if defined ASM_OUTPUT_DEF. Put the thunk + into the same section as the function it is calling. + Include gt-cp-method.h. + * Make-lang.in (gt-cp-method.h): Depend on s-gtype. + (cp/method.o): Depend on gt-cp-method.h. + * config-lang.in (gtfiles): Add $(srcdir)/cp/method.c. + Mon Jun 23 19:41:27 CEST 2003 Jan Hubicka <jh@suse.cz> * decl.c (register_dtor_fn): Mark cleanup as used. diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index ddada02bd6b..e340987c08f 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -103,7 +103,7 @@ $(srcdir)/cp/cfns.h: $(srcdir)/cp/cfns.gperf $(srcdir)/cp/cfns.gperf > $(srcdir)/cp/cfns.h gtype-cp.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h : s-gtype; @true -gt-cp-pt.h gt-cp-repo.h gt-cp-parser.h : s-gtype; @true +gt-cp-pt.h gt-cp-repo.h gt-cp-parser.h gt-cp-method.h : s-gtype; @true gt-cp-tree.h gt-cp-mangle.h gt-cp-name-lookup.h: s-gtype; @true # @@ -253,7 +253,7 @@ cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) toplev.h $(EXPR_ cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \ except.h cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h $(RTL_H) $(EXPR_H) \ - $(TM_P_H) $(TARGET_H) + $(TM_P_H) $(TARGET_H) gt-cp-method.h cp/cvt.o: cp/cvt.c $(CXX_TREE_H) $(TM_H) cp/decl.h flags.h toplev.h convert.h cp/search.o: cp/search.c $(CXX_TREE_H) $(TM_H) stack.h flags.h toplev.h $(RTL_H) cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) \ diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in index 2927606c12c..8ba5506e8fb 100644 --- a/gcc/cp/config-lang.in +++ b/gcc/cp/config-lang.in @@ -34,4 +34,4 @@ stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)" target_libs="target-libstdc++-v3 target-gperf" -gtfiles="\$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c" +gtfiles="\$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c" diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 2a08f70305b..9e00fff70c0 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -351,6 +351,53 @@ thunk_adjust (tree ptr, bool this_adjusting, return ptr; } +static GTY (()) int thunk_labelno; + +/* Create a static alias to function. */ + +static tree +make_alias_for_thunk (tree function) +{ + tree alias; + char buf[256]; + + ASM_GENERATE_INTERNAL_LABEL (buf, "LTHUNK", thunk_labelno); + thunk_labelno++; + alias = build_decl (FUNCTION_DECL, get_identifier (buf), + TREE_TYPE (function)); + DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (function); + cxx_dup_lang_specific_decl (alias); + DECL_CONTEXT (alias) = NULL; + TREE_READONLY (alias) = TREE_READONLY (function); + TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (function); + TREE_PUBLIC (alias) = 0; + DECL_INTERFACE_KNOWN (alias) = 1; + DECL_NOT_REALLY_EXTERN (alias) = 1; + DECL_THIS_STATIC (alias) = 1; + DECL_SAVED_FUNCTION_DATA (alias) = NULL; + DECL_DESTRUCTOR_P (alias) = 0; + DECL_CONSTRUCTOR_P (alias) = 0; + DECL_CLONED_FUNCTION (alias) = NULL_TREE; + DECL_EXTERNAL (alias) = 0; + DECL_ARTIFICIAL (alias) = 1; + DECL_NO_STATIC_CHAIN (alias) = 1; + DECL_PENDING_INLINE_P (alias) = 0; + DECL_INLINE (alias) = 0; + DECL_DECLARED_INLINE_P (alias) = 0; + DECL_DEFERRED_FN (alias) = 0; + DECL_USE_TEMPLATE (alias) = 0; + DECL_TEMPLATE_INSTANTIATED (alias) = 0; + DECL_TEMPLATE_INFO (alias) = NULL; + DECL_INITIAL (alias) = error_mark_node; + TREE_ADDRESSABLE (alias) = 1; + TREE_USED (alias) = 1; + SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias)); + TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1; + if (!flag_syntax_only) + assemble_alias (alias, DECL_ASSEMBLER_NAME (function)); + return alias; +} + /* Emit the definition of a C++ multiple inheritance or covariant return vtable thunk. If EMIT_P is nonzero, the thunk is emitted immediately. */ @@ -358,7 +405,7 @@ thunk_adjust (tree ptr, bool this_adjusting, void use_thunk (tree thunk_fndecl, bool emit_p) { - tree function; + tree function, alias; tree virtual_offset; HOST_WIDE_INT fixed_offset, virtual_value; bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl); @@ -386,6 +433,12 @@ use_thunk (tree thunk_fndecl, bool emit_p) if (!emit_p) return; +#ifdef ASM_OUTPUT_DEF + alias = make_alias_for_thunk (function); +#else + alias = function; +#endif + fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl); virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl); @@ -415,6 +468,21 @@ use_thunk (tree thunk_fndecl, bool emit_p) push_to_top_level (); +#ifdef ASM_OUTPUT_DEF + if (targetm.have_named_sections) + { + resolve_unique_section (function, 0, flag_function_sections); + + if (DECL_SECTION_NAME (function) != NULL && DECL_ONE_ONLY (function)) + { + resolve_unique_section (thunk_fndecl, 0, flag_function_sections); + + /* Output the thunk into the same section as function. */ + DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function); + } + } +#endif + /* The back-end expects DECL_INITIAL to contain a BLOCK, so we create one. */ DECL_INITIAL (thunk_fndecl) = make_node (BLOCK); @@ -422,7 +490,7 @@ use_thunk (tree thunk_fndecl, bool emit_p) if (this_adjusting && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset, - virtual_value, function)) + virtual_value, alias)) { const char *fnname; current_function_decl = thunk_fndecl; @@ -434,7 +502,7 @@ use_thunk (tree thunk_fndecl, bool emit_p) assemble_start_function (thunk_fndecl, fnname); targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl, - fixed_offset, virtual_value, function); + fixed_offset, virtual_value, alias); assemble_end_function (thunk_fndecl, fnname); current_function_decl = 0; @@ -486,7 +554,7 @@ use_thunk (tree thunk_fndecl, bool emit_p) for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a)) t = tree_cons (NULL_TREE, a, t); t = nreverse (t); - t = build_call (function, t); + t = build_call (alias, t); if (!this_adjusting) t = thunk_adjust (t, /*this_adjusting=*/0, fixed_offset, virtual_offset); @@ -1054,3 +1122,5 @@ skip_artificial_parms_for (tree fn, tree list) list = TREE_CHAIN (list); return list; } + +#include "gt-cp-method.h" diff --git a/gcc/tree.h b/gcc/tree.h index 26c79a8489b..93065c5f2fe 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2907,6 +2907,7 @@ extern int supports_one_only PARAMS ((void)); extern void variable_section PARAMS ((tree, int)); enum tls_model decl_tls_model PARAMS ((tree)); enum symbol_visibility decl_visibility PARAMS ((tree)); +extern void resolve_unique_section PARAMS ((tree, int, int)); /* In stmt.c */ extern void emit_nop PARAMS ((void)); diff --git a/gcc/varasm.c b/gcc/varasm.c index a76d23ae1cb..091bbb31209 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -183,7 +183,6 @@ static void asm_output_aligned_bss static bool asm_emit_uninitialised PARAMS ((tree, const char*, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT)); -static void resolve_unique_section PARAMS ((tree, int, int)); static void mark_weak PARAMS ((tree)); enum in_section { no_section, in_text, in_data, in_named @@ -460,7 +459,7 @@ named_section (decl, name, reloc) /* If required, set DECL_SECTION_NAME to a unique name. */ -static void +void resolve_unique_section (decl, reloc, flag_function_or_data_sections) tree decl; int reloc ATTRIBUTE_UNUSED; |