Skip to content

Commit

Permalink
[compiler-rt][AArch64] Rewrite SME routines to all use FMV feature bits.
Browse files Browse the repository at this point in the history
When llvm#92921 added the `__arm_get_current_vg` functionality, it used
the FMV feature bits mechanism rather than the existing mechanism that was
previously added for SME that called `getauxval` (on Linux platforms)
or `__aarch64_sme_accessible` (required for baremetal libraries).

It seems simpler to always use the FMV feature bits mechanism, but
for baremetal targets we still need to rely on `__arm_sme_accessible`.
  • Loading branch information
sdesmalen-arm committed Dec 10, 2024
1 parent 5a0d73b commit 8db75c0
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 69 deletions.
9 changes: 7 additions & 2 deletions compiler-rt/lib/builtins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -573,10 +573,13 @@ set(aarch64_SOURCES
)

if (COMPILER_RT_HAS_AARCH64_SME)
if (NOT COMPILER_RT_DISABLE_AARCH64_FMV AND COMPILER_RT_HAS_FNO_BUILTIN_FLAG AND (COMPILER_RT_HAS_AUXV OR COMPILER_RT_BAREMETAL_BUILD))
list(APPEND aarch64_SOURCES aarch64/sme-abi.S aarch64/sme-libc-mem-routines.S aarch64/sme-abi-init.c aarch64/sme-libc-routines.c)
if (NOT COMPILER_RT_DISABLE_AARCH64_FMV AND COMPILER_RT_HAS_FNO_BUILTIN_FLAG)
list(APPEND aarch64_SOURCES aarch64/sme-abi.S aarch64/sme-libc-mem-routines.S aarch64/sme-abi-assert.c aarch64/sme-libc-routines.c)
message(STATUS "AArch64 SME ABI routines enabled")
set_source_files_properties(aarch64/sme-libc-routines.c PROPERTIES COMPILE_FLAGS "-fno-builtin")
if(COMPILER_RT_BAREMETAL_BUILD)
set(COMPILER_RT_BAREMETAL_AARCH64_SME TRUE)
endif()
else()
if(COMPILER_RT_DISABLE_AARCH64_FMV)
message(WARNING "AArch64 SME ABI routines require function multiversioning support.")
Expand Down Expand Up @@ -844,6 +847,8 @@ else ()
list(APPEND BUILTIN_DEFS DISABLE_AARCH64_FMV)
endif()

append_list_if(COMPILER_RT_BAREMETAL_AARCH64_SME -DENABLE_BAREMETAL_AARCH64_SME_FMV_FEATURES BUILTIN_CFLAGS)

append_list_if(COMPILER_RT_HAS_ASM_LSE HAS_ASM_LSE BUILTIN_DEFS)

foreach (arch ${BUILTIN_SUPPORTED_ARCH})
Expand Down
10 changes: 10 additions & 0 deletions compiler-rt/lib/builtins/aarch64/sme-abi-assert.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// We rely on the FMV __aarch64_cpu_features mechanism to determine
// which features are set at runtime.

#include "../cpu_model/AArch64CPUFeatures.inc"
_Static_assert(FEAT_SVE== 30, "sme-abi.S assumes FEAT_SVE = 30");
_Static_assert(FEAT_SME== 42, "sme-abi.S assumes FEAT_SME = 42");
50 changes: 0 additions & 50 deletions compiler-rt/lib/builtins/aarch64/sme-abi-init.c

This file was deleted.

29 changes: 12 additions & 17 deletions compiler-rt/lib/builtins/aarch64/sme-abi.S
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,15 @@
#include "../assembly.h"

.set FEAT_SVE_BIT, 30
.set FEAT_SME_BIT, 42
.set SVCR_PSTATE_SM_BIT, 0

#if !defined(__APPLE__)
#define TPIDR2_SYMBOL SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0)
#define TPIDR2_SYMBOL_OFFSET :lo12:SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0)
#define CPU_FEATS_SYMBOL SYMBOL_NAME(__aarch64_cpu_features)
#define CPU_FEATS_SYMBOL_OFFSET :lo12:SYMBOL_NAME(__aarch64_cpu_features)
#else
// MachO requires @page/@pageoff directives because the global is defined
// in a different file. Otherwise this file may fail to build.
#define TPIDR2_SYMBOL SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0)@page
#define TPIDR2_SYMBOL_OFFSET SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0)@pageoff
#define CPU_FEATS_SYMBOL SYMBOL_NAME(__aarch64_cpu_features)@page
#define CPU_FEATS_SYMBOL_OFFSET SYMBOL_NAME(__aarch64_cpu_features)@pageoff
#endif
Expand Down Expand Up @@ -63,9 +60,9 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_sme_state)
mov x0, xzr
mov x1, xzr

