mirror of git://gcc.gnu.org/git/gcc.git
[RS6000] .gnu.attributes Tag_GNU_Power_ABI_FP
Extend this attribute to cover long double ABIs, for 64-bit too. This patch also corrects an error that crept in to code setting rs6000_passes_float. See the added comment. Passing IEEE128 values in vsx regs ought to set both Tag_GNU_Power_ABI_FP and Tag_GNU_Power_ABI_Vector. Also adds a new option, default on, that disables output of .gnu_attribute assembly directives. * config/rs6000/sysv4.opt (mgnu-attribute): New option. * doc/invoke.texi: Document it. * config/rs6000/rs6000.c (HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE): Define. (rs6000_passes_float): Comment. (rs6000_passes_long_double): New static var. (call_ABI_of_interest): Return false unless rs6000_gnu_attr is set. (init_cumulative_args): Set up to emit fp .gnu_attribute for ELF 64-bit ABIs as well as 32-bit ELF. Correct rs6000_passes_float to include fp values returned in vectors. Set rs6000_passes_long_double. (rs6000_function_arg_advance_1): Likewise for function args. (rs6000_elf_file_end): Emit fp .gnu_attribute for ELF 64-bit ABIs, and SPE. Emit long double tag value too. (rs6000_opt_vars): Add gnu-attr. * configure.ac (HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE): New ppc32 test. * configure: Regenerate. * config.in: Regenerate. From-SVN: r240601
This commit is contained in:
parent
91eaca5e32
commit
e9dda04f07
|
|
@ -1,3 +1,23 @@
|
||||||
|
2016-09-29 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* config/rs6000/sysv4.opt (mgnu-attribute): New option.
|
||||||
|
* doc/invoke.texi: Document it.
|
||||||
|
* config/rs6000/rs6000.c (HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE): Define.
|
||||||
|
(rs6000_passes_float): Comment.
|
||||||
|
(rs6000_passes_long_double): New static var.
|
||||||
|
(call_ABI_of_interest): Return false unless rs6000_gnu_attr is set.
|
||||||
|
(init_cumulative_args): Set up to emit fp .gnu_attribute for
|
||||||
|
ELF 64-bit ABIs as well as 32-bit ELF. Correct rs6000_passes_float
|
||||||
|
to include fp values returned in vectors.
|
||||||
|
Set rs6000_passes_long_double.
|
||||||
|
(rs6000_function_arg_advance_1): Likewise for function args.
|
||||||
|
(rs6000_elf_file_end): Emit fp .gnu_attribute for ELF 64-bit ABIs,
|
||||||
|
and SPE. Emit long double tag value too.
|
||||||
|
(rs6000_opt_vars): Add gnu-attr.
|
||||||
|
* configure.ac (HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE): New ppc32 test.
|
||||||
|
* configure: Regenerate.
|
||||||
|
* config.in: Regenerate.
|
||||||
|
|
||||||
2016-09-28 Jakub Jelinek <jakub@redhat.com>
|
2016-09-28 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* gimple-ssa-sprintf.c (pass_sprintf_length::gate): Use x > 0 instead
|
* gimple-ssa-sprintf.c (pass_sprintf_length::gate): Use x > 0 instead
|
||||||
|
|
|
||||||
|
|
@ -1538,6 +1538,12 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Define if your PowerPC linker has .gnu.attributes long double support. */
|
||||||
|
#ifndef USED_FOR_TARGET
|
||||||
|
#undef HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Define if your linker supports --push-state/--pop-state */
|
/* Define if your linker supports --push-state/--pop-state */
|
||||||
#ifndef USED_FOR_TARGET
|
#ifndef USED_FOR_TARGET
|
||||||
#undef HAVE_LD_PUSHPOPSTATE_SUPPORT
|
#undef HAVE_LD_PUSHPOPSTATE_SUPPORT
|
||||||
|
|
|
||||||
|
|
@ -183,8 +183,16 @@ unsigned rs6000_pmode;
|
||||||
unsigned rs6000_pointer_size;
|
unsigned rs6000_pointer_size;
|
||||||
|
|
||||||
#ifdef HAVE_AS_GNU_ATTRIBUTE
|
#ifdef HAVE_AS_GNU_ATTRIBUTE
|
||||||
/* Flag whether floating point values have been passed/returned. */
|
# ifndef HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE
|
||||||
|
# define HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE 0
|
||||||
|
# endif
|
||||||
|
/* Flag whether floating point values have been passed/returned.
|
||||||
|
Note that this doesn't say whether fprs are used, since the
|
||||||
|
Tag_GNU_Power_ABI_FP .gnu.attributes value this flag controls
|
||||||
|
should be set for soft-float values passed in gprs and ieee128
|
||||||
|
values passed in vsx registers. */
|
||||||
static bool rs6000_passes_float;
|
static bool rs6000_passes_float;
|
||||||
|
static bool rs6000_passes_long_double;
|
||||||
/* Flag whether vector values have been passed/returned. */
|
/* Flag whether vector values have been passed/returned. */
|
||||||
static bool rs6000_passes_vector;
|
static bool rs6000_passes_vector;
|
||||||
/* Flag whether small (<= 8 byte) structures have been returned. */
|
/* Flag whether small (<= 8 byte) structures have been returned. */
|
||||||
|
|
@ -10920,7 +10928,7 @@ rs6000_return_in_msb (const_tree valtype)
|
||||||
static bool
|
static bool
|
||||||
call_ABI_of_interest (tree fndecl)
|
call_ABI_of_interest (tree fndecl)
|
||||||
{
|
{
|
||||||
if (symtab->state == EXPANSION)
|
if (rs6000_gnu_attr && symtab->state == EXPANSION)
|
||||||
{
|
{
|
||||||
struct cgraph_node *c_node;
|
struct cgraph_node *c_node;
|
||||||
|
|
||||||
|
|
@ -10997,7 +11005,7 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_AS_GNU_ATTRIBUTE
|
#ifdef HAVE_AS_GNU_ATTRIBUTE
|
||||||
if (DEFAULT_ABI == ABI_V4)
|
if (TARGET_ELF && (TARGET_64BIT || DEFAULT_ABI == ABI_V4))
|
||||||
{
|
{
|
||||||
cum->escapes = call_ABI_of_interest (fndecl);
|
cum->escapes = call_ABI_of_interest (fndecl);
|
||||||
if (cum->escapes)
|
if (cum->escapes)
|
||||||
|
|
@ -11025,10 +11033,19 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
|
||||||
<= 8))
|
<= 8))
|
||||||
rs6000_returns_struct = true;
|
rs6000_returns_struct = true;
|
||||||
}
|
}
|
||||||
if (SCALAR_FLOAT_MODE_NOT_VECTOR_P (return_mode))
|
if (SCALAR_FLOAT_MODE_P (return_mode))
|
||||||
rs6000_passes_float = true;
|
{
|
||||||
else if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode)
|
rs6000_passes_float = true;
|
||||||
|| SPE_VECTOR_MODE (return_mode))
|
if ((HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE || TARGET_64BIT)
|
||||||
|
&& (FLOAT128_IBM_P (return_mode)
|
||||||
|
|| FLOAT128_IEEE_P (return_mode)
|
||||||
|
|| (return_type != NULL
|
||||||
|
&& (TYPE_MAIN_VARIANT (return_type)
|
||||||
|
== long_double_type_node))))
|
||||||
|
rs6000_passes_long_double = true;
|
||||||
|
}
|
||||||
|
if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode)
|
||||||
|
|| SPE_VECTOR_MODE (return_mode))
|
||||||
rs6000_passes_vector = true;
|
rs6000_passes_vector = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -11475,16 +11492,23 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, machine_mode mode,
|
||||||
cum->nargs_prototype--;
|
cum->nargs_prototype--;
|
||||||
|
|
||||||
#ifdef HAVE_AS_GNU_ATTRIBUTE
|
#ifdef HAVE_AS_GNU_ATTRIBUTE
|
||||||
if (DEFAULT_ABI == ABI_V4
|
if (TARGET_ELF && (TARGET_64BIT || DEFAULT_ABI == ABI_V4)
|
||||||
&& cum->escapes)
|
&& cum->escapes)
|
||||||
{
|
{
|
||||||
if (SCALAR_FLOAT_MODE_NOT_VECTOR_P (mode))
|
if (SCALAR_FLOAT_MODE_P (mode))
|
||||||
rs6000_passes_float = true;
|
{
|
||||||
else if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
|
rs6000_passes_float = true;
|
||||||
rs6000_passes_vector = true;
|
if ((HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE || TARGET_64BIT)
|
||||||
else if (SPE_VECTOR_MODE (mode)
|
&& (FLOAT128_IBM_P (mode)
|
||||||
&& !cum->stdarg
|
|| FLOAT128_IEEE_P (mode)
|
||||||
&& cum->sysv_gregno <= GP_ARG_MAX_REG)
|
|| (type != NULL
|
||||||
|
&& TYPE_MAIN_VARIANT (type) == long_double_type_node)))
|
||||||
|
rs6000_passes_long_double = true;
|
||||||
|
}
|
||||||
|
if ((named && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
|
||||||
|
|| (SPE_VECTOR_MODE (mode)
|
||||||
|
&& !cum->stdarg
|
||||||
|
&& cum->sysv_gregno <= GP_ARG_MAX_REG))
|
||||||
rs6000_passes_vector = true;
|
rs6000_passes_vector = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -34292,13 +34316,33 @@ static void
|
||||||
rs6000_elf_file_end (void)
|
rs6000_elf_file_end (void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_AS_GNU_ATTRIBUTE
|
#ifdef HAVE_AS_GNU_ATTRIBUTE
|
||||||
|
/* ??? The value emitted depends on options active at file end.
|
||||||
|
Assume anyone using #pragma or attributes that might change
|
||||||
|
options knows what they are doing. */
|
||||||
|
if ((TARGET_64BIT || DEFAULT_ABI == ABI_V4)
|
||||||
|
&& rs6000_passes_float)
|
||||||
|
{
|
||||||
|
int fp;
|
||||||
|
|
||||||
|
if (TARGET_DF_FPR | TARGET_DF_SPE)
|
||||||
|
fp = 1;
|
||||||
|
else if (TARGET_SF_FPR | TARGET_SF_SPE)
|
||||||
|
fp = 3;
|
||||||
|
else
|
||||||
|
fp = 2;
|
||||||
|
if (rs6000_passes_long_double)
|
||||||
|
{
|
||||||
|
if (!TARGET_LONG_DOUBLE_128)
|
||||||
|
fp |= 2 * 4;
|
||||||
|
else if (TARGET_IEEEQUAD)
|
||||||
|
fp |= 3 * 4;
|
||||||
|
else
|
||||||
|
fp |= 1 * 4;
|
||||||
|
}
|
||||||
|
fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n", fp);
|
||||||
|
}
|
||||||
if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
|
if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
|
||||||
{
|
{
|
||||||
if (rs6000_passes_float)
|
|
||||||
fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
|
|
||||||
((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
|
|
||||||
: (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
|
|
||||||
: 2));
|
|
||||||
if (rs6000_passes_vector)
|
if (rs6000_passes_vector)
|
||||||
fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
|
fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
|
||||||
(TARGET_ALTIVEC_ABI ? 2
|
(TARGET_ALTIVEC_ABI ? 2
|
||||||
|
|
@ -37085,6 +37129,9 @@ static struct rs6000_opt_var const rs6000_opt_vars[] =
|
||||||
{ "warn-cell-microcode",
|
{ "warn-cell-microcode",
|
||||||
offsetof (struct gcc_options, x_rs6000_warn_cell_microcode),
|
offsetof (struct gcc_options, x_rs6000_warn_cell_microcode),
|
||||||
offsetof (struct cl_target_option, x_rs6000_warn_cell_microcode), },
|
offsetof (struct cl_target_option, x_rs6000_warn_cell_microcode), },
|
||||||
|
{ "gnu-attr",
|
||||||
|
offsetof (struct gcc_options, x_rs6000_gnu_attr),
|
||||||
|
offsetof (struct cl_target_option, x_rs6000_gnu_attr), },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Inner function to handle attribute((target("..."))) and #pragma GCC target
|
/* Inner function to handle attribute((target("..."))) and #pragma GCC target
|
||||||
|
|
|
||||||
|
|
@ -155,3 +155,7 @@ Generate code to use a non-exec PLT and GOT.
|
||||||
mbss-plt
|
mbss-plt
|
||||||
Target Report RejectNegative Var(secure_plt, 0) Save
|
Target Report RejectNegative Var(secure_plt, 0) Save
|
||||||
Generate code for old exec BSS PLT.
|
Generate code for old exec BSS PLT.
|
||||||
|
|
||||||
|
mgnu-attribute
|
||||||
|
Target Report Var(rs6000_gnu_attr) Init(1) Save
|
||||||
|
Emit .gnu_attribute tags.
|
||||||
|
|
|
||||||
|
|
@ -28322,6 +28322,58 @@ fi
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_clearcap" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_clearcap" >&5
|
||||||
$as_echo "$gcc_cv_ld_clearcap" >&6; }
|
$as_echo "$gcc_cv_ld_clearcap" >&6; }
|
||||||
|
|
||||||
|
case "$target" in
|
||||||
|
powerpc*-*-*)
|
||||||
|
case "$target" in
|
||||||
|
*le-*-linux*)
|
||||||
|
emul_name="-melf32lppc"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
emul_name="-melf32ppc"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker .gnu.attributes long double support" >&5
|
||||||
|
$as_echo_n "checking linker .gnu.attributes long double support... " >&6; }
|
||||||
|
if test "${gcc_cv_ld_ppc_attr+set}" = set; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
gcc_cv_ld_ppc_attr=no
|
||||||
|
if test x"$ld_is_gold" = xyes; then
|
||||||
|
gcc_cv_ld_ppc_attr=yes
|
||||||
|
elif test $in_tree_ld = yes ; then
|
||||||
|
if test "$gcc_cv_gld_major_version" -eq 2 \
|
||||||
|
-a "$gcc_cv_gld_minor_version" -ge 28 \
|
||||||
|
-o "$gcc_cv_gld_major_version" -gt 2; then
|
||||||
|
gcc_cv_ld_ppc_attr=yes
|
||||||
|
fi
|
||||||
|
elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x ; then
|
||||||
|
# check that merging the long double .gnu_attribute doesn't warn
|
||||||
|
cat > conftest1.s <<EOF
|
||||||
|
.gnu_attribute 4,1
|
||||||
|
EOF
|
||||||
|
cat > conftest2.s <<EOF
|
||||||
|
.gnu_attribute 4,9
|
||||||
|
EOF
|
||||||
|
if $gcc_cv_as -a32 -o conftest1.o conftest1.s > /dev/null 2>&1 \
|
||||||
|
&& $gcc_cv_as -a32 -o conftest2.o conftest2.s > /dev/null 2>&1 \
|
||||||
|
&& $gcc_cv_ld $emul_name -r -o conftest.o conftest1.o conftest2.o > /dev/null 2> conftest.err \
|
||||||
|
&& test ! -s conftest.err; then
|
||||||
|
gcc_cv_ld_ppc_attr=yes
|
||||||
|
fi
|
||||||
|
rm -f conftest.err conftest.o conftest1.o conftest2.o conftest1.s conftest2.s
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_ppc_attr" >&5
|
||||||
|
$as_echo "$gcc_cv_ld_ppc_attr" >&6; }
|
||||||
|
if test x$gcc_cv_ld_ppc_attr = xyes; then
|
||||||
|
|
||||||
|
$as_echo "#define HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE 1" >>confdefs.h
|
||||||
|
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
case "$target:$tm_file" in
|
case "$target:$tm_file" in
|
||||||
powerpc64-*-freebsd* | powerpc64*-*-linux* | powerpc*-*-linux*rs6000/biarch64.h*)
|
powerpc64-*-freebsd* | powerpc64*-*-linux* | powerpc*-*-linux*rs6000/biarch64.h*)
|
||||||
case "$target" in
|
case "$target" in
|
||||||
|
|
|
||||||
|
|
@ -5322,6 +5322,51 @@ if test "x$gcc_cv_ld_clearcap" = xyes; then
|
||||||
fi
|
fi
|
||||||
AC_MSG_RESULT($gcc_cv_ld_clearcap)
|
AC_MSG_RESULT($gcc_cv_ld_clearcap)
|
||||||
|
|
||||||
|
case "$target" in
|
||||||
|
powerpc*-*-*)
|
||||||
|
case "$target" in
|
||||||
|
*le-*-linux*)
|
||||||
|
emul_name="-melf32lppc"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
emul_name="-melf32ppc"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_CACHE_CHECK(linker .gnu.attributes long double support,
|
||||||
|
gcc_cv_ld_ppc_attr,
|
||||||
|
[gcc_cv_ld_ppc_attr=no
|
||||||
|
if test x"$ld_is_gold" = xyes; then
|
||||||
|
gcc_cv_ld_ppc_attr=yes
|
||||||
|
elif test $in_tree_ld = yes ; then
|
||||||
|
if test "$gcc_cv_gld_major_version" -eq 2 \
|
||||||
|
-a "$gcc_cv_gld_minor_version" -ge 28 \
|
||||||
|
-o "$gcc_cv_gld_major_version" -gt 2; then
|
||||||
|
gcc_cv_ld_ppc_attr=yes
|
||||||
|
fi
|
||||||
|
elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x ; then
|
||||||
|
# check that merging the long double .gnu_attribute doesn't warn
|
||||||
|
cat > conftest1.s <<EOF
|
||||||
|
.gnu_attribute 4,1
|
||||||
|
EOF
|
||||||
|
cat > conftest2.s <<EOF
|
||||||
|
.gnu_attribute 4,9
|
||||||
|
EOF
|
||||||
|
if $gcc_cv_as -a32 -o conftest1.o conftest1.s > /dev/null 2>&1 \
|
||||||
|
&& $gcc_cv_as -a32 -o conftest2.o conftest2.s > /dev/null 2>&1 \
|
||||||
|
&& $gcc_cv_ld $emul_name -r -o conftest.o conftest1.o conftest2.o > /dev/null 2> conftest.err \
|
||||||
|
&& test ! -s conftest.err; then
|
||||||
|
gcc_cv_ld_ppc_attr=yes
|
||||||
|
fi
|
||||||
|
rm -f conftest.err conftest.o conftest1.o conftest2.o conftest1.s conftest2.s
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
if test x$gcc_cv_ld_ppc_attr = xyes; then
|
||||||
|
AC_DEFINE(HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE, 1,
|
||||||
|
[Define if your PowerPC linker has .gnu.attributes long double support.])
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
case "$target:$tm_file" in
|
case "$target:$tm_file" in
|
||||||
powerpc64-*-freebsd* | powerpc64*-*-linux* | powerpc*-*-linux*rs6000/biarch64.h*)
|
powerpc64-*-freebsd* | powerpc64*-*-linux* | powerpc*-*-linux*rs6000/biarch64.h*)
|
||||||
case "$target" in
|
case "$target" in
|
||||||
|
|
|
||||||
|
|
@ -1017,6 +1017,7 @@ See RS/6000 and PowerPC Options.
|
||||||
-mupper-regs-di -mno-upper-regs-di @gol
|
-mupper-regs-di -mno-upper-regs-di @gol
|
||||||
-mupper-regs -mno-upper-regs @gol
|
-mupper-regs -mno-upper-regs @gol
|
||||||
-mfloat128 -mno-float128 -mfloat128-hardware -mno-float128-hardware @gol
|
-mfloat128 -mno-float128 -mfloat128-hardware -mno-float128-hardware @gol
|
||||||
|
-mgnu-attribute -mno-gnu-attribute @gol
|
||||||
-mlra -mno-lra}
|
-mlra -mno-lra}
|
||||||
|
|
||||||
@emph{RX Options}
|
@emph{RX Options}
|
||||||
|
|
@ -21299,6 +21300,14 @@ This is the default ABI for little-endian PowerPC 64-bit Linux.
|
||||||
Overriding the default ABI requires special system support and is
|
Overriding the default ABI requires special system support and is
|
||||||
likely to fail in spectacular ways.
|
likely to fail in spectacular ways.
|
||||||
|
|
||||||
|
@item -mgnu-attribute
|
||||||
|
@itemx -mno-gnu-attribute
|
||||||
|
@opindex mgnu-attribute
|
||||||
|
@opindex mno-gnu-attribute
|
||||||
|
Emit .gnu_attribute assembly directives to set tag/value pairs in a
|
||||||
|
.gnu.attributes section that specify ABI variations in function
|
||||||
|
parameters or return values.
|
||||||
|
|
||||||
@item -mprototype
|
@item -mprototype
|
||||||
@itemx -mno-prototype
|
@itemx -mno-prototype
|
||||||
@opindex mprototype
|
@opindex mprototype
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue