Skip to content

Commit 6da6772

Browse files
[AArch64][SME] Rewrite __arm_get_current_vg to preserve required registers (llvm#100143)
The documentation for the __arm_get_current_vg support routine specifies that the following registers are call-preserved: - X1-X15, X19-X29 and SP - Z0-Z31 - P0-P15 This patch rewrites the implementation of this routine in compiler-rt, as the current version does not guarantee that these registers will be preserved.
1 parent b9995a1 commit 6da6772

File tree

2 files changed

+44
-28
lines changed

2 files changed

+44
-28
lines changed

compiler-rt/lib/builtins/aarch64/sme-abi-vg.c

-28
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,6 @@ struct FEATURES {
1010

1111
extern struct FEATURES __aarch64_cpu_features;
1212

13-
struct SME_STATE {
14-
long PSTATE;
15-
long TPIDR2_EL0;
16-
};
17-
18-
extern struct SME_STATE __arm_sme_state(void) __arm_streaming_compatible;
19-
20-
extern bool __aarch64_has_sme_and_tpidr2_el0;
21-
2213
#if __GNUC__ >= 9
2314
#pragma GCC diagnostic ignored "-Wprio-ctor-dtor"
2415
#endif
@@ -28,22 +19,3 @@ __attribute__((constructor(90))) static void get_aarch64_cpu_features(void) {
2819

2920
__init_cpu_features();
3021
}
31-
32-
__attribute__((target("sve"))) long
33-
__arm_get_current_vg(void) __arm_streaming_compatible {
34-
struct SME_STATE State = __arm_sme_state();
35-
unsigned long long features =
36-
__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED);
37-
bool HasSVE = features & (1ULL << FEAT_SVE);
38-
39-
if (!HasSVE && !__aarch64_has_sme_and_tpidr2_el0)
40-
return 0;
41-
42-
if (HasSVE || (State.PSTATE & 1)) {
43-
long vl;
44-
__asm__ __volatile__("cntd %0" : "=r"(vl));
45-
return vl;
46-
}
47-
48-
return 0;
49-
}

compiler-rt/lib/builtins/aarch64/sme-abi.S

+44
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@
1212
#if !defined(__APPLE__)
1313
#define TPIDR2_SYMBOL SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0)
1414
#define TPIDR2_SYMBOL_OFFSET :lo12:SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0)
15+
#define CPU_FEATS_SYMBOL SYMBOL_NAME(__aarch64_cpu_features)
16+
#define CPU_FEATS_SYMBOL_OFFSET :lo12:SYMBOL_NAME(__aarch64_cpu_features)
1517
#else
1618
// MachO requires @page/@pageoff directives because the global is defined
1719
// in a different file. Otherwise this file may fail to build.
1820
#define TPIDR2_SYMBOL SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0)@page
1921
#define TPIDR2_SYMBOL_OFFSET SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0)@pageoff
22+
#define CPU_FEATS_SYMBOL SYMBOL_NAME(__aarch64_cpu_features)@page
23+
#define CPU_FEATS_SYMBOL_OFFSET SYMBOL_NAME(__aarch64_cpu_features)@pageoff
2024
#endif
2125

2226
.arch armv9-a+sme
@@ -180,6 +184,46 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_za_disable)
180184
ret
181185
END_COMPILERRT_OUTLINE_FUNCTION(__arm_za_disable)
182186

187+
DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_get_current_vg)
188+
.variant_pcs __arm_get_current_vg
189+
BTI_C
190+
191+
stp x29, x30, [sp, #-16]!
192+
.cfi_def_cfa_offset 16
193+
mov x29, sp
194+
.cfi_def_cfa w29, 16
195+
.cfi_offset w30, -8
196+
.cfi_offset w29, -16
197+
adrp x17, CPU_FEATS_SYMBOL
198+
ldr w17, [x17, CPU_FEATS_SYMBOL_OFFSET]
199+
tbnz w17, #30, 0f
200+
adrp x16, TPIDR2_SYMBOL
201+
ldrb w16, [x16, TPIDR2_SYMBOL_OFFSET]
202+
cbz w16, 1f
203+
0:
204+
mov x18, x1
205+
bl __arm_sme_state
206+
mov x1, x18
207+
and x17, x17, #0x40000000
208+
bfxil x17, x0, #0, #1
209+
cbz x17, 1f
210+
cntd x0
211+
.cfi_def_cfa wsp, 16
212+
ldp x29, x30, [sp], #16
213+
.cfi_def_cfa_offset 0
214+
.cfi_restore w30
215+
.cfi_restore w29
216+
ret
217+
1:
218+
mov x0, xzr
219+
.cfi_def_cfa wsp, 16
220+
ldp x29, x30, [sp], #16
221+
.cfi_def_cfa_offset 0
222+
.cfi_restore w30
223+
.cfi_restore w29
224+
ret
225+
END_COMPILERRT_OUTLINE_FUNCTION(__arm_get_current_vg)
226+
183227
NO_EXEC_STACK_DIRECTIVE
184228

185229
// GNU property note for BTI and PAC

0 commit comments

Comments
 (0)