xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1bdd1243dSDimitry Andric //===-- SPIRVBaseInfo.cpp - Top level SPIRV definitions ---------*- C++ -*-===//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric //
9bdd1243dSDimitry Andric // This file contains the implementation for helper mnemonic lookup functions,
10bdd1243dSDimitry Andric // versioning/capabilities/extensions getters for symbolic/named operands used
11bdd1243dSDimitry Andric // in various SPIR-V instructions.
1281ad6265SDimitry Andric //
1381ad6265SDimitry Andric //===----------------------------------------------------------------------===//
1481ad6265SDimitry Andric 
1581ad6265SDimitry Andric #include "SPIRVBaseInfo.h"
16bdd1243dSDimitry Andric #include "llvm/ADT/ArrayRef.h"
17bdd1243dSDimitry Andric #include "llvm/ADT/StringRef.h"
1881ad6265SDimitry Andric 
1981ad6265SDimitry Andric namespace llvm {
2081ad6265SDimitry Andric namespace SPIRV {
21bdd1243dSDimitry Andric struct SymbolicOperand {
22bdd1243dSDimitry Andric   OperandCategory::OperandCategory Category;
23bdd1243dSDimitry Andric   uint32_t Value;
24bdd1243dSDimitry Andric   StringRef Mnemonic;
25bdd1243dSDimitry Andric   uint32_t MinVersion;
26bdd1243dSDimitry Andric   uint32_t MaxVersion;
2781ad6265SDimitry Andric };
2881ad6265SDimitry Andric 
29bdd1243dSDimitry Andric struct ExtensionEntry {
30bdd1243dSDimitry Andric   OperandCategory::OperandCategory Category;
31bdd1243dSDimitry Andric   uint32_t Value;
32bdd1243dSDimitry Andric   Extension::Extension ReqExtension;
3381ad6265SDimitry Andric };
3481ad6265SDimitry Andric 
35bdd1243dSDimitry Andric struct CapabilityEntry {
36bdd1243dSDimitry Andric   OperandCategory::OperandCategory Category;
37bdd1243dSDimitry Andric   uint32_t Value;
38bdd1243dSDimitry Andric   Capability::Capability ReqCapability;
3981ad6265SDimitry Andric };
4081ad6265SDimitry Andric 
41bdd1243dSDimitry Andric using namespace OperandCategory;
42bdd1243dSDimitry Andric using namespace Extension;
43bdd1243dSDimitry Andric using namespace Capability;
44bdd1243dSDimitry Andric using namespace InstructionSet;
45bdd1243dSDimitry Andric #define GET_SymbolicOperands_DECL
46bdd1243dSDimitry Andric #define GET_SymbolicOperands_IMPL
47bdd1243dSDimitry Andric #define GET_ExtensionEntries_DECL
48bdd1243dSDimitry Andric #define GET_ExtensionEntries_IMPL
49bdd1243dSDimitry Andric #define GET_CapabilityEntries_DECL
50bdd1243dSDimitry Andric #define GET_CapabilityEntries_IMPL
51bdd1243dSDimitry Andric #define GET_ExtendedBuiltins_DECL
52bdd1243dSDimitry Andric #define GET_ExtendedBuiltins_IMPL
53bdd1243dSDimitry Andric #include "SPIRVGenTables.inc"
5481ad6265SDimitry Andric } // namespace SPIRV
55bdd1243dSDimitry Andric 
56bdd1243dSDimitry Andric std::string
57bdd1243dSDimitry Andric getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category,
58bdd1243dSDimitry Andric                            int32_t Value) {
59bdd1243dSDimitry Andric   const SPIRV::SymbolicOperand *Lookup =
60bdd1243dSDimitry Andric       SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
61bdd1243dSDimitry Andric   // Value that encodes just one enum value.
62bdd1243dSDimitry Andric   if (Lookup)
63bdd1243dSDimitry Andric     return Lookup->Mnemonic.str();
64bdd1243dSDimitry Andric   if (Category != SPIRV::OperandCategory::ImageOperandOperand &&
65bdd1243dSDimitry Andric       Category != SPIRV::OperandCategory::FPFastMathModeOperand &&
66bdd1243dSDimitry Andric       Category != SPIRV::OperandCategory::SelectionControlOperand &&
67bdd1243dSDimitry Andric       Category != SPIRV::OperandCategory::LoopControlOperand &&
68bdd1243dSDimitry Andric       Category != SPIRV::OperandCategory::FunctionControlOperand &&
69bdd1243dSDimitry Andric       Category != SPIRV::OperandCategory::MemorySemanticsOperand &&
70bdd1243dSDimitry Andric       Category != SPIRV::OperandCategory::MemoryOperandOperand &&
71bdd1243dSDimitry Andric       Category != SPIRV::OperandCategory::KernelProfilingInfoOperand)
72bdd1243dSDimitry Andric     return "UNKNOWN";
73bdd1243dSDimitry Andric   // Value that encodes many enum values (one bit per enum value).
74bdd1243dSDimitry Andric   std::string Name;
75bdd1243dSDimitry Andric   std::string Separator;
76bdd1243dSDimitry Andric   const SPIRV::SymbolicOperand *EnumValueInCategory =
77bdd1243dSDimitry Andric       SPIRV::lookupSymbolicOperandByCategory(Category);
78bdd1243dSDimitry Andric 
79bdd1243dSDimitry Andric   while (EnumValueInCategory && EnumValueInCategory->Category == Category) {
80bdd1243dSDimitry Andric     if ((EnumValueInCategory->Value != 0) &&
81bdd1243dSDimitry Andric         (Value & EnumValueInCategory->Value)) {
82bdd1243dSDimitry Andric       Name += Separator + EnumValueInCategory->Mnemonic.str();
83bdd1243dSDimitry Andric       Separator = "|";
84bdd1243dSDimitry Andric     }
85bdd1243dSDimitry Andric     ++EnumValueInCategory;
86bdd1243dSDimitry Andric   }
87bdd1243dSDimitry Andric 
88bdd1243dSDimitry Andric   return Name;
89bdd1243dSDimitry Andric }
90bdd1243dSDimitry Andric 
91*0fca6ea1SDimitry Andric VersionTuple
92bdd1243dSDimitry Andric getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category,
93bdd1243dSDimitry Andric                              uint32_t Value) {
94bdd1243dSDimitry Andric   const SPIRV::SymbolicOperand *Lookup =
95bdd1243dSDimitry Andric       SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
96bdd1243dSDimitry Andric 
97bdd1243dSDimitry Andric   if (Lookup)
98*0fca6ea1SDimitry Andric     return VersionTuple(Lookup->MinVersion / 10, Lookup->MinVersion % 10);
99bdd1243dSDimitry Andric 
100*0fca6ea1SDimitry Andric   return VersionTuple(0);
101bdd1243dSDimitry Andric }
102bdd1243dSDimitry Andric 
103*0fca6ea1SDimitry Andric VersionTuple
104bdd1243dSDimitry Andric getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category,
105bdd1243dSDimitry Andric                              uint32_t Value) {
106bdd1243dSDimitry Andric   const SPIRV::SymbolicOperand *Lookup =
107bdd1243dSDimitry Andric       SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
108bdd1243dSDimitry Andric 
109bdd1243dSDimitry Andric   if (Lookup)
110*0fca6ea1SDimitry Andric     return VersionTuple(Lookup->MaxVersion / 10, Lookup->MaxVersion % 10);
111bdd1243dSDimitry Andric 
112*0fca6ea1SDimitry Andric   return VersionTuple();
113bdd1243dSDimitry Andric }
114bdd1243dSDimitry Andric 
115bdd1243dSDimitry Andric CapabilityList
116bdd1243dSDimitry Andric getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category,
117bdd1243dSDimitry Andric                                uint32_t Value) {
118bdd1243dSDimitry Andric   const SPIRV::CapabilityEntry *Capability =
119bdd1243dSDimitry Andric       SPIRV::lookupCapabilityByCategoryAndValue(Category, Value);
120bdd1243dSDimitry Andric 
121bdd1243dSDimitry Andric   CapabilityList Capabilities;
122bdd1243dSDimitry Andric   while (Capability && Capability->Category == Category &&
123bdd1243dSDimitry Andric          Capability->Value == Value) {
124bdd1243dSDimitry Andric     Capabilities.push_back(
125bdd1243dSDimitry Andric         static_cast<SPIRV::Capability::Capability>(Capability->ReqCapability));
126bdd1243dSDimitry Andric     ++Capability;
127bdd1243dSDimitry Andric   }
128bdd1243dSDimitry Andric 
129bdd1243dSDimitry Andric   return Capabilities;
130bdd1243dSDimitry Andric }
131bdd1243dSDimitry Andric 
1325f757f3fSDimitry Andric CapabilityList
1335f757f3fSDimitry Andric getCapabilitiesEnabledByExtension(SPIRV::Extension::Extension Extension) {
1345f757f3fSDimitry Andric   const SPIRV::ExtensionEntry *Entry =
1355f757f3fSDimitry Andric       SPIRV::lookupSymbolicOperandsEnabledByExtension(
1365f757f3fSDimitry Andric           Extension, SPIRV::OperandCategory::CapabilityOperand);
1375f757f3fSDimitry Andric 
1385f757f3fSDimitry Andric   CapabilityList Capabilities;
1395f757f3fSDimitry Andric   while (Entry &&
1405f757f3fSDimitry Andric          Entry->Category == SPIRV::OperandCategory::CapabilityOperand &&
1415f757f3fSDimitry Andric          Entry->ReqExtension == Extension) {
1425f757f3fSDimitry Andric     Capabilities.push_back(
1435f757f3fSDimitry Andric         static_cast<SPIRV::Capability::Capability>(Entry->Value));
1445f757f3fSDimitry Andric     ++Entry;
1455f757f3fSDimitry Andric   }
1465f757f3fSDimitry Andric 
1475f757f3fSDimitry Andric   return Capabilities;
1485f757f3fSDimitry Andric }
1495f757f3fSDimitry Andric 
150bdd1243dSDimitry Andric ExtensionList
151bdd1243dSDimitry Andric getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category,
152bdd1243dSDimitry Andric                              uint32_t Value) {
153bdd1243dSDimitry Andric   const SPIRV::ExtensionEntry *Extension =
154bdd1243dSDimitry Andric       SPIRV::lookupExtensionByCategoryAndValue(Category, Value);
155bdd1243dSDimitry Andric 
156bdd1243dSDimitry Andric   ExtensionList Extensions;
157bdd1243dSDimitry Andric   while (Extension && Extension->Category == Category &&
158bdd1243dSDimitry Andric          Extension->Value == Value) {
159bdd1243dSDimitry Andric     Extensions.push_back(
160bdd1243dSDimitry Andric         static_cast<SPIRV::Extension::Extension>(Extension->ReqExtension));
161bdd1243dSDimitry Andric     ++Extension;
162bdd1243dSDimitry Andric   }
163bdd1243dSDimitry Andric 
164bdd1243dSDimitry Andric   return Extensions;
165bdd1243dSDimitry Andric }
166bdd1243dSDimitry Andric 
167bdd1243dSDimitry Andric std::string getLinkStringForBuiltIn(SPIRV::BuiltIn::BuiltIn BuiltInValue) {
168bdd1243dSDimitry Andric   const SPIRV::SymbolicOperand *Lookup =
169bdd1243dSDimitry Andric       SPIRV::lookupSymbolicOperandByCategoryAndValue(
170bdd1243dSDimitry Andric           SPIRV::OperandCategory::BuiltInOperand, BuiltInValue);
171bdd1243dSDimitry Andric 
172bdd1243dSDimitry Andric   if (Lookup)
173bdd1243dSDimitry Andric     return "__spirv_BuiltIn" + Lookup->Mnemonic.str();
174bdd1243dSDimitry Andric   return "UNKNOWN_BUILTIN";
175bdd1243dSDimitry Andric }
176bdd1243dSDimitry Andric 
177bdd1243dSDimitry Andric bool getSpirvBuiltInIdByName(llvm::StringRef Name,
178bdd1243dSDimitry Andric                              SPIRV::BuiltIn::BuiltIn &BI) {
179bdd1243dSDimitry Andric   const std::string Prefix = "__spirv_BuiltIn";
1805f757f3fSDimitry Andric   if (!Name.starts_with(Prefix))
181bdd1243dSDimitry Andric     return false;
182bdd1243dSDimitry Andric 
183bdd1243dSDimitry Andric   const SPIRV::SymbolicOperand *Lookup =
184bdd1243dSDimitry Andric       SPIRV::lookupSymbolicOperandByCategoryAndMnemonic(
185bdd1243dSDimitry Andric           SPIRV::OperandCategory::BuiltInOperand,
186bdd1243dSDimitry Andric           Name.drop_front(Prefix.length()));
187bdd1243dSDimitry Andric 
188bdd1243dSDimitry Andric   if (!Lookup)
189bdd1243dSDimitry Andric     return false;
190bdd1243dSDimitry Andric 
191bdd1243dSDimitry Andric   BI = static_cast<SPIRV::BuiltIn::BuiltIn>(Lookup->Value);
192bdd1243dSDimitry Andric   return true;
193bdd1243dSDimitry Andric }
194bdd1243dSDimitry Andric 
195bdd1243dSDimitry Andric std::string getExtInstSetName(SPIRV::InstructionSet::InstructionSet Set) {
196bdd1243dSDimitry Andric   switch (Set) {
197bdd1243dSDimitry Andric   case SPIRV::InstructionSet::OpenCL_std:
198bdd1243dSDimitry Andric     return "OpenCL.std";
199bdd1243dSDimitry Andric   case SPIRV::InstructionSet::GLSL_std_450:
200bdd1243dSDimitry Andric     return "GLSL.std.450";
201*0fca6ea1SDimitry Andric   case SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100:
202*0fca6ea1SDimitry Andric     return "NonSemantic.Shader.DebugInfo.100";
203bdd1243dSDimitry Andric   case SPIRV::InstructionSet::SPV_AMD_shader_trinary_minmax:
204bdd1243dSDimitry Andric     return "SPV_AMD_shader_trinary_minmax";
205bdd1243dSDimitry Andric   }
206bdd1243dSDimitry Andric   return "UNKNOWN_EXT_INST_SET";
207bdd1243dSDimitry Andric }
208bdd1243dSDimitry Andric 
209bdd1243dSDimitry Andric SPIRV::InstructionSet::InstructionSet
210bdd1243dSDimitry Andric getExtInstSetFromString(std::string SetName) {
211*0fca6ea1SDimitry Andric   for (auto Set :
212*0fca6ea1SDimitry Andric        {SPIRV::InstructionSet::GLSL_std_450, SPIRV::InstructionSet::OpenCL_std,
213*0fca6ea1SDimitry Andric         SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100}) {
214bdd1243dSDimitry Andric     if (SetName == getExtInstSetName(Set))
215bdd1243dSDimitry Andric       return Set;
216bdd1243dSDimitry Andric   }
217bdd1243dSDimitry Andric   llvm_unreachable("UNKNOWN_EXT_INST_SET");
218bdd1243dSDimitry Andric }
219bdd1243dSDimitry Andric 
220bdd1243dSDimitry Andric std::string getExtInstName(SPIRV::InstructionSet::InstructionSet Set,
221bdd1243dSDimitry Andric                            uint32_t InstructionNumber) {
222bdd1243dSDimitry Andric   const SPIRV::ExtendedBuiltin *Lookup =
2235f757f3fSDimitry Andric       SPIRV::lookupExtendedBuiltinBySetAndNumber(Set, InstructionNumber);
224bdd1243dSDimitry Andric 
225bdd1243dSDimitry Andric   if (!Lookup)
226bdd1243dSDimitry Andric     return "UNKNOWN_EXT_INST";
227bdd1243dSDimitry Andric 
228bdd1243dSDimitry Andric   return Lookup->Name.str();
229bdd1243dSDimitry Andric }
23081ad6265SDimitry Andric } // namespace llvm
231