1 //===-- SPIRVBaseInfo.cpp - Top level SPIRV definitions ---------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains the implementation for helper mnemonic lookup functions,
10 // versioning/capabilities/extensions getters for symbolic/named operands used
11 // in various SPIR-V instructions.
13 //===----------------------------------------------------------------------===//
15 #include "SPIRVBaseInfo.h"
16 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/StringRef.h"
21 struct SymbolicOperand
{
22 OperandCategory::OperandCategory Category
;
29 struct ExtensionEntry
{
30 OperandCategory::OperandCategory Category
;
32 Extension::Extension ReqExtension
;
35 struct CapabilityEntry
{
36 OperandCategory::OperandCategory Category
;
38 Capability::Capability ReqCapability
;
41 using namespace OperandCategory
;
42 using namespace Extension
;
43 using namespace Capability
;
44 using namespace InstructionSet
;
45 #define GET_SymbolicOperands_DECL
46 #define GET_SymbolicOperands_IMPL
47 #define GET_ExtensionEntries_DECL
48 #define GET_ExtensionEntries_IMPL
49 #define GET_CapabilityEntries_DECL
50 #define GET_CapabilityEntries_IMPL
51 #define GET_ExtendedBuiltins_DECL
52 #define GET_ExtendedBuiltins_IMPL
53 #include "SPIRVGenTables.inc"
57 getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category
,
59 const SPIRV::SymbolicOperand
*Lookup
=
60 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category
, Value
);
61 // Value that encodes just one enum value.
63 return Lookup
->Mnemonic
.str();
64 if (Category
!= SPIRV::OperandCategory::ImageOperandOperand
&&
65 Category
!= SPIRV::OperandCategory::FPFastMathModeOperand
&&
66 Category
!= SPIRV::OperandCategory::SelectionControlOperand
&&
67 Category
!= SPIRV::OperandCategory::LoopControlOperand
&&
68 Category
!= SPIRV::OperandCategory::FunctionControlOperand
&&
69 Category
!= SPIRV::OperandCategory::MemorySemanticsOperand
&&
70 Category
!= SPIRV::OperandCategory::MemoryOperandOperand
&&
71 Category
!= SPIRV::OperandCategory::KernelProfilingInfoOperand
)
73 // Value that encodes many enum values (one bit per enum value).
75 std::string Separator
;
76 const SPIRV::SymbolicOperand
*EnumValueInCategory
=
77 SPIRV::lookupSymbolicOperandByCategory(Category
);
79 while (EnumValueInCategory
&& EnumValueInCategory
->Category
== Category
) {
80 if ((EnumValueInCategory
->Value
!= 0) &&
81 (Value
& EnumValueInCategory
->Value
)) {
82 Name
+= Separator
+ EnumValueInCategory
->Mnemonic
.str();
85 ++EnumValueInCategory
;
92 getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category
,
94 const SPIRV::SymbolicOperand
*Lookup
=
95 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category
, Value
);
98 return VersionTuple(Lookup
->MinVersion
/ 10, Lookup
->MinVersion
% 10);
100 return VersionTuple(0);
104 getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category
,
106 const SPIRV::SymbolicOperand
*Lookup
=
107 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category
, Value
);
110 return VersionTuple(Lookup
->MaxVersion
/ 10, Lookup
->MaxVersion
% 10);
112 return VersionTuple();
116 getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category
,
118 const SPIRV::CapabilityEntry
*Capability
=
119 SPIRV::lookupCapabilityByCategoryAndValue(Category
, Value
);
121 CapabilityList Capabilities
;
122 while (Capability
&& Capability
->Category
== Category
&&
123 Capability
->Value
== Value
) {
124 Capabilities
.push_back(
125 static_cast<SPIRV::Capability::Capability
>(Capability
->ReqCapability
));
133 getCapabilitiesEnabledByExtension(SPIRV::Extension::Extension Extension
) {
134 const SPIRV::ExtensionEntry
*Entry
=
135 SPIRV::lookupSymbolicOperandsEnabledByExtension(
136 Extension
, SPIRV::OperandCategory::CapabilityOperand
);
138 CapabilityList Capabilities
;
140 Entry
->Category
== SPIRV::OperandCategory::CapabilityOperand
&&
141 Entry
->ReqExtension
== Extension
) {
142 Capabilities
.push_back(
143 static_cast<SPIRV::Capability::Capability
>(Entry
->Value
));
151 getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category
,
153 const SPIRV::ExtensionEntry
*Extension
=
154 SPIRV::lookupExtensionByCategoryAndValue(Category
, Value
);
156 ExtensionList Extensions
;
157 while (Extension
&& Extension
->Category
== Category
&&
158 Extension
->Value
== Value
) {
159 Extensions
.push_back(
160 static_cast<SPIRV::Extension::Extension
>(Extension
->ReqExtension
));
167 std::string
getLinkStringForBuiltIn(SPIRV::BuiltIn::BuiltIn BuiltInValue
) {
168 const SPIRV::SymbolicOperand
*Lookup
=
169 SPIRV::lookupSymbolicOperandByCategoryAndValue(
170 SPIRV::OperandCategory::BuiltInOperand
, BuiltInValue
);
173 return "__spirv_BuiltIn" + Lookup
->Mnemonic
.str();
174 return "UNKNOWN_BUILTIN";
177 bool getSpirvBuiltInIdByName(llvm::StringRef Name
,
178 SPIRV::BuiltIn::BuiltIn
&BI
) {
179 const std::string Prefix
= "__spirv_BuiltIn";
180 if (!Name
.starts_with(Prefix
))
183 const SPIRV::SymbolicOperand
*Lookup
=
184 SPIRV::lookupSymbolicOperandByCategoryAndMnemonic(
185 SPIRV::OperandCategory::BuiltInOperand
,
186 Name
.drop_front(Prefix
.length()));
191 BI
= static_cast<SPIRV::BuiltIn::BuiltIn
>(Lookup
->Value
);
195 std::string
getExtInstSetName(SPIRV::InstructionSet::InstructionSet Set
) {
197 case SPIRV::InstructionSet::OpenCL_std
:
199 case SPIRV::InstructionSet::GLSL_std_450
:
200 return "GLSL.std.450";
201 case SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100
:
202 return "NonSemantic.Shader.DebugInfo.100";
203 case SPIRV::InstructionSet::SPV_AMD_shader_trinary_minmax
:
204 return "SPV_AMD_shader_trinary_minmax";
206 return "UNKNOWN_EXT_INST_SET";
209 SPIRV::InstructionSet::InstructionSet
210 getExtInstSetFromString(std::string SetName
) {
212 {SPIRV::InstructionSet::GLSL_std_450
, SPIRV::InstructionSet::OpenCL_std
,
213 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100
}) {
214 if (SetName
== getExtInstSetName(Set
))
217 llvm_unreachable("UNKNOWN_EXT_INST_SET");
220 std::string
getExtInstName(SPIRV::InstructionSet::InstructionSet Set
,
221 uint32_t InstructionNumber
) {
222 const SPIRV::ExtendedBuiltin
*Lookup
=
223 SPIRV::lookupExtendedBuiltinBySetAndNumber(Set
, InstructionNumber
);
226 return "UNKNOWN_EXT_INST";
228 return Lookup
->Name
.str();