Re: [PATCH v2] libgcc: aarch64: Add SME runtime support

2023-12-08 Thread Richard Sandiford
Szabolcs Nagy  writes:
> The call ABI for SME (Scalable Matrix Extension) requires a number of
> helper routines which are added to libgcc so they are tied to the
> compiler version instead of the libc version. See
> https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#sme-support-routines
>
> The routines are in shared libgcc and static libgcc eh, even though
> they are not related to exception handling.  This is to avoid linking
> a copy of the routines into dynamic linked binaries, because TPIDR2_EL0
> block can be extended in the future which is better to handle in a
> single place per process.
>
> The support routines have to decide if SME is accessible or not. Linux
> tells userspace if SME is accessible via AT_HWCAP2, otherwise a new
> __aarch64_sme_accessible symbol was introduced that a libc can define.
> Due to libgcc and libc build order, the symbol availability cannot be
> checked so for __aarch64_sme_accessible an unistd.h feature test macro
> is used while such detection mechanism is not available for __getauxval
> so we rely on configure checks based on the target triplet.
>
> Asm helper code is added to make writing the routines easier.
>
> libgcc/ChangeLog:
>
>   * config/aarch64/t-aarch64: Add sources to the build.
>   * config/aarch64/__aarch64_have_sme.c: New file.
>   * config/aarch64/__arm_sme_state.S: New file.
>   * config/aarch64/__arm_tpidr2_restore.S: New file.
>   * config/aarch64/__arm_tpidr2_save.S: New file.
>   * config/aarch64/__arm_za_disable.S: New file.
>   * config/aarch64/aarch64-asm.h: New file.
>   * config/aarch64/libgcc-sme.ver: New file.
> ---
> v2:
> - do not include unistd.h when inhibit_libc is set.
> - use msr tpidr2_el0,xzr in __arm_za_disable.

LGTM, thanks.

>  libgcc/config/aarch64/__aarch64_have_sme.c   |  75 ++
>  libgcc/config/aarch64/__arm_sme_state.S  |  55 ++
>  libgcc/config/aarch64/__arm_tpidr2_restore.S |  89 
>  libgcc/config/aarch64/__arm_tpidr2_save.S| 101 +++
>  libgcc/config/aarch64/__arm_za_disable.S |  65 
>  libgcc/config/aarch64/aarch64-asm.h  |  98 ++
>  libgcc/config/aarch64/libgcc-sme.ver |  24 +
>  libgcc/config/aarch64/t-aarch64  |  10 ++
>  8 files changed, 517 insertions(+)
>  create mode 100644 libgcc/config/aarch64/__aarch64_have_sme.c
>  create mode 100644 libgcc/config/aarch64/__arm_sme_state.S
>  create mode 100644 libgcc/config/aarch64/__arm_tpidr2_restore.S
>  create mode 100644 libgcc/config/aarch64/__arm_tpidr2_save.S
>  create mode 100644 libgcc/config/aarch64/__arm_za_disable.S
>  create mode 100644 libgcc/config/aarch64/aarch64-asm.h
>  create mode 100644 libgcc/config/aarch64/libgcc-sme.ver
>
> diff --git a/libgcc/config/aarch64/__aarch64_have_sme.c 
> b/libgcc/config/aarch64/__aarch64_have_sme.c
> new file mode 100644
> index 000..5e649246270
> --- /dev/null
> +++ b/libgcc/config/aarch64/__aarch64_have_sme.c
> @@ -0,0 +1,75 @@
> +/* Initializer for SME support.
> +   Copyright (C) 2023 Free Software Foundation, Inc.
> +
> +   This file is part of GCC.
> +
> +   GCC is free software; you can redistribute it and/or modify it
> +   under the terms of the GNU General Public License as published
> +   by the Free Software Foundation; either version 3, or (at your
> +   option) any later version.
> +
> +   GCC is distributed in the hope that it will be useful, but WITHOUT
> +   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> +   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
> +   License for more details.
> +
> +   Under Section 7 of GPL version 3, you are granted additional
> +   permissions described in the GCC Runtime Library Exception, version
> +   3.1, as published by the Free Software Foundation.
> +
> +   You should have received a copy of the GNU General Public License and
> +   a copy of the GCC Runtime Library Exception along with this program;
> +   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
> +   .  */
> +
> +#include "auto-target.h"
> +
> +#ifndef inhibit_libc
> +/* For libc feature test macros.  */
> +# include 
> +#endif
> +
> +#if __ARM_FEATURE_SME
> +/* Avoid runtime SME detection if libgcc is built with SME.  */
> +# define HAVE_SME_CONST const
> +# define HAVE_SME_VALUE 1
> +#elif HAVE___GETAUXVAL
> +/* SME access detection on Linux.  */
> +# define HAVE_SME_CONST
> +# define HAVE_SME_VALUE 0
> +# define HAVE_SME_CTOR sme_accessible ()
> +
> +# define AT_HWCAP2   26
> +# define HWCAP2_SME  (1 << 23)
> +unsigned long int __getauxval (unsigned long int);
> +
> +static _Bool
> +sme_accessible (void)
> +{
> +  unsigned long hwcap2 = __getauxval (AT_HWCAP2);
> +  return (hwcap2 & HWCAP2_SME) != 0;
> +}
> +#elif __LIBC___AARCH64_SME_ACCESSIBLE
> +/* Alternative SME access detection.  */
> +# define HAVE_SME_CONST
> +# define HAVE_SME_VALU

