xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.cpp (revision 9207f9d206a4017001f01ca27d3d25a26c268a95)
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(!(hasNewZABody() && sharesZA()) &&
27          "ZA_New and ZA_Shared are mutually exclusive");
28   assert(!(hasNewZABody() && preservesZA()) &&
29          "ZA_New and ZA_Preserved are mutually exclusive");
30   assert(!(hasNewZABody() && (Bitmask & SME_ABI_Routine)) &&
31          "ZA_New and SME_ABI_Routine are mutually exclusive");
32 
33   // ZT0 Attrs
34   assert(
35       (!sharesZT0() || (isNewZT0() ^ isInZT0() ^ isInOutZT0() ^ isOutZT0() ^
36                         isPreservesZT0())) &&
37       "Attributes 'aarch64_new_zt0', 'aarch64_in_zt0', 'aarch64_out_zt0', "
38       "'aarch64_inout_zt0' and 'aarch64_preserves_zt0' are mutually exclusive");
39 }
40 
41 SMEAttrs::SMEAttrs(const CallBase &CB) {
42   *this = SMEAttrs(CB.getAttributes());
43   if (auto *F = CB.getCalledFunction()) {
44     set(SMEAttrs(*F).Bitmask | SMEAttrs(F->getName()).Bitmask);
45   }
46 }
47 
48 SMEAttrs::SMEAttrs(StringRef FuncName) : Bitmask(0) {
49   if (FuncName == "__arm_tpidr2_save" || FuncName == "__arm_sme_state")
50     Bitmask |= (SMEAttrs::SM_Compatible | SMEAttrs::SME_ABI_Routine);
51   if (FuncName == "__arm_tpidr2_restore")
52     Bitmask |= (SMEAttrs::SM_Compatible | SMEAttrs::ZA_Shared |
53                 SMEAttrs::SME_ABI_Routine);
54 }
55 
56 SMEAttrs::SMEAttrs(const AttributeList &Attrs) {
57   Bitmask = 0;
58   if (Attrs.hasFnAttr("aarch64_pstate_sm_enabled"))
59     Bitmask |= SM_Enabled;
60   if (Attrs.hasFnAttr("aarch64_pstate_sm_compatible"))
61     Bitmask |= SM_Compatible;
62   if (Attrs.hasFnAttr("aarch64_pstate_sm_body"))
63     Bitmask |= SM_Body;
64   if (Attrs.hasFnAttr("aarch64_pstate_za_shared"))
65     Bitmask |= ZA_Shared;
66   if (Attrs.hasFnAttr("aarch64_pstate_za_new"))
67     Bitmask |= ZA_New;
68   if (Attrs.hasFnAttr("aarch64_pstate_za_preserved"))
69     Bitmask |= ZA_Preserved;
70   if (Attrs.hasFnAttr("aarch64_in_zt0"))
71     Bitmask |= encodeZT0State(StateValue::In);
72   if (Attrs.hasFnAttr("aarch64_out_zt0"))
73     Bitmask |= encodeZT0State(StateValue::Out);
74   if (Attrs.hasFnAttr("aarch64_inout_zt0"))
75     Bitmask |= encodeZT0State(StateValue::InOut);
76   if (Attrs.hasFnAttr("aarch64_preserves_zt0"))
77     Bitmask |= encodeZT0State(StateValue::Preserved);
78   if (Attrs.hasFnAttr("aarch64_new_zt0"))
79     Bitmask |= encodeZT0State(StateValue::New);
80 }
81 
82 bool SMEAttrs::requiresSMChange(const SMEAttrs &Callee) const {
83   if (Callee.hasStreamingCompatibleInterface())
84     return false;
85 
86   // Both non-streaming
87   if (hasNonStreamingInterfaceAndBody() && Callee.hasNonStreamingInterface())
88     return false;
89 
90   // Both streaming
91   if (hasStreamingInterfaceOrBody() && Callee.hasStreamingInterface())
92     return false;
93 
94   return true;
95 }
96