adrp x16, TPIDR2_SYMBOL
ldrb w16, [x16, TPIDR2_SYMBOL_OFFSET]
cbz w16, 1f
adrp x16, CPU_FEATS_SYMBOL
ldr x16, [x16, CPU_FEATS_SYMBOL_OFFSET]
tbz x16, #FEAT_SME_BIT, 1f
0:
orr x0, x0, #0xC000000000000000
mrs x16, SVCR
Expand Down Expand Up @@ -116,9 +113,9 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_tpidr2_save)
BTI_C
// If the current thread does not have access to TPIDR2_EL0, the subroutine
// does nothing.
adrp x14, TPIDR2_SYMBOL
ldrb w14, [x14, TPIDR2_SYMBOL_OFFSET]
cbz w14, 1f
adrp x14, CPU_FEATS_SYMBOL
ldr x14, [x14, CPU_FEATS_SYMBOL_OFFSET]
tbz x14, #FEAT_SME_BIT, 1f

// If TPIDR2_EL0 is null, the subroutine does nothing.
mrs x16, TPIDR2_EL0
Expand Down Expand Up @@ -157,9 +154,9 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_za_disable)
BTI_C
// If the current thread does not have access to SME, the subroutine does
// nothing.
adrp x14, TPIDR2_SYMBOL
ldrb w14, [x14, TPIDR2_SYMBOL_OFFSET]
cbz w14, 0f
adrp x14, CPU_FEATS_SYMBOL
ldr x14, [x14, CPU_FEATS_SYMBOL_OFFSET]
tbz x14, #FEAT_SME_BIT, 0f

// Otherwise, the subroutine behaves as if it did the following:
// * Call __arm_tpidr2_save.
Expand Down Expand Up @@ -191,11 +188,9 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_get_current_vg)
BTI_C

adrp x17, CPU_FEATS_SYMBOL
ldr w17, [x17, CPU_FEATS_SYMBOL_OFFSET]
ldr x17, [x17, CPU_FEATS_SYMBOL_OFFSET]
tbnz w17, #FEAT_SVE_BIT, 1f
adrp x17, TPIDR2_SYMBOL
ldrb w17, [x17, TPIDR2_SYMBOL_OFFSET]
cbz x17, 2f
tbz x17, #FEAT_SME_BIT, 2f
0:
mrs x17, SVCR
tbz x17, #SVCR_PSTATE_SM_BIT, 2f
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/lib/builtins/cpu_model/aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ struct {
#include "aarch64/fmv/getauxval.inc"
#elif defined(_WIN32)
#include "aarch64/fmv/windows.inc"
#elif defined(ENABLE_BAREMETAL_AARCH64_SME_FMV_FEATURES)
#include "aarch64/fmv/baremetal_sme.inc"
#else
#include "aarch64/fmv/unimplemented.inc"
#endif
Expand Down
30 changes: 30 additions & 0 deletions compiler-rt/lib/builtins/cpu_model/aarch64/fmv/baremetal_sme.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// For baremetal platforms, we don't really initialise '__aarch64_cpu_features',
// with exception of FEAT_SME that we can get from '__aarch64_sme_accessible'.

#if defined(COMPILER_RT_SHARED_LIB)
__attribute__((weak))
#endif
extern _Bool __aarch64_sme_accessible(void);

static _Bool has_sme(void) {
#if defined(COMPILER_RT_SHARED_LIB)
if (!__aarch64_sme_accessible)
return 0;
#endif
return __aarch64_sme_accessible();
}

void __init_cpu_features_resolver(unsigned long hwcap,
const __ifunc_arg_t *arg) { }

void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) {
// CPU features already initialized.
if (__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED))
return;

unsigned long long feat = 0;
if (has_sme())
feat |= 1ULL << FEAT_SME;

__atomic_store_n(&__aarch64_cpu_features.features, feat, __ATOMIC_RELAXED);
}

0 comments on commit 8db75c0

Please sign in to comment.