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