[PATCH v2] libgcc: aarch64: Add SME runtime support

2023-12-08 Thread Szabolcs Nagy
The call ABI for SME (Scalable Matrix Extension) requires a number of
helper routines which are added to libgcc so they are tied to the
compiler version instead of the libc version. See
https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#sme-support-routines

The routines are in shared libgcc and static libgcc eh, even though
they are not related to exception handling.  This is to avoid linking
a copy of the routines into dynamic linked binaries, because TPIDR2_EL0
block can be extended in the future which is better to handle in a
single place per process.

The support routines have to decide if SME is accessible or not. Linux
tells userspace if SME is accessible via AT_HWCAP2, otherwise a new
__aarch64_sme_accessible symbol was introduced that a libc can define.
Due to libgcc and libc build order, the symbol availability cannot be
checked so for __aarch64_sme_accessible an unistd.h feature test macro
is used while such detection mechanism is not available for __getauxval
so we rely on configure checks based on the target triplet.

Asm helper code is added to make writing the routines easier.

libgcc/ChangeLog:

* config/aarch64/t-aarch64: Add sources to the build.
* config/aarch64/__aarch64_have_sme.c: New file.
* config/aarch64/__arm_sme_state.S: New file.
* config/aarch64/__arm_tpidr2_restore.S: New file.
* config/aarch64/__arm_tpidr2_save.S: New file.
* config/aarch64/__arm_za_disable.S: New file.
* config/aarch64/aarch64-asm.h: New file.
* config/aarch64/libgcc-sme.ver: New file.
---
v2:
- do not include unistd.h when inhibit_libc is set.
- use msr tpidr2_el0,xzr in __arm_za_disable.

 libgcc/config/aarch64/__aarch64_have_sme.c   |  75 ++
 libgcc/config/aarch64/__arm_sme_state.S  |  55 ++
 libgcc/config/aarch64/__arm_tpidr2_restore.S |  89 
 libgcc/config/aarch64/__arm_tpidr2_save.S| 101 +++
 libgcc/config/aarch64/__arm_za_disable.S |  65 
 libgcc/config/aarch64/aarch64-asm.h  |  98 ++
 libgcc/config/aarch64/libgcc-sme.ver |  24 +
 libgcc/config/aarch64/t-aarch64  |  10 ++
 8 files changed, 517 insertions(+)
 create mode 100644 libgcc/config/aarch64/__aarch64_have_sme.c
 create mode 100644 libgcc/config/aarch64/__arm_sme_state.S
 create mode 100644 libgcc/config/aarch64/__arm_tpidr2_restore.S
 create mode 100644 libgcc/config/aarch64/__arm_tpidr2_save.S
 create mode 100644 libgcc/config/aarch64/__arm_za_disable.S
 create mode 100644 libgcc/config/aarch64/aarch64-asm.h
 create mode 100644 libgcc/config/aarch64/libgcc-sme.ver

diff --git a/libgcc/config/aarch64/__aarch64_have_sme.c 
b/libgcc/config/aarch64/__aarch64_have_sme.c
new file mode 100644
index 000..5e649246270
--- /dev/null
+++ b/libgcc/config/aarch64/__aarch64_have_sme.c
@@ -0,0 +1,75 @@
+/* Initializer for SME support.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   .  */
+
+#include "auto-target.h"
+
+#ifndef inhibit_libc
+/* For libc feature test macros.  */
+# include 
+#endif
+
+#if __ARM_FEATURE_SME
+/* Avoid runtime SME detection if libgcc is built with SME.  */
+# define HAVE_SME_CONST const
+# define HAVE_SME_VALUE 1
+#elif HAVE___GETAUXVAL
+/* SME access detection on Linux.  */
+# define HAVE_SME_CONST
+# define HAVE_SME_VALUE 0
+# define HAVE_SME_CTOR sme_accessible ()
+
+# define AT_HWCAP2 26
+# define HWCAP2_SME(1 << 23)
+unsigned long int __getauxval (unsigned long int);
+
+static _Bool
+sme_accessible (void)
+{
+  unsigned long hwcap2 = __getauxval (AT_HWCAP2);
+  return (hwcap2 & HWCAP2_SME) != 0;
+}
+#elif __LIBC___AARCH64_SME_ACCESSIBLE
+/* Alternative SME access detection.  */
+# define HAVE_SME_CONST
+# define HAVE_SME_VALUE 0
+# define HAVE_SME_CTOR __aarch64_sme_accessible ()
+_Bool __aarch64_sme_accessible (void);
+#else
+# define HAVE_SME_CONST const
+# define HAVE_SME_VALUE 0
+#endif
+
+/* Define the symbol gating SME support in libgcc.  */
+HAVE_SME_CON