aarch64: Fix bootstrap with old binutils [PR93053]

As reported in the PR, GCC 10 (and also 9.3.1 but not 9.3.0) fails to build
when using older binutils which lack LSE support, because those instructions
are used in libgcc.
Thanks to Kyrylo's hint, the following patches (hopefully) allow it to build
even with older binutils by using .inst directive if LSE support isn't
available in the assembler.

2020-04-15  Jakub Jelinek  <jakub@redhat.com>

	PR target/93053
	* configure.ac (LIBGCC_CHECK_AS_LSE): Add HAVE_AS_LSE checking.
	* config/aarch64/lse.S: Include auto-target.h, if HAVE_AS_LSE
	is not defined, use just .arch armv8-a.
	(B, M, N, OPN): Define.
	(COMMENT): New .macro.
	(CAS, CASP, SWP, LDOP): Use .inst directive if HAVE_AS_LSE is not
	defined.  Otherwise, move the operands right after the glue? and
	comment out operands where the macros are used.
	* configure: Regenerated.
	* config.in: Regenerated.
This commit is contained in:
Jakub Jelinek 2020-04-15 11:01:19 +02:00
parent 2dc9294c3c
commit 5b2f76e36d
5 changed files with 125 additions and 8 deletions

View File

@ -1,3 +1,17 @@
2020-04-15 Jakub Jelinek <jakub@redhat.com>
PR target/93053
* configure.ac (LIBGCC_CHECK_AS_LSE): Add HAVE_AS_LSE checking.
* config/aarch64/lse.S: Include auto-target.h, if HAVE_AS_LSE
is not defined, use just .arch armv8-a.
(B, M, N, OPN): Define.
(COMMENT): New .macro.
(CAS, CASP, SWP, LDOP): Use .inst directive if HAVE_AS_LSE is not
defined. Otherwise, move the operands right after the glue? and
comment out operands where the macros are used.
* configure: Regenerated.
* config.in: Regenerated.
2020-04-07 Ian Lance Taylor <iant@golang.org>
PR libgcc/94513

View File

@ -10,6 +10,9 @@
*/
#undef HAVE_AS_CFI_SECTIONS
/* Define to 1 if the assembler supports LSE. */
#undef HAVE_AS_LSE
/* Define to 1 if the target assembler supports thread-local storage. */
#undef HAVE_CC_TLS

View File

