Path: blob/main/contrib/llvm-project/compiler-rt/lib/builtins/aarch64/sme-abi.S
35291 views
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.1// See https://llvm.org/LICENSE.txt for license information.2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception34// This patch implements the support routines for the SME ABI,5// described here:6// https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#sme-support-routines78#include "../assembly.h"91011#if !defined(__APPLE__)12#define TPIDR2_SYMBOL SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0)13#define TPIDR2_SYMBOL_OFFSET :lo12:SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0)14#define CPU_FEATS_SYMBOL SYMBOL_NAME(__aarch64_cpu_features)15#define CPU_FEATS_SYMBOL_OFFSET :lo12:SYMBOL_NAME(__aarch64_cpu_features)16#else17// MachO requires @page/@pageoff directives because the global is defined18// in a different file. Otherwise this file may fail to build.19#define TPIDR2_SYMBOL SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0)@page20#define TPIDR2_SYMBOL_OFFSET SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0)@pageoff21#define CPU_FEATS_SYMBOL SYMBOL_NAME(__aarch64_cpu_features)@page22#define CPU_FEATS_SYMBOL_OFFSET SYMBOL_NAME(__aarch64_cpu_features)@pageoff23#endif2425.arch armv9-a+sme2627// Utility function which calls a system's abort() routine. Because the function28// is streaming-compatible it should disable streaming-SVE mode before calling29// abort(). Note that there is no need to preserve any state before the call,30// because the function does not return.31DEFINE_COMPILERRT_PRIVATE_FUNCTION(do_abort)32.cfi_startproc33.variant_pcs SYMBOL_NAME(do_abort)34BTI_C35stp x29, x30, [sp, #-32]!36cntd x037// Store VG to a stack location that we describe with .cfi_offset38str x0, [sp, #16]39.cfi_def_cfa_offset 3240.cfi_offset w30, -2441.cfi_offset w29, -3242.cfi_offset 46, -1643bl __arm_sme_state44tbz x0, #0, 2f451:46smstop sm472:48// We can't make this into a tail-call because the unwinder would49// need to restore the value of VG.50bl SYMBOL_NAME(abort)51.cfi_endproc52END_COMPILERRT_FUNCTION(do_abort)5354// __arm_sme_state fills the result registers based on a local55// that is set as part of the compiler-rt startup code.56// __aarch64_has_sme_and_tpidr2_el057DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_sme_state)58.variant_pcs __arm_sme_state59BTI_C60mov x0, xzr61mov x1, xzr6263adrp x16, TPIDR2_SYMBOL64ldrb w16, [x16, TPIDR2_SYMBOL_OFFSET]65cbz w16, 1f660:67orr x0, x0, #0xC00000000000000068mrs x16, SVCR69bfxil x0, x16, #0, #270mrs x1, TPIDR2_EL0711:72ret73END_COMPILERRT_OUTLINE_FUNCTION(__arm_sme_state)7475DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_tpidr2_restore)76.variant_pcs __arm_tpidr2_restore77BTI_C78// If TPIDR2_EL0 is nonnull, the subroutine aborts in some platform-specific79// manner.80mrs x14, TPIDR2_EL081cbnz x14, 2f8283// If any of the reserved bytes in the first 16 bytes of BLK are nonzero,84// the subroutine [..] aborts in some platform-defined manner.85ldrh w14, [x0, #10]86cbnz w14, 2f87ldr w14, [x0, #12]88cbnz w14, 2f8990// If BLK.za_save_buffer is NULL, the subroutine does nothing.91ldr x16, [x0]92cbz x16, 1f9394// If BLK.num_za_save_slices is zero, the subroutine does nothing.95ldrh w14, [x0, #8]96cbz x14, 1f9798mov x15, xzr990:100ldr za[w15,0], [x16]101addsvl x16, x16, #1102add x15, x15, #1103cmp x14, x15104b.ne 0b1051:106ret1072:108b SYMBOL_NAME(do_abort)109END_COMPILERRT_OUTLINE_FUNCTION(__arm_tpidr2_restore)110111DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_tpidr2_save)112.variant_pcs __arm_tpidr2_restore113BTI_C114// If the current thread does not have access to TPIDR2_EL0, the subroutine115// does nothing.116adrp x14, TPIDR2_SYMBOL117ldrb w14, [x14, TPIDR2_SYMBOL_OFFSET]118cbz w14, 1f119120// If TPIDR2_EL0 is null, the subroutine does nothing.121mrs x16, TPIDR2_EL0122cbz x16, 1f123124// If any of the reserved bytes in the first 16 bytes of the TPIDR2 block are125// nonzero, the subroutine [..] aborts in some platform-defined manner.126ldrh w14, [x16, #10]127cbnz w14, 2f128ldr w14, [x16, #12]129cbnz w14, 2f130131// If num_za_save_slices is zero, the subroutine does nothing.132ldrh w14, [x16, #8]133cbz x14, 1f134135// If za_save_buffer is NULL, the subroutine does nothing.136ldr x16, [x16]137cbz x16, 1f138139mov x15, xzr1400:141str za[w15,0], [x16]142addsvl x16, x16, #1143add x15, x15, #1144cmp x14, x15145b.ne 0b1461:147ret1482:149b SYMBOL_NAME(do_abort)150END_COMPILERRT_OUTLINE_FUNCTION(__arm_tpidr2_save)151152DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_za_disable)153.variant_pcs __arm_tpidr2_restore154BTI_C155// If the current thread does not have access to SME, the subroutine does156// nothing.157adrp x14, TPIDR2_SYMBOL158ldrb w14, [x14, TPIDR2_SYMBOL_OFFSET]159cbz w14, 0f160161// Otherwise, the subroutine behaves as if it did the following:162// * Call __arm_tpidr2_save.163stp x29, x30, [sp, #-16]!164.cfi_def_cfa_offset 16165mov x29, sp166.cfi_def_cfa w29, 16167.cfi_offset w30, -8168.cfi_offset w29, -16169bl __arm_tpidr2_save170171// * Set TPIDR2_EL0 to null.172msr TPIDR2_EL0, xzr173174// * Set PSTATE.ZA to 0.175smstop za176177.cfi_def_cfa wsp, 16178ldp x29, x30, [sp], #16179.cfi_def_cfa_offset 0180.cfi_restore w30181.cfi_restore w291820:183ret184END_COMPILERRT_OUTLINE_FUNCTION(__arm_za_disable)185186DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_get_current_vg)187.variant_pcs __arm_get_current_vg188BTI_C189190stp x29, x30, [sp, #-16]!191.cfi_def_cfa_offset 16192mov x29, sp193.cfi_def_cfa w29, 16194.cfi_offset w30, -8195.cfi_offset w29, -16196adrp x17, CPU_FEATS_SYMBOL197ldr w17, [x17, CPU_FEATS_SYMBOL_OFFSET]198tbnz w17, #30, 0f199adrp x16, TPIDR2_SYMBOL200ldrb w16, [x16, TPIDR2_SYMBOL_OFFSET]201cbz w16, 1f2020:203mov x18, x1204bl __arm_sme_state205mov x1, x18206and x17, x17, #0x40000000207bfxil x17, x0, #0, #1208cbz x17, 1f209cntd x0210.cfi_def_cfa wsp, 16211ldp x29, x30, [sp], #16212.cfi_def_cfa_offset 0213.cfi_restore w30214.cfi_restore w29215ret2161:217mov x0, xzr218.cfi_def_cfa wsp, 16219ldp x29, x30, [sp], #16220.cfi_def_cfa_offset 0221.cfi_restore w30222.cfi_restore w29223ret224END_COMPILERRT_OUTLINE_FUNCTION(__arm_get_current_vg)225226NO_EXEC_STACK_DIRECTIVE227228// GNU property note for BTI and PAC229GNU_PROPERTY_BTI_PAC230231232