1 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 2 // See https://llvm.org/LICENSE.txt for license information. 3 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 4 5 #include "../cpu_model/aarch64.h" 6 7 struct FEATURES { 8 unsigned long long features; 9 }; 10 11 extern struct FEATURES __aarch64_cpu_features; 12 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 22 #if __GNUC__ >= 9 23 #pragma GCC diagnostic ignored "-Wprio-ctor-dtor" 24 #endif 25 __attribute__((constructor(90))) static void get_aarch64_cpu_features(void) { 26 if (__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED)) 27 return; 28 29 __init_cpu_features(); 30 } 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 } 50