@ -48,8 +48,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
* separately to minimize code size.
*/
#include "auto-target.h"
/* Tell the assembler to accept LSE instructions. */
#ifdef HAVE_AS_LSE
.arch armv8-a+lse
#else
.arch armv8-a
#endif
/* Declare the symbol gating the LSE implementations. */
.hidden __aarch64_have_lse_atomics
@ -58,12 +64,19 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#if SIZE == 1
# define S b
# define UXT uxtb
# define B 0x00000000
#elif SIZE == 2
# define S h
# define UXT uxth
# define B 0x40000000
#elif SIZE == 4 || SIZE == 8 || SIZE == 16
# define S
# define UXT mov
# if SIZE == 4
# define B 0x80000000
# elif SIZE == 8
# define B 0xc0000000
# endif
#else
# error
#endif
@ -72,18 +85,26 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
# define SUFF _relax
# define A
# define L
# define M 0x000000
# define N 0x000000
#elif MODEL == 2
# define SUFF _acq
# define A a
# define L
# define M 0x400000
# define N 0x800000
#elif MODEL == 3
# define SUFF _rel
# define A
# define L l
# define M 0x008000
# define N 0x400000
#elif MODEL == 4
# define SUFF _acq_rel
# define A a
# define L l
# define M 0x408000
# define N 0xc00000
#else
# error
#endif
@ -144,9 +165,13 @@ STARTFN NAME(cas)
JUMP_IF_NOT_LSE 8f
#if SIZE < 16
#define CAS glue4(cas, A, L, S)
#ifdef HAVE_AS_LSE
# define CAS glue4(cas, A, L, S) s(0), s(1), [x2]
#else
# define CAS .inst 0x08a07c41 + B + M
#endif
CAS s(0), s(1), [x2]
CAS /* s(0), s(1), [x2] */
ret
8: UXT s(tmp0), s(0)
@ -160,9 +185,13 @@ STARTFN NAME(cas)
#else
#define LDXP glue3(ld, A, xp)
#define STXP glue3(st, L, xp)
#define CASP glue3(casp, A, L)
#ifdef HAVE_AS_LSE
# define CASP glue3(casp, A, L) x0, x1, x2, x3, [x4]
#else
# define CASP .inst 0x48207c82 + M
#endif
CASP x0, x1, x2, x3, [x4]
CASP /* x0, x1, x2, x3, [x4] */
ret
8: mov x(tmp0), x0
@ -181,12 +210,16 @@ ENDFN NAME(cas)
#endif
#ifdef L_swp
#define SWP glue4(swp, A, L, S)
#ifdef HAVE_AS_LSE
# define SWP glue4(swp, A, L, S) s(0), s(0), [x1]
#else
# define SWP .inst 0x38208020 + B + N
#endif
STARTFN NAME(swp)
JUMP_IF_NOT_LSE 8f
SWP s(0), s(0), [x1]
SWP /* s(0), s(0), [x1] */
ret
8: mov s(tmp0), s(0)
@ -204,24 +237,32 @@ ENDFN NAME(swp)
#ifdef L_ldadd
#define LDNM ldadd
#define OP add
#define OPN 0x0000
#elif defined(L_ldclr)
#define LDNM ldclr
#define OP bic
#define OPN 0x1000
#elif defined(L_ldeor)
#define LDNM ldeor
#define OP eor
#define OPN 0x2000
#elif defined(L_ldset)
#define LDNM ldset
#define OP orr
#define OPN 0x3000
#else
#error
#endif
#define LDOP glue4(LDNM, A, L, S)
#ifdef HAVE_AS_LSE
# define LDOP glue4(LDNM, A, L, S) s(0), s(0), [x1]
#else
# define LDOP .inst 0x38200020 + OPN + B + N
#endif
STARTFN NAME(LDNM)
JUMP_IF_NOT_LSE 8f
LDOP s(0), s(0), [x1]
LDOP /* s(0), s(0), [x1] */
ret
8: mov s(tmp0), s(0)

40
libgcc/configure vendored
View File

@ -5530,6 +5530,46 @@ $as_echo "#define HAVE_AS_AVX 1" >>confdefs.h
;;
esac
case "${target}" in
aarch64*-*-*)
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler supports LSE" >&5
$as_echo_n "checking if the assembler supports LSE... " >&6; }
if ${libgcc_cv_as_lse+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
asm(".arch armv8-a+lse\n\tcas w0, w1, [x2]");
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
libgcc_cv_as_lse=yes
else
libgcc_cv_as_lse=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_as_lse" >&5
$as_echo "$libgcc_cv_as_lse" >&6; }
if test x$libgcc_cv_as_lse = xyes; then
$as_echo "#define HAVE_AS_LSE 1" >>confdefs.h
fi
;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for init priority support" >&5
$as_echo_n "checking for init priority support... " >&6; }
if ${libgcc_cv_init_priority+:} false; then :

View File

@ -599,6 +599,25 @@ i[[34567]]86-*-* | x86_64-*-*)
esac])
LIBGCC_CHECK_AS_AVX
dnl Check if as supports LSE instructions.
AC_DEFUN([LIBGCC_CHECK_AS_LSE], [
case "${target}" in
aarch64*-*-*)
AC_CACHE_CHECK([if the assembler supports LSE], libgcc_cv_as_lse, [
AC_TRY_COMPILE([],
changequote(,)dnl
asm(".arch armv8-a+lse\n\tcas w0, w1, [x2]");
changequote([,])dnl
,
[libgcc_cv_as_lse=yes], [libgcc_cv_as_lse=no])
])
if test x$libgcc_cv_as_lse = xyes; then
AC_DEFINE(HAVE_AS_LSE, 1, [Define to 1 if the assembler supports LSE.])
fi
;;
esac])
LIBGCC_CHECK_AS_LSE
dnl Check if as supports RTM instructions.
AC_CACHE_CHECK(for init priority support, libgcc_cv_init_priority, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,