configure.ac: Test if linker and assembler properly support GOTDATA_OP relocations.
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. From-SVN: r156933
This commit is contained in:
parent
9cd1520f41
commit
878ee0ab0f
@ -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>
|
2010-02-20 Uros Bizjak <ubizjak@gmail.com>
|
||||||
|
|
||||||
PR target/43067
|
PR target/43067
|
||||||
|
@ -417,6 +417,12 @@
|
|||||||
#endif
|
#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.
|
/* Define if your assembler and linker support unaligned PC relative relocs.
|
||||||
*/
|
*/
|
||||||
#ifndef USED_FOR_TARGET
|
#ifndef USED_FOR_TARGET
|
||||||
|
@ -3374,6 +3374,8 @@ legitimize_tls_address (rtx addr)
|
|||||||
static rtx
|
static rtx
|
||||||
legitimize_pic_address (rtx orig, rtx reg)
|
legitimize_pic_address (rtx orig, rtx reg)
|
||||||
{
|
{
|
||||||
|
bool gotdata_op = false;
|
||||||
|
|
||||||
if (GET_CODE (orig) == SYMBOL_REF
|
if (GET_CODE (orig) == SYMBOL_REF
|
||||||
/* See the comment in sparc_expand_move. */
|
/* See the comment in sparc_expand_move. */
|
||||||
|| (TARGET_VXWORKS_RTP && GET_CODE (orig) == LABEL_REF))
|
|| (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));
|
emit_insn (gen_movsi_lo_sum_pic (temp_reg, temp_reg, orig));
|
||||||
}
|
}
|
||||||
address = temp_reg;
|
address = temp_reg;
|
||||||
|
gotdata_op = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
address = orig;
|
address = orig;
|
||||||
|
|
||||||
pic_ref = gen_const_mem (Pmode,
|
|
||||||
gen_rtx_PLUS (Pmode,
|
|
||||||
pic_offset_table_rtx, address));
|
|
||||||
crtl->uses_pic_offset_table = 1;
|
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
|
/* Put a REG_EQUAL note on this insn, so that it can be optimized
|
||||||
by loop. */
|
by loop. */
|
||||||
set_unique_reg_note (insn, REG_EQUAL, orig);
|
set_unique_reg_note (insn, REG_EQUAL, orig);
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
(UNSPEC_EMB_TEXTHI 14)
|
(UNSPEC_EMB_TEXTHI 14)
|
||||||
(UNSPEC_EMB_TEXTULO 15)
|
(UNSPEC_EMB_TEXTULO 15)
|
||||||
(UNSPEC_EMB_SETHM 18)
|
(UNSPEC_EMB_SETHM 18)
|
||||||
|
(UNSPEC_MOVE_GOTDATA 19)
|
||||||
|
|
||||||
(UNSPEC_MEMBAR 20)
|
(UNSPEC_MEMBAR 20)
|
||||||
|
|
||||||
@ -1224,13 +1225,40 @@
|
|||||||
(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
|
(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
|
||||||
(unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
|
(unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
|
||||||
"flag_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"
|
(define_insn "movsi_high_pic"
|
||||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
(high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
|
(high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
|
||||||
"flag_pic && check_pic (1)"
|
"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"
|
(define_expand "movsi_pic_label_ref"
|
||||||
[(set (match_dup 3) (high:SI
|
[(set (match_dup 3) (high:SI
|
||||||
@ -1430,13 +1458,40 @@
|
|||||||
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
|
||||||
(unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
|
(unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
|
||||||
"TARGET_ARCH64 && flag_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"
|
(define_insn "movdi_high_pic"
|
||||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||||
(high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
|
(high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
|
||||||
"TARGET_ARCH64 && flag_pic && check_pic (1)"
|
"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"
|
(define_insn "*sethi_di_medlow_embmedany_pic"
|
||||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||||
|
45
gcc/configure
vendored
45
gcc/configure
vendored
@ -22489,6 +22489,51 @@ if test $gcc_cv_as_sparc_relax = yes; then
|
|||||||
|
|
||||||
$as_echo "#define HAVE_AS_RELAX_OPTION 1" >>confdefs.h
|
$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
|
fi
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for unaligned pcrel relocs" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for unaligned pcrel relocs" >&5
|
||||||
|
@ -2944,6 +2944,28 @@ case "$target" in
|
|||||||
[AC_DEFINE(HAVE_AS_RELAX_OPTION, 1,
|
[AC_DEFINE(HAVE_AS_RELAX_OPTION, 1,
|
||||||
[Define if your assembler supports -relax option.])])
|
[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_GAS_CHECK_FEATURE([unaligned pcrel relocs],
|
||||||
gcc_cv_as_sparc_ua_pcrel,,
|
gcc_cv_as_sparc_ua_pcrel,,
|
||||||
[-K PIC],
|
[-K PIC],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user