aarch64: Fix bootstrap with old binutils [PR93053]
authorJakub Jelinek <jakub@redhat.com>
Wed, 15 Apr 2020 09:01:19 +0000 (11:01 +0200)
committerJakub Jelinek <jakub@redhat.com>
Wed, 15 Apr 2020 09:01:19 +0000 (11:01 +0200)
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.

libgcc/ChangeLog
libgcc/config.in
libgcc/config/aarch64/lse.S
libgcc/configure
libgcc/configure.ac

index 6340cfbbf5905257ae249bc9e11b98016178816c..3426ff8470b0b3fe2d652fc9b43cf344f6aba62c 100644 (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
index 59a3d8daf52e72e548d3d9425d6043d5e0c663ad..5be5321d2584392bac1ec3af779cd96823212902 100644 (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
 
index ca6495f119f7ed696be7bb7a6672103558dc16aa..f3ccf5cf54343c682666f5bdcf204c834a73ff33 100644 (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)
index 093036acf81c1f5d347e6b6098dde016a0b1db08..26bf75789e0d999fd5edbdc6e93d356474b298be 100755 (executable)
@@ -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 :
index 85979da9ae58211969174862f142755d40a57a03..bff6e54f22e019f4703f3f7dec9b49b581d317c3 100644 (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(,