From 878ee0ab0f556ba94f653d1352717d398e16a4ec Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 21 Feb 2010 03:58:51 +0000 Subject: [PATCH] configure.ac: Test if linker and assembler properly support GOTDATA_OP relocations. gcc/ 2010-02-20 David S. Miller * configure.ac: Test if linker and assembler properly support GOTDATA_OP relocations. * configure: Rebuild. * config.in: Likewise. * config/sparc/sparc.md (UNSPEC_MOVE_GOTDATA): New. (movsi_lo_sum_pic): Use %gdop_*() relocs if available. (movsi_high_pic): Likewise. (movdi_lo_sum_pic): Likewise. (movdi_high_pic): Likewise. (movsi_pic_gotdata_op): New pattern. (movdi_pic_gotdata_op): Likewise. * config/sparc/sparc.c (legitimize_pic_address): If flag_pic is 2, emit gen_mov{si,di}_pic_gotdata_op for the GOT slot load. From-SVN: r156933 --- gcc/ChangeLog | 16 ++++++++++ gcc/config.in | 6 ++++ gcc/config/sparc/sparc.c | 23 +++++++++++--- gcc/config/sparc/sparc.md | 63 ++++++++++++++++++++++++++++++++++++--- gcc/configure | 45 ++++++++++++++++++++++++++++ gcc/configure.ac | 22 ++++++++++++++ 6 files changed, 167 insertions(+), 8 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 105023b0f6e..8975aea4f16 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2010-02-20 David S. Miller + + * configure.ac: Test if linker and assembler properly support + GOTDATA_OP relocations. + * configure: Rebuild. + * config.in: Likewise. + * config/sparc/sparc.md (UNSPEC_MOVE_GOTDATA): New. + (movsi_lo_sum_pic): Use %gdop_*() relocs if available. + (movsi_high_pic): Likewise. + (movdi_lo_sum_pic): Likewise. + (movdi_high_pic): Likewise. + (movsi_pic_gotdata_op): New pattern. + (movdi_pic_gotdata_op): Likewise. + * config/sparc/sparc.c (legitimize_pic_address): If flag_pic is 2, + emit gen_mov{si,di}_pic_gotdata_op for the GOT slot load. + 2010-02-20 Uros Bizjak PR target/43067 diff --git a/gcc/config.in b/gcc/config.in index a3744f99dcb..98dffa73b2c 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -417,6 +417,12 @@ #endif +/* Define if your assembler and linker support GOTDATA_OP relocs. */ +#ifndef USED_FOR_TARGET +#undef HAVE_AS_SPARC_GOTDATA_OP +#endif + + /* Define if your assembler and linker support unaligned PC relative relocs. */ #ifndef USED_FOR_TARGET diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index f366f78aaa9..c45460db4db 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -3374,6 +3374,8 @@ legitimize_tls_address (rtx addr) static rtx legitimize_pic_address (rtx orig, rtx reg) { + bool gotdata_op = false; + if (GET_CODE (orig) == SYMBOL_REF /* See the comment in sparc_expand_move. */ || (TARGET_VXWORKS_RTP && GET_CODE (orig) == LABEL_REF)) @@ -3410,15 +3412,28 @@ legitimize_pic_address (rtx orig, rtx reg) emit_insn (gen_movsi_lo_sum_pic (temp_reg, temp_reg, orig)); } address = temp_reg; + gotdata_op = true; } else address = orig; - pic_ref = gen_const_mem (Pmode, - gen_rtx_PLUS (Pmode, - pic_offset_table_rtx, address)); crtl->uses_pic_offset_table = 1; - insn = emit_move_insn (reg, pic_ref); + if (gotdata_op) + { + if (TARGET_ARCH64) + insn = emit_insn (gen_movdi_pic_gotdata_op (reg, pic_offset_table_rtx, + address, orig)); + else + insn = emit_insn (gen_movsi_pic_gotdata_op (reg, pic_offset_table_rtx, + address, orig)); + } + else + { + pic_ref = gen_const_mem (Pmode, + gen_rtx_PLUS (Pmode, + pic_offset_table_rtx, address)); + insn = emit_move_insn (reg, pic_ref); + } /* Put a REG_EQUAL note on this insn, so that it can be optimized by loop. */ set_unique_reg_note (insn, REG_EQUAL, orig); diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index caf84437ecf..586c06655f3 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -38,6 +38,7 @@ (UNSPEC_EMB_TEXTHI 14) (UNSPEC_EMB_TEXTULO 15) (UNSPEC_EMB_SETHM 18) + (UNSPEC_MOVE_GOTDATA 19) (UNSPEC_MEMBAR 20) @@ -1224,13 +1225,40 @@ (lo_sum:SI (match_operand:SI 1 "register_operand" "r") (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))] "flag_pic" - "or\t%1, %%lo(%a2), %0") +{ +#ifdef HAVE_AS_SPARC_GOTDATA_OP + return "xor\t%1, %%gdop_lox10(%a2), %0"; +#else + return "or\t%1, %%lo(%a2), %0"; +#endif +}) (define_insn "movsi_high_pic" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))] "flag_pic && check_pic (1)" - "sethi\t%%hi(%a1), %0") +{ +#ifdef HAVE_AS_SPARC_GOTDATA_OP + return "sethi\t%%gdop_hix22(%a1), %0"; +#else + return "sethi\t%%hi(%a1), %0"; +#endif +}) + +(define_insn "movsi_pic_gotdata_op" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r") + (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))] + "flag_pic && check_pic (1)" +{ +#ifdef HAVE_AS_SPARC_GOTDATA_OP + return "ld\t[%1 + %2], %0, %%gdop(%a3)"; +#else + return "ld\t[%1 + %2], %0"; +#endif +} + [(set_attr "type" "load")]) (define_expand "movsi_pic_label_ref" [(set (match_dup 3) (high:SI @@ -1430,13 +1458,40 @@ (lo_sum:DI (match_operand:DI 1 "register_operand" "r") (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))] "TARGET_ARCH64 && flag_pic" - "or\t%1, %%lo(%a2), %0") +{ +#ifdef HAVE_AS_SPARC_GOTDATA_OP + return "xor\t%1, %%gdop_lox10(%a2), %0"; +#else + return "or\t%1, %%lo(%a2), %0"; +#endif +}) (define_insn "movdi_high_pic" [(set (match_operand:DI 0 "register_operand" "=r") (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))] "TARGET_ARCH64 && flag_pic && check_pic (1)" - "sethi\t%%hi(%a1), %0") +{ +#ifdef HAVE_AS_SPARC_GOTDATA_OP + return "sethi\t%%gdop_hix22(%a1), %0"; +#else + return "sethi\t%%hi(%a1), %0"; +#endif +}) + +(define_insn "movdi_pic_gotdata_op" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "register_operand" "r") + (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))] + "TARGET_ARCH64 && flag_pic && check_pic (1)" +{ +#ifdef HAVE_AS_SPARC_GOTDATA_OP + return "ldx\t[%1 + %2], %0, %%gdop(%a3)"; +#else + return "ldx\t[%1 + %2], %0"; +#endif +} + [(set_attr "type" "load")]) (define_insn "*sethi_di_medlow_embmedany_pic" [(set (match_operand:DI 0 "register_operand" "=r") diff --git a/gcc/configure b/gcc/configure index a0e15ad2f47..938f5c1d9f4 100755 --- a/gcc/configure +++ b/gcc/configure @@ -22489,6 +22489,51 @@ if test $gcc_cv_as_sparc_relax = yes; then $as_echo "#define HAVE_AS_RELAX_OPTION 1" >>confdefs.h +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for GOTDATA_OP relocs" >&5 +$as_echo_n "checking assembler for GOTDATA_OP relocs... " >&6; } +if test "${gcc_cv_as_sparc_gotdata_op+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + gcc_cv_as_sparc_gotdata_op=no + if test x$gcc_cv_as != x; then + echo '.text +foo: + nop +bar: + sethi %gdop_hix22(foo), %g1 + xor %g1, %gdop_lox10(foo), %g1 + ld [%l7 + %g1], %g2, %gdop(foo)' > conftest.s + if { ac_try='$gcc_cv_as $gcc_cv_as_flags -K PIC -o conftest.o conftest.s >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + then + if test x$gcc_cv_ld != x \ + && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1 \ + && (test x$gnu_ld_flag = xno \ + || (test x$gcc_cv_objdump != x \ + && $gcc_cv_objdump -s -j .text conftest.o 2> /dev/null \ + | grep ' 03000004 82186004 c405c001'> /dev/null 2>&1)); then + gcc_cv_as_sparc_gotdata_op=yes + fi + rm -f conftest + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sparc_gotdata_op" >&5 +$as_echo "$gcc_cv_as_sparc_gotdata_op" >&6; } +if test $gcc_cv_as_sparc_gotdata_op = yes; then + +$as_echo "#define HAVE_AS_SPARC_GOTDATA_OP 1" >>confdefs.h + fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for unaligned pcrel relocs" >&5 diff --git a/gcc/configure.ac b/gcc/configure.ac index cd44af8b35e..fe1ac55d863 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -2944,6 +2944,28 @@ case "$target" in [AC_DEFINE(HAVE_AS_RELAX_OPTION, 1, [Define if your assembler supports -relax option.])]) + gcc_GAS_CHECK_FEATURE([GOTDATA_OP relocs], + gcc_cv_as_sparc_gotdata_op,, + [-K PIC], +[.text +foo: + nop +bar: + sethi %gdop_hix22(foo), %g1 + xor %g1, %gdop_lox10(foo), %g1 + ld [[%l7 + %g1]], %g2, %gdop(foo)], + [if test x$gcc_cv_ld != x \ + && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1 \ + && (test x$gnu_ld_flag = xno \ + || (test x$gcc_cv_objdump != x \ + && $gcc_cv_objdump -s -j .text conftest.o 2> /dev/null \ + | grep ' 03000004 82186004 c405c001'> /dev/null 2>&1)); then + gcc_cv_as_sparc_gotdata_op=yes + fi + rm -f conftest], + [AC_DEFINE(HAVE_AS_SPARC_GOTDATA_OP, 1, + [Define if your assembler and linker support GOTDATA_OP relocs.])]) + gcc_GAS_CHECK_FEATURE([unaligned pcrel relocs], gcc_cv_as_sparc_ua_pcrel,, [-K PIC],