xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVBaseInfo.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
1*bdd1243dSDimitry 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 //
9*bdd1243dSDimitry Andric // This file contains the implementation for helper mnemonic lookup functions,
10*bdd1243dSDimitry Andric // versioning/capabilities/extensions getters for symbolic/named operands used
11*bdd1243dSDimitry Andric // in various SPIR-V instructions.
1281ad6265SDimitry Andric //
1381ad6265SDimitry Andric //===----------------------------------------------------------------------===//
1481ad6265SDimitry Andric 
1581ad6265SDimitry Andric #include "SPIRVBaseInfo.h"
16*bdd1243dSDimitry Andric #include "llvm/ADT/ArrayRef.h"
17*bdd1243dSDimitry Andric #include "llvm/ADT/StringRef.h"
1881ad6265SDimitry Andric 
1981ad6265SDimitry Andric namespace llvm {
2081ad6265SDimitry Andric namespace SPIRV {
21*bdd1243dSDimitry Andric struct SymbolicOperand {
22*bdd1243dSDimitry Andric   OperandCategory::OperandCategory Category;
23*bdd1243dSDimitry Andric   uint32_t Value;
24*bdd1243dSDimitry Andric   StringRef Mnemonic;
25*bdd1243dSDimitry Andric   uint32_t MinVersion;
26*bdd1243dSDimitry Andric   uint32_t MaxVersion;
2781ad6265SDimitry Andric };
2881ad6265SDimitry Andric 
29*bdd1243dSDimitry Andric struct ExtensionEntry {
30*bdd1243dSDimitry Andric   OperandCategory::OperandCategory Category;
31*bdd1243dSDimitry Andric   uint32_t Value;
32*bdd1243dSDimitry Andric   Extension::Extension ReqExtension;
3381ad6265SDimitry Andric };
3481ad6265SDimitry Andric 
35*bdd1243dSDimitry Andric struct CapabilityEntry {
36*bdd1243dSDimitry Andric   OperandCategory::OperandCategory Category;
37*bdd1243dSDimitry Andric   uint32_t Value;
38*bdd1243dSDimitry Andric   Capability::Capability ReqCapability;
3981ad6265SDimitry Andric };
4081ad6265SDimitry Andric 
41*bdd1243dSDimitry Andric using namespace OperandCategory;
42*bdd1243dSDimitry Andric using namespace Extension;
43*bdd1243dSDimitry Andric using namespace Capability;
44*bdd1243dSDimitry Andric using namespace InstructionSet;
45*bdd1243dSDimitry Andric #define GET_SymbolicOperands_DECL
46*bdd1243dSDimitry Andric #define GET_SymbolicOperands_IMPL
47*bdd1243dSDimitry Andric #define GET_ExtensionEntries_DECL
48*bdd1243dSDimitry Andric #define GET_ExtensionEntries_IMPL
49*bdd1243dSDimitry Andric #define GET_CapabilityEntries_DECL
50*bdd1243dSDimitry Andric #define GET_CapabilityEntries_IMPL
51*bdd1243dSDimitry Andric #define GET_ExtendedBuiltins_DECL
52*bdd1243dSDimitry Andric #define GET_ExtendedBuiltins_IMPL
53*bdd1243dSDimitry Andric #include "SPIRVGenTables.inc"
5481ad6265SDimitry Andric } // namespace SPIRV
55*bdd1243dSDimitry Andric 
56*bdd1243dSDimitry Andric std::string
57*bdd1243dSDimitry Andric getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category,
58*bdd1243dSDimitry Andric                            int32_t Value) {
59*bdd1243dSDimitry Andric   const SPIRV::SymbolicOperand *Lookup =
60*bdd1243dSDimitry Andric       SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
61*bdd1243dSDimitry Andric   // Value that encodes just one enum value.
62*bdd1243dSDimitry Andric   if (Lookup)
63*bdd1243dSDimitry Andric     return Lookup->Mnemonic.str();
64*bdd1243dSDimitry Andric   if (Category != SPIRV::OperandCategory::ImageOperandOperand &&
65*bdd1243dSDimitry Andric       Category != SPIRV::OperandCategory::FPFastMathModeOperand &&
66*bdd1243dSDimitry Andric       Category != SPIRV::OperandCategory::SelectionControlOperand &&
67*bdd1243dSDimitry Andric       Category != SPIRV::OperandCategory::LoopControlOperand &&
68*bdd1243dSDimitry Andric       Category != SPIRV::OperandCategory::FunctionControlOperand &&
69*bdd1243dSDimitry Andric       Category != SPIRV::OperandCategory::MemorySemanticsOperand &&
70*bdd1243dSDimitry Andric       Category != SPIRV::OperandCategory::MemoryOperandOperand &&
71*bdd1243dSDimitry Andric       Category != SPIRV::OperandCategory::KernelProfilingInfoOperand)
72*bdd1243dSDimitry Andric     return "UNKNOWN";
73*bdd1243dSDimitry Andric   // Value that encodes many enum values (one bit per enum value).
74*bdd1243dSDimitry Andric   std::string Name;
75*bdd1243dSDimitry Andric   std::string Separator;
76*bdd1243dSDimitry Andric   const SPIRV::SymbolicOperand *EnumValueInCategory =
77*bdd1243dSDimitry Andric       SPIRV::lookupSymbolicOperandByCategory(Category);
78*bdd1243dSDimitry Andric 
79*bdd1243dSDimitry Andric   while (EnumValueInCategory && EnumValueInCategory->Category == Category) {
80*bdd1243dSDimitry Andric     if ((EnumValueInCategory->Value != 0) &&
81*bdd1243dSDimitry Andric         (Value & EnumValueInCategory->Value)) {
82*bdd1243dSDimitry Andric       Name += Separator + EnumValueInCategory->Mnemonic.str();
83*bdd1243dSDimitry Andric       Separator = "|";
84*bdd1243dSDimitry Andric     }
85*bdd1243dSDimitry Andric     ++EnumValueInCategory;
86*bdd1243dSDimitry Andric   }
87*bdd1243dSDimitry Andric 
88*bdd1243dSDimitry Andric   return Name;
89*bdd1243dSDimitry Andric }
90*bdd1243dSDimitry Andric 
91*bdd1243dSDimitry Andric uint32_t
92*bdd1243dSDimitry Andric getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category,
93*bdd1243dSDimitry Andric                              uint32_t Value) {
94*bdd1243dSDimitry Andric   const SPIRV::SymbolicOperand *Lookup =
95*bdd1243dSDimitry Andric       SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
96*bdd1243dSDimitry Andric 
97*bdd1243dSDimitry Andric   if (Lookup)
98*bdd1243dSDimitry Andric     return Lookup->MinVersion;
99*bdd1243dSDimitry Andric 
100*bdd1243dSDimitry Andric   return 0;
101*bdd1243dSDimitry Andric }
102*bdd1243dSDimitry Andric 
103*bdd1243dSDimitry Andric uint32_t
104*bdd1243dSDimitry Andric getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category,
105*bdd1243dSDimitry Andric                              uint32_t Value) {
106*bdd1243dSDimitry Andric   const SPIRV::SymbolicOperand *Lookup =
107*bdd1243dSDimitry Andric       SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
108*bdd1243dSDimitry Andric 
109*bdd1243dSDimitry Andric   if (Lookup)
110*bdd1243dSDimitry Andric     return Lookup->MaxVersion;
111*bdd1243dSDimitry Andric 
112*bdd1243dSDimitry Andric   return 0;
113*bdd1243dSDimitry Andric }
114*bdd1243dSDimitry Andric 
115*bdd1243dSDimitry Andric CapabilityList
116*bdd1243dSDimitry Andric getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category,
117*bdd1243dSDimitry Andric                                uint32_t Value) {
118*bdd1243dSDimitry Andric   const SPIRV::CapabilityEntry *Capability =
119*bdd1243dSDimitry Andric       SPIRV::lookupCapabilityByCategoryAndValue(Category, Value);
120*bdd1243dSDimitry Andric 
121*bdd1243dSDimitry Andric   CapabilityList Capabilities;
122*bdd1243dSDimitry Andric   while (Capability && Capability->Category == Category &&
123*bdd1243dSDimitry Andric          Capability->Value == Value) {
124*bdd1243dSDimitry Andric     Capabilities.push_back(
125*bdd1243dSDimitry Andric         static_cast<SPIRV::Capability::Capability>(Capability->ReqCapability));
126*bdd1243dSDimitry Andric     ++Capability;
127*bdd1243dSDimitry Andric   }
128*bdd1243dSDimitry Andric 
129*bdd1243dSDimitry Andric   return Capabilities;
130*bdd1243dSDimitry Andric }
131*bdd1243dSDimitry Andric 
132*bdd1243dSDimitry Andric ExtensionList
133*bdd1243dSDimitry Andric getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category,
134*bdd1243dSDimitry Andric                              uint32_t Value) {
135*bdd1243dSDimitry Andric   const SPIRV::ExtensionEntry *Extension =
136*bdd1243dSDimitry Andric       SPIRV::lookupExtensionByCategoryAndValue(Category, Value);
137*bdd1243dSDimitry Andric 
138*bdd1243dSDimitry Andric   ExtensionList Extensions;
139*bdd1243dSDimitry Andric   while (Extension && Extension->Category == Category &&
140*bdd1243dSDimitry Andric          Extension->Value == Value) {
141*bdd1243dSDimitry Andric     Extensions.push_back(
142*bdd1243dSDimitry Andric         static_cast<SPIRV::Extension::Extension>(Extension->ReqExtension));
143*bdd1243dSDimitry Andric     ++Extension;
144*bdd1243dSDimitry Andric   }
145*bdd1243dSDimitry Andric 
146*bdd1243dSDimitry Andric   return Extensions;
147*bdd1243dSDimitry Andric }
148*bdd1243dSDimitry Andric 
149*bdd1243dSDimitry Andric std::string getLinkStringForBuiltIn(SPIRV::BuiltIn::BuiltIn BuiltInValue) {
150*bdd1243dSDimitry Andric   const SPIRV::SymbolicOperand *Lookup =
151*bdd1243dSDimitry Andric       SPIRV::lookupSymbolicOperandByCategoryAndValue(
152*bdd1243dSDimitry Andric           SPIRV::OperandCategory::BuiltInOperand, BuiltInValue);
153*bdd1243dSDimitry Andric 
154*bdd1243dSDimitry Andric   if (Lookup)
155*bdd1243dSDimitry Andric     return "__spirv_BuiltIn" + Lookup->Mnemonic.str();
156*bdd1243dSDimitry Andric   return "UNKNOWN_BUILTIN";
157*bdd1243dSDimitry Andric }
158*bdd1243dSDimitry Andric 
159*bdd1243dSDimitry Andric bool getSpirvBuiltInIdByName(llvm::StringRef Name,
160*bdd1243dSDimitry Andric                              SPIRV::BuiltIn::BuiltIn &BI) {
161*bdd1243dSDimitry Andric   const std::string Prefix = "__spirv_BuiltIn";
162*bdd1243dSDimitry Andric   if (!Name.startswith(Prefix))
163*bdd1243dSDimitry Andric     return false;
164*bdd1243dSDimitry Andric 
165*bdd1243dSDimitry Andric   const SPIRV::SymbolicOperand *Lookup =
166*bdd1243dSDimitry Andric       SPIRV::lookupSymbolicOperandByCategoryAndMnemonic(
167*bdd1243dSDimitry Andric           SPIRV::OperandCategory::BuiltInOperand,
168*bdd1243dSDimitry Andric           Name.drop_front(Prefix.length()));
169*bdd1243dSDimitry Andric 
170*bdd1243dSDimitry Andric   if (!Lookup)
171*bdd1243dSDimitry Andric     return false;
172*bdd1243dSDimitry Andric 
173*bdd1243dSDimitry Andric   BI = static_cast<SPIRV::BuiltIn::BuiltIn>(Lookup->Value);
174*bdd1243dSDimitry Andric   return true;
175*bdd1243dSDimitry Andric }
176*bdd1243dSDimitry Andric 
177*bdd1243dSDimitry Andric std::string getExtInstSetName(SPIRV::InstructionSet::InstructionSet Set) {
178*bdd1243dSDimitry Andric   switch (Set) {
179*bdd1243dSDimitry Andric   case SPIRV::InstructionSet::OpenCL_std:
180*bdd1243dSDimitry Andric     return "OpenCL.std";
181*bdd1243dSDimitry Andric   case SPIRV::InstructionSet::GLSL_std_450:
182*bdd1243dSDimitry Andric     return "GLSL.std.450";
183*bdd1243dSDimitry Andric   case SPIRV::InstructionSet::SPV_AMD_shader_trinary_minmax:
184*bdd1243dSDimitry Andric     return "SPV_AMD_shader_trinary_minmax";
185*bdd1243dSDimitry Andric   }
186*bdd1243dSDimitry Andric   return "UNKNOWN_EXT_INST_SET";
187*bdd1243dSDimitry Andric }
188*bdd1243dSDimitry Andric 
189*bdd1243dSDimitry Andric SPIRV::InstructionSet::InstructionSet
190*bdd1243dSDimitry Andric getExtInstSetFromString(std::string SetName) {
191*bdd1243dSDimitry Andric   for (auto Set : {SPIRV::InstructionSet::GLSL_std_450,
192*bdd1243dSDimitry Andric                    SPIRV::InstructionSet::OpenCL_std}) {
193*bdd1243dSDimitry Andric     if (SetName == getExtInstSetName(Set))
194*bdd1243dSDimitry Andric       return Set;
195*bdd1243dSDimitry Andric   }
196*bdd1243dSDimitry Andric   llvm_unreachable("UNKNOWN_EXT_INST_SET");
197*bdd1243dSDimitry Andric }
198*bdd1243dSDimitry Andric 
199*bdd1243dSDimitry Andric std::string getExtInstName(SPIRV::InstructionSet::InstructionSet Set,
200*bdd1243dSDimitry Andric                            uint32_t InstructionNumber) {
201*bdd1243dSDimitry Andric   const SPIRV::ExtendedBuiltin *Lookup =
202*bdd1243dSDimitry Andric       SPIRV::lookupExtendedBuiltinBySetAndNumber(
203*bdd1243dSDimitry Andric           SPIRV::InstructionSet::OpenCL_std, InstructionNumber);
204*bdd1243dSDimitry Andric 
205*bdd1243dSDimitry Andric   if (!Lookup)
206*bdd1243dSDimitry Andric     return "UNKNOWN_EXT_INST";
207*bdd1243dSDimitry Andric 
208*bdd1243dSDimitry Andric   return Lookup->Name.str();
209*bdd1243dSDimitry Andric }
21081ad6265SDimitry Andric } // namespace llvm
211