// Detects whether FEAT_SME is available. // // FEAT_SME is optional from Armv9.2.
[[maybe_unused]] staticbool sme_is_enabled() { return ((getauxval(AT_HWCAP2) & HWCAP2_SME) != 0);
}
// Sets PSTATE.SM to 0. // // Requires FEAT_SME, which is optional from Armv9.2.
[[maybe_unused]] __attribute__((naked)) staticvoid sme_disable_sm() {
__asm__ __volatile__(".arch_extension sme; bti c; smstop sm; ret;");
}
// Sets PSTATE.ZA to 1. // // Requires FEAT_SME, which is optional from Armv9.2.
[[maybe_unused]] __attribute__((naked)) staticvoid sme_enable_za() {
__asm__ __volatile__(".arch_extension sme; bti c; smstart za; ret;");
}
// Sets PSTATE.ZA to 0. // // Requires FEAT_SME, which is optional from Armv9.2.
[[maybe_unused]] __attribute__((naked)) staticvoid sme_disable_za() {
__asm__ __volatile__(".arch_extension sme; bti c; smstop za; ret;");
}
// Sets TPIDR2_EL0 to a given value. // // Requires FEAT_SME, which is optional from Armv9.2.
[[maybe_unused]] __attribute__((naked)) staticvoid sme_set_tpidr2_el0(uint64_t value) {
__asm__ __volatile__(".arch_extension sme; bti c; msr TPIDR2_EL0, x0; ret;");
}
// Reads TPIDR2_EL0 and returns its value. // // Requires FEAT_SME, which is optional from Armv9.2.
[[maybe_unused]] __attribute__((naked)) static uint64_t sme_tpidr2_el0() {
__asm__ __volatile__(".arch_extension sme; bti c; mrs x0, TPIDR2_EL0; ret;");
}
// Reads SVCR special register. // // Requires FEAT_SME, which is optional from Armv9.2.
[[maybe_unused]] __attribute__((naked)) static uint64_t sme_read_svcr() {
__asm__ __volatile__(".arch_extension sme; bti c; mrs x0, SVCR; ret;");
}
// Reads Streaming SVE vector size in bytes. // // Requires FEAT_SME, which is optional from Armv9.2.
[[maybe_unused]] __attribute__((naked)) static uint16_t sme_get_svl() {
__asm__ __volatile__(".arch_extension sme; bti c; rdsvl x0, 1; ret;");
}
// Returns true if PSTATE.SM is 1, otherwise false. // // Requires FEAT_SME, which is optional from Armv9.2.
[[maybe_unused]] staticbool sme_is_sm_on() { static constexpr uint64_t kSvcrSmMask = 0x01UL; return ((sme_read_svcr() & kSvcrSmMask) != 0);
}
// Returns true if PSTATE.ZA is 1, otherwise false. // // Requires FEAT_SME, which is optional from Armv9.2.
[[maybe_unused]] staticbool sme_is_za_on() { static constexpr uint64_t kSvcrZaMask = 0x02UL; return ((sme_read_svcr() & kSvcrZaMask) != 0);
}
// Assembly is required to ensure the test does not depend on compiler optimizations.
[[maybe_unused]] __attribute__((naked)) staticvoid sme_dormant_caller(void (*fn_address)()) { // clang-format off
__asm__ __volatile__( ".arch_extension sme\n\r" "bti c\n\r" "stp fp, lr, [sp, #-16]!\n\r" "mov fp, sp\n\r" // Set up a lazy-save buffer on the stack. // It is 16 bytes + size according to VL. "sub sp, sp, #16\n\r" "rdsvl x8, #1\n\r" "mul x9, x8, x8\n\r" "sub sp, sp, x9\n\r" "mov x9, sp\n\r" // Bytes 0-7: za_save_buffer // Bytes 8-9: num_za_save_slices // Other bytes are cleared. "stp x9, x8, [fp, #-16]\n\r" "sub x9, fp, #16\n\r" // Finalize the lazy-save buffer. "msr TPIDR2_EL0, x9\n\r" // Call the given function with dormant SME state. "smstart za\n\r" "blr x0\n\r" // Set SME state to off. "msr TPIDR2_EL0, xzr\n\r" "smstop za\n\r" "mov sp, fp\n\r" "ldp fp, lr, [sp], #16\n\r" "ret\n\r"
); // clang-format on
}
// 'buf' is an 'svl'*'svl' size ZA save buffer (must be aligned to 16 bytes).
[[maybe_unused]] staticvoid sme_enable_za_active_state(uint8_t* buf, uint16_t svl) { // Enable PSTATE.ZA.
sme_enable_za(); // Fill za_save_buffer with some data.
memset(buf, 0xa, svl * svl); // Restore ZA from the save buffer. struct tpidr2_blk {
uint8_t* za_save_buffer;
uint16_t num_za_save_slices;
uint8_t pad[6];
} tpidr2_blk = { .za_save_buffer = buf, .num_za_save_slices = svl };
__arm_tpidr2_restore(reinterpret_cast<uint64_t>(&tpidr2_blk)); // Set TPIDR2 to 0.
sme_set_tpidr2_el0(0UL);
}
// Turns all SME state off. // // Requires FEAT_SME, which is optional from Armv9.2.
[[maybe_unused]] staticvoid sme_state_cleanup() {
sme_disable_sm();
sme_set_tpidr2_el0(0UL);
sme_disable_za();
}
#endif// defined(__aarch64__)
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.