re PR target/65810 (powerpc64 alignment of r2 insufficient for loading long-double constants)
PR target/65810 * config/rs6000/rs6000.c (POWERPC64_TOC_POINTER_ALIGNMENT): Define. (offsettable_ok_by_alignment): Use minimum of decl and toc pointer alignment. Replace dead code with assertion. (use_toc_relative_ref): Add mode arg. Return false in -mcmodel=medium case if size exceeds toc pointer alignment. (rs6000_legitimize_reload_address): Update use_toc_relative_ref call. (rs6000_emit_move): Likewise. * configure.ac: Add linker toc pointer alignment check. * configure: Regenerate. * config.in: Regenerate. From-SVN: r222498
This commit is contained in:
parent
1a9f259288
commit
3954ead0d8
@ -1,3 +1,17 @@
|
||||
2015-04-28 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR target/65810
|
||||
* config/rs6000/rs6000.c (POWERPC64_TOC_POINTER_ALIGNMENT): Define.
|
||||
(offsettable_ok_by_alignment): Use minimum of decl and toc
|
||||
pointer alignment. Replace dead code with assertion.
|
||||
(use_toc_relative_ref): Add mode arg. Return false in -mcmodel=medium
|
||||
case if size exceeds toc pointer alignment.
|
||||
(rs6000_legitimize_reload_address): Update use_toc_relative_ref call.
|
||||
(rs6000_emit_move): Likewise.
|
||||
* configure.ac: Add linker toc pointer alignment check.
|
||||
* configure: Regenerate.
|
||||
* config.in: Regenerate.
|
||||
|
||||
2015-04-27 Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
|
||||
* config.gcc: Add h8300-*-linux.
|
||||
|
@ -1910,6 +1910,12 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* Define to .TOC. alignment forced by your linker. */
|
||||
#ifndef USED_FOR_TARGET
|
||||
#undef POWERPC64_TOC_POINTER_ALIGNMENT
|
||||
#endif
|
||||
|
||||
|
||||
/* Define to PREFIX/include if cpp should also search that directory. */
|
||||
#ifndef USED_FOR_TARGET
|
||||
#undef PREFIX_INCLUDE_DIR
|
||||
|
@ -6524,13 +6524,21 @@ virtual_stack_registers_memory_p (rtx op)
|
||||
}
|
||||
|
||||
/* Return true if a MODE sized memory accesses to OP plus OFFSET
|
||||
is known to not straddle a 32k boundary. */
|
||||
is known to not straddle a 32k boundary. This function is used
|
||||
to determine whether -mcmodel=medium code can use TOC pointer
|
||||
relative addressing for OP. This means the alignment of the TOC
|
||||
pointer must also be taken into account, and unfortunately that is
|
||||
only 8 bytes. */
|
||||
|
||||
#ifndef POWERPC64_TOC_POINTER_ALIGNMENT
|
||||
#define POWERPC64_TOC_POINTER_ALIGNMENT 8
|
||||
#endif
|
||||
|
||||
static bool
|
||||
offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
|
||||
machine_mode mode)
|
||||
{
|
||||
tree decl, type;
|
||||
tree decl;
|
||||
unsigned HOST_WIDE_INT dsize, dalign, lsb, mask;
|
||||
|
||||
if (GET_CODE (op) != SYMBOL_REF)
|
||||
@ -6583,38 +6591,20 @@ offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
|
||||
if (dsize > 32768)
|
||||
return false;
|
||||
|
||||
return dalign / BITS_PER_UNIT >= dsize;
|
||||
dalign /= BITS_PER_UNIT;
|
||||
if (dalign > POWERPC64_TOC_POINTER_ALIGNMENT)
|
||||
dalign = POWERPC64_TOC_POINTER_ALIGNMENT;
|
||||
return dalign >= dsize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
type = TREE_TYPE (decl);
|
||||
|
||||
dalign = TYPE_ALIGN (type);
|
||||
if (CONSTANT_CLASS_P (decl))
|
||||
dalign = CONSTANT_ALIGNMENT (decl, dalign);
|
||||
else
|
||||
dalign = DATA_ALIGNMENT (decl, dalign);
|
||||
|
||||
if (dsize == 0)
|
||||
{
|
||||
/* BLKmode, check the entire object. */
|
||||
if (TREE_CODE (decl) == STRING_CST)
|
||||
dsize = TREE_STRING_LENGTH (decl);
|
||||
else if (TYPE_SIZE_UNIT (type)
|
||||
&& tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
|
||||
dsize = tree_to_uhwi (TYPE_SIZE_UNIT (type));
|
||||
else
|
||||
return false;
|
||||
if (dsize > 32768)
|
||||
return false;
|
||||
|
||||
return dalign / BITS_PER_UNIT >= dsize;
|
||||
}
|
||||
}
|
||||
gcc_unreachable ();
|
||||
|
||||
/* Find how many bits of the alignment we know for this access. */
|
||||
mask = dalign / BITS_PER_UNIT - 1;
|
||||
dalign /= BITS_PER_UNIT;
|
||||
if (dalign > POWERPC64_TOC_POINTER_ALIGNMENT)
|
||||
dalign = POWERPC64_TOC_POINTER_ALIGNMENT;
|
||||
mask = dalign - 1;
|
||||
lsb = offset & -offset;
|
||||
mask &= lsb - 1;
|
||||
dalign = mask + 1;
|
||||
@ -7553,13 +7543,14 @@ rs6000_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
|
||||
can be addressed relative to the toc pointer. */
|
||||
|
||||
static bool
|
||||
use_toc_relative_ref (rtx sym)
|
||||
use_toc_relative_ref (rtx sym, machine_mode mode)
|
||||
{
|
||||
return ((constant_pool_expr_p (sym)
|
||||
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym),
|
||||
get_pool_mode (sym)))
|
||||
|| (TARGET_CMODEL == CMODEL_MEDIUM
|
||||
&& SYMBOL_REF_LOCAL_P (sym)));
|
||||
&& SYMBOL_REF_LOCAL_P (sym)
|
||||
&& GET_MODE_SIZE (mode) <= POWERPC64_TOC_POINTER_ALIGNMENT));
|
||||
}
|
||||
|
||||
/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
|
||||
@ -7764,7 +7755,7 @@ rs6000_legitimize_reload_address (rtx x, machine_mode mode,
|
||||
if (TARGET_TOC
|
||||
&& reg_offset_p
|
||||
&& GET_CODE (x) == SYMBOL_REF
|
||||
&& use_toc_relative_ref (x))
|
||||
&& use_toc_relative_ref (x, mode))
|
||||
{
|
||||
x = create_TOC_reference (x, NULL_RTX);
|
||||
if (TARGET_CMODEL != CMODEL_SMALL)
|
||||
@ -8842,7 +8833,7 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
|
||||
reference to it. */
|
||||
if (TARGET_TOC
|
||||
&& GET_CODE (operands[1]) == SYMBOL_REF
|
||||
&& use_toc_relative_ref (operands[1]))
|
||||
&& use_toc_relative_ref (operands[1], mode))
|
||||
operands[1] = create_TOC_reference (operands[1], operands[0]);
|
||||
else if (mode == Pmode
|
||||
&& CONSTANT_P (operands[1])
|
||||
|
34
gcc/configure
vendored
34
gcc/configure
vendored
@ -27530,6 +27530,40 @@ $as_echo "$gcc_cv_ld_large_toc" >&6; }
|
||||
|
||||
$as_echo "#define HAVE_LD_LARGE_TOC 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker toc pointer alignment" >&5
|
||||
$as_echo_n "checking linker toc pointer alignment... " >&6; }
|
||||
if test "${gcc_cv_ld_toc_align+set}" = set; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_nm != x; then
|
||||
cat > conftest.s <<EOF
|
||||
.global _start
|
||||
.text
|
||||
_start:
|
||||
addis 9,2,x@got@ha
|
||||
.section .data.rel.ro,"aw",@progbits
|
||||
.p2align 16
|
||||
.space 32768
|
||||
x: .quad .TOC.
|
||||
EOF
|
||||
if $gcc_cv_as -a64 -o conftest.o conftest.s > /dev/null 2>&1 \
|
||||
&& $gcc_cv_ld $emul_name -o conftest conftest.o > /dev/null 2>&1; then
|
||||
gcc_cv_ld_toc_align=`$gcc_cv_nm conftest | ${AWK} '/\.TOC\./ { match ($0, "0[[:xdigit:]]*", a); print strtonum ("0x" substr(a[0], length(a[0])-3)) }'`
|
||||
fi
|
||||
rm -f conftest conftest.o conftest.s
|
||||
fi
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_toc_align" >&5
|
||||
$as_echo "$gcc_cv_ld_toc_align" >&6; }
|
||||
if test -n "$gcc_cv_ld_toc_align" && test $gcc_cv_ld_toc_align -gt 8; then
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define POWERPC64_TOC_POINTER_ALIGNMENT $gcc_cv_ld_toc_align
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
@ -5087,6 +5087,31 @@ EOF
|
||||
AC_DEFINE(HAVE_LD_LARGE_TOC, 1,
|
||||
[Define if your PowerPC64 linker supports a large TOC.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK(linker toc pointer alignment,
|
||||
gcc_cv_ld_toc_align,
|
||||
[if test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_nm != x; then
|
||||
cat > conftest.s <<EOF
|
||||
.global _start
|
||||
.text
|
||||
_start:
|
||||
addis 9,2,x@got@ha
|
||||
.section .data.rel.ro,"aw",@progbits
|
||||
.p2align 16
|
||||
.space 32768
|
||||
x: .quad .TOC.
|
||||
EOF
|
||||
if $gcc_cv_as -a64 -o conftest.o conftest.s > /dev/null 2>&1 \
|
||||
&& $gcc_cv_ld $emul_name -o conftest conftest.o > /dev/null 2>&1; then
|
||||
gcc_cv_ld_toc_align=`$gcc_cv_nm conftest | ${AWK} '/\.TOC\./ { match ($0, "0[[[:xdigit:]]]*", a); print strtonum ("0x" substr(a[[0]], length(a[[0]])-3)) }'`
|
||||
fi
|
||||
rm -f conftest conftest.o conftest.s
|
||||
fi
|
||||
])
|
||||
if test -n "$gcc_cv_ld_toc_align" && test $gcc_cv_ld_toc_align -gt 8; then
|
||||
AC_DEFINE_UNQUOTED(POWERPC64_TOC_POINTER_ALIGNMENT, $gcc_cv_ld_toc_align,
|
||||
[Define to .TOC. alignment forced by your linker.])
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user