summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authordavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>2010-02-21 03:58:51 +0000
committerdavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>2010-02-21 03:58:51 +0000
commit2f1e7d0b3cc16bfdc2206528200cb3438c025c5e (patch)
tree1f268d9d146f9c7ed9d1caef3cd9d4aadc1046a9 /gcc
parentd088d2eb7f2c5e20f0da735cffa5f4e71559f6ce (diff)
downloadgcc-2f1e7d0b3cc16bfdc2206528200cb3438c025c5e.tar.gz
gcc/
2010-02-20 David S. Miller <davem@davemloft.net> * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156933 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config.in6
-rw-r--r--gcc/config/sparc/sparc.c23
-rw-r--r--gcc/config/sparc/sparc.md63
-rwxr-xr-xgcc/configure45
-rw-r--r--gcc/configure.ac22
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 <davem@davemloft.net>
+
+ * 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 <ubizjak@gmail.com>
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
@@ -22491,6 +22491,51 @@ $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
$as_echo_n "checking assembler for unaligned pcrel relocs... " >&6; }
if test "${gcc_cv_as_sparc_ua_pcrel+set}" = set; then :
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],