xref: /llvm-project/llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.cpp (revision 2ce168baed02c7a6fdb039f4a2d9e48dee31e5c9)
1 //===-- AArch64SMEAttributes.cpp - Helper for interpreting SME attributes -===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "AArch64SMEAttributes.h"
10 #include "llvm/IR/InstrTypes.h"
11 #include <cassert>
12 
13 using namespace llvm;
14 
15 void SMEAttrs::set(unsigned M, bool Enable) {
16   if (Enable)
17     Bitmask |= M;
18   else
19     Bitmask &= ~M;
20 
21   // Streaming Mode Attrs
22   assert(!(hasStreamingInterface() && hasStreamingCompatibleInterface()) &&
23          "SM_Enabled and SM_Compatible are mutually exclusive");
24 
25   // ZA Attrs
26   assert(!(isNewZA() && (Bitmask & SME_ABI_Routine)) &&
27          "ZA_New and SME_ABI_Routine are mutually exclusive");
28 
29   assert(
30       (!sharesZA() ||
31        (isNewZA() ^ isInZA() ^ isInOutZA() ^ isOutZA() ^ isPreservesZA())) &&
32       "Attributes 'aarch64_new_za', 'aarch64_in_za', 'aarch64_out_za', "
33       "'aarch64_inout_za' and 'aarch64_preserves_za' are mutually exclusive");
34 
35   // ZT0 Attrs
36   assert(
37       (!sharesZT0() || (isNewZT0() ^ isInZT0() ^ isInOutZT0() ^ isOutZT0() ^
38                         isPreservesZT0())) &&
39       "Attributes 'aarch64_new_zt0', 'aarch64_in_zt0', 'aarch64_out_zt0', "
40       "'aarch64_inout_zt0' and 'aarch64_preserves_zt0' are mutually exclusive");
41 
42   assert(!(hasAgnosticZAInterface() && hasSharedZAInterface()) &&
43          "Function cannot have a shared-ZA interface and an agnostic-ZA "
44          "interface");
45 }
46 
47 SMEAttrs::SMEAttrs(const CallBase &CB) {
48   *this = SMEAttrs(CB.getAttributes());
49   if (auto *F = CB.getCalledFunction()) {
50     set(SMEAttrs(*F).Bitmask | SMEAttrs(F->getName()).Bitmask);
51   }
52 }
53 
54 SMEAttrs::SMEAttrs(StringRef FuncName) : Bitmask(0) {
55   if (FuncName == "__arm_tpidr2_save" || FuncName == "__arm_sme_state")
56     Bitmask |= (SMEAttrs::SM_Compatible | SMEAttrs::SME_ABI_Routine);
57   if (FuncName == "__arm_tpidr2_restore")
58     Bitmask |= SMEAttrs::SM_Compatible | encodeZAState(StateValue::In) |
59                SMEAttrs::SME_ABI_Routine;
60   if (FuncName == "__arm_sc_memcpy" || FuncName == "__arm_sc_memset" ||
61       FuncName == "__arm_sc_memmove" || FuncName == "__arm_sc_memchr")
62     Bitmask |= SMEAttrs::SM_Compatible;
63   if (FuncName == "__arm_sme_save" || FuncName == "__arm_sme_restore" ||
64       FuncName == "__arm_sme_state_size")
65     Bitmask |= SMEAttrs::SM_Compatible | SMEAttrs::SME_ABI_Routine;
66 }
67 
68 SMEAttrs::SMEAttrs(const AttributeList &Attrs) {
69   Bitmask = 0;
70   if (Attrs.hasFnAttr("aarch64_pstate_sm_enabled"))
71     Bitmask |= SM_Enabled;
72   if (Attrs.hasFnAttr("aarch64_pstate_sm_compatible"))
73     Bitmask |= SM_Compatible;
74   if (Attrs.hasFnAttr("aarch64_pstate_sm_body"))
75     Bitmask |= SM_Body;
76   if (Attrs.hasFnAttr("aarch64_za_state_agnostic"))
77     Bitmask |= ZA_State_Agnostic;
78   if (Attrs.hasFnAttr("aarch64_in_za"))
79     Bitmask |= encodeZAState(StateValue::In);
80   if (Attrs.hasFnAttr("aarch64_out_za"))
81     Bitmask |= encodeZAState(StateValue::Out);
82   if (Attrs.hasFnAttr("aarch64_inout_za"))
83     Bitmask |= encodeZAState(StateValue::InOut);
84   if (Attrs.hasFnAttr("aarch64_preserves_za"))
85     Bitmask |= encodeZAState(StateValue::Preserved);
86   if (Attrs.hasFnAttr("aarch64_new_za"))
87     Bitmask |= encodeZAState(StateValue::New);
88   if (Attrs.hasFnAttr("aarch64_in_zt0"))
89     Bitmask |= encodeZT0State(StateValue::In);
90   if (Attrs.hasFnAttr("aarch64_out_zt0"))
91     Bitmask |= encodeZT0State(StateValue::Out);
92   if (Attrs.hasFnAttr("aarch64_inout_zt0"))
93     Bitmask |= encodeZT0State(StateValue::InOut);
94   if (Attrs.hasFnAttr("aarch64_preserves_zt0"))
95     Bitmask |= encodeZT0State(StateValue::Preserved);
96   if (Attrs.hasFnAttr("aarch64_new_zt0"))
97     Bitmask |= encodeZT0State(StateValue::New);
98 }
99 
100 bool SMEAttrs::requiresSMChange(const SMEAttrs &Callee) const {
101   if (Callee.hasStreamingCompatibleInterface())
102     return false;
103 
104   // Both non-streaming
105   if (hasNonStreamingInterfaceAndBody() && Callee.hasNonStreamingInterface())
106     return false;
107 
108   // Both streaming
109   if (hasStreamingInterfaceOrBody() && Callee.hasStreamingInterface())
110     return false;
111 
112   return true;
113 }
114