xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AArch64/Utils/AArch64SMEAttributes.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1bdd1243dSDimitry Andric //===-- AArch64SMEAttributes.cpp - Helper for interpreting SME attributes -===//
2bdd1243dSDimitry Andric //
3bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bdd1243dSDimitry Andric //
7bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
8bdd1243dSDimitry Andric 
9bdd1243dSDimitry Andric #include "AArch64SMEAttributes.h"
10bdd1243dSDimitry Andric #include "llvm/IR/InstrTypes.h"
11bdd1243dSDimitry Andric #include <cassert>
12bdd1243dSDimitry Andric 
13bdd1243dSDimitry Andric using namespace llvm;
14bdd1243dSDimitry Andric 
15bdd1243dSDimitry Andric void SMEAttrs::set(unsigned M, bool Enable) {
16bdd1243dSDimitry Andric   if (Enable)
17bdd1243dSDimitry Andric     Bitmask |= M;
18bdd1243dSDimitry Andric   else
19bdd1243dSDimitry Andric     Bitmask &= ~M;
20bdd1243dSDimitry Andric 
217a6dacacSDimitry Andric   // Streaming Mode Attrs
22bdd1243dSDimitry Andric   assert(!(hasStreamingInterface() && hasStreamingCompatibleInterface()) &&
23bdd1243dSDimitry Andric          "SM_Enabled and SM_Compatible are mutually exclusive");
247a6dacacSDimitry Andric 
257a6dacacSDimitry Andric   // ZA Attrs
26*0fca6ea1SDimitry Andric   assert(!(isNewZA() && (Bitmask & SME_ABI_Routine)) &&
277a6dacacSDimitry Andric          "ZA_New and SME_ABI_Routine are mutually exclusive");
287a6dacacSDimitry Andric 
29*0fca6ea1SDimitry Andric   assert(
30*0fca6ea1SDimitry Andric       (!sharesZA() ||
31*0fca6ea1SDimitry Andric        (isNewZA() ^ isInZA() ^ isInOutZA() ^ isOutZA() ^ isPreservesZA())) &&
32*0fca6ea1SDimitry Andric       "Attributes 'aarch64_new_za', 'aarch64_in_za', 'aarch64_out_za', "
33*0fca6ea1SDimitry Andric       "'aarch64_inout_za' and 'aarch64_preserves_za' are mutually exclusive");
34*0fca6ea1SDimitry Andric 
357a6dacacSDimitry Andric   // ZT0 Attrs
367a6dacacSDimitry Andric   assert(
377a6dacacSDimitry Andric       (!sharesZT0() || (isNewZT0() ^ isInZT0() ^ isInOutZT0() ^ isOutZT0() ^
387a6dacacSDimitry Andric                         isPreservesZT0())) &&
397a6dacacSDimitry Andric       "Attributes 'aarch64_new_zt0', 'aarch64_in_zt0', 'aarch64_out_zt0', "
407a6dacacSDimitry Andric       "'aarch64_inout_zt0' and 'aarch64_preserves_zt0' are mutually exclusive");
41bdd1243dSDimitry Andric }
42bdd1243dSDimitry Andric 
43bdd1243dSDimitry Andric SMEAttrs::SMEAttrs(const CallBase &CB) {
44bdd1243dSDimitry Andric   *this = SMEAttrs(CB.getAttributes());
455f757f3fSDimitry Andric   if (auto *F = CB.getCalledFunction()) {
465f757f3fSDimitry Andric     set(SMEAttrs(*F).Bitmask | SMEAttrs(F->getName()).Bitmask);
475f757f3fSDimitry Andric   }
485f757f3fSDimitry Andric }
495f757f3fSDimitry Andric 
505f757f3fSDimitry Andric SMEAttrs::SMEAttrs(StringRef FuncName) : Bitmask(0) {
515f757f3fSDimitry Andric   if (FuncName == "__arm_tpidr2_save" || FuncName == "__arm_sme_state")
527a6dacacSDimitry Andric     Bitmask |= (SMEAttrs::SM_Compatible | SMEAttrs::SME_ABI_Routine);
535f757f3fSDimitry Andric   if (FuncName == "__arm_tpidr2_restore")
54*0fca6ea1SDimitry Andric     Bitmask |= SMEAttrs::SM_Compatible | encodeZAState(StateValue::In) |
55*0fca6ea1SDimitry Andric                SMEAttrs::SME_ABI_Routine;
56*0fca6ea1SDimitry Andric   if (FuncName == "__arm_sc_memcpy" || FuncName == "__arm_sc_memset" ||
57*0fca6ea1SDimitry Andric       FuncName == "__arm_sc_memmove" || FuncName == "__arm_sc_memchr")
58*0fca6ea1SDimitry Andric     Bitmask |= SMEAttrs::SM_Compatible;
59bdd1243dSDimitry Andric }
60bdd1243dSDimitry Andric 
61bdd1243dSDimitry Andric SMEAttrs::SMEAttrs(const AttributeList &Attrs) {
62bdd1243dSDimitry Andric   Bitmask = 0;
63bdd1243dSDimitry Andric   if (Attrs.hasFnAttr("aarch64_pstate_sm_enabled"))
64bdd1243dSDimitry Andric     Bitmask |= SM_Enabled;
65bdd1243dSDimitry Andric   if (Attrs.hasFnAttr("aarch64_pstate_sm_compatible"))
66bdd1243dSDimitry Andric     Bitmask |= SM_Compatible;
67bdd1243dSDimitry Andric   if (Attrs.hasFnAttr("aarch64_pstate_sm_body"))
68bdd1243dSDimitry Andric     Bitmask |= SM_Body;
69*0fca6ea1SDimitry Andric   if (Attrs.hasFnAttr("aarch64_in_za"))
70*0fca6ea1SDimitry Andric     Bitmask |= encodeZAState(StateValue::In);
71*0fca6ea1SDimitry Andric   if (Attrs.hasFnAttr("aarch64_out_za"))
72*0fca6ea1SDimitry Andric     Bitmask |= encodeZAState(StateValue::Out);
73*0fca6ea1SDimitry Andric   if (Attrs.hasFnAttr("aarch64_inout_za"))
74*0fca6ea1SDimitry Andric     Bitmask |= encodeZAState(StateValue::InOut);
75*0fca6ea1SDimitry Andric   if (Attrs.hasFnAttr("aarch64_preserves_za"))
76*0fca6ea1SDimitry Andric     Bitmask |= encodeZAState(StateValue::Preserved);
77*0fca6ea1SDimitry Andric   if (Attrs.hasFnAttr("aarch64_new_za"))
78*0fca6ea1SDimitry Andric     Bitmask |= encodeZAState(StateValue::New);
797a6dacacSDimitry Andric   if (Attrs.hasFnAttr("aarch64_in_zt0"))
807a6dacacSDimitry Andric     Bitmask |= encodeZT0State(StateValue::In);
817a6dacacSDimitry Andric   if (Attrs.hasFnAttr("aarch64_out_zt0"))
827a6dacacSDimitry Andric     Bitmask |= encodeZT0State(StateValue::Out);
837a6dacacSDimitry Andric   if (Attrs.hasFnAttr("aarch64_inout_zt0"))
847a6dacacSDimitry Andric     Bitmask |= encodeZT0State(StateValue::InOut);
857a6dacacSDimitry Andric   if (Attrs.hasFnAttr("aarch64_preserves_zt0"))
867a6dacacSDimitry Andric     Bitmask |= encodeZT0State(StateValue::Preserved);
877a6dacacSDimitry Andric   if (Attrs.hasFnAttr("aarch64_new_zt0"))
887a6dacacSDimitry Andric     Bitmask |= encodeZT0State(StateValue::New);
89bdd1243dSDimitry Andric }
90bdd1243dSDimitry Andric 
917a6dacacSDimitry Andric bool SMEAttrs::requiresSMChange(const SMEAttrs &Callee) const {
92bdd1243dSDimitry Andric   if (Callee.hasStreamingCompatibleInterface())
937a6dacacSDimitry Andric     return false;
94bdd1243dSDimitry Andric 
95bdd1243dSDimitry Andric   // Both non-streaming
96bdd1243dSDimitry Andric   if (hasNonStreamingInterfaceAndBody() && Callee.hasNonStreamingInterface())
977a6dacacSDimitry Andric     return false;
98bdd1243dSDimitry Andric 
99bdd1243dSDimitry Andric   // Both streaming
100bdd1243dSDimitry Andric   if (hasStreamingInterfaceOrBody() && Callee.hasStreamingInterface())
1017a6dacacSDimitry Andric     return false;
102bdd1243dSDimitry Andric 
1037a6dacacSDimitry Andric   return true;
104bdd1243dSDimitry Andric }
105