summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-04-15 11:01:19 +0200
committerJakub Jelinek <jakub@redhat.com>2020-04-15 11:01:19 +0200
commit5b2f76e36d861c881c6770b4f47c1fae6c0c8965 (patch)
tree563a3d7aff7d0c6e027f99e6502f92ff05b83257
parent2dc9294c3c7c81a6d5e1d4dedf58fea87bbadde6 (diff)
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.
-rw-r--r--libgcc/ChangeLog14
-rw-r--r--libgcc/config.in3
-rw-r--r--libgcc/config/aarch64/lse.S57
-rwxr-xr-xlibgcc/configure40
-rw-r--r--libgcc/configure.ac19
5 files changed, 125 insertions, 8 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 6340cfbbf59..3426ff8470b 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -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
diff --git a/libgcc/config.in b/libgcc/config.in
index 59a3d8daf52..5be5321d258 100644
--- a/libgcc/config.in
+++ b/libgcc/config.in
@@ -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
diff --git a/libgcc/config/aarch64/lse.S b/libgcc/config/aarch64/lse.S
index ca6495f119f..f3ccf5cf543 100644
--- a/libgcc/config/aarch64/lse.S
+++ b/libgcc/config/aarch64/lse.S
@@ -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)
diff --git a/libgcc/configure b/libgcc/configure
index 093036acf81..26bf75789e0 100755
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -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 :
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index 85979da9ae5..bff6e54f22e 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -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(,