1 //===-- SPIRVBaseInfo.cpp - Top level SPIRV definitions ---------*- C++ -*-===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 // 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. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "SPIRVBaseInfo.h" 16 #include "llvm/ADT/ArrayRef.h" 17 #include "llvm/ADT/StringRef.h" 18 19 namespace llvm { 20 namespace SPIRV { 21 struct SymbolicOperand { 22 OperandCategory::OperandCategory Category; 23 uint32_t Value; 24 StringRef Mnemonic; 25 uint32_t MinVersion; 26 uint32_t MaxVersion; 27 }; 28 29 struct ExtensionEntry { 30 OperandCategory::OperandCategory Category; 31 uint32_t Value; 32 Extension::Extension ReqExtension; 33 }; 34 35 struct CapabilityEntry { 36 OperandCategory::OperandCategory Category; 37 uint32_t Value; 38 Capability::Capability ReqCapability; 39 }; 40 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" 54 } // namespace SPIRV 55 56 std::string 57 getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category, 58 int32_t Value) { 59 const SPIRV::SymbolicOperand *Lookup = 60 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value); 61 // Value that encodes just one enum value. 62 if (Lookup) 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) 72 return "UNKNOWN"; 73 // Value that encodes many enum values (one bit per enum value). 74 std::string Name; 75 std::string Separator; 76 const SPIRV::SymbolicOperand *EnumValueInCategory = 77 SPIRV::lookupSymbolicOperandByCategory(Category); 78 79 while (EnumValueInCategory && EnumValueInCategory->Category == Category) { 80 if ((EnumValueInCategory->Value != 0) && 81 (Value & EnumValueInCategory->Value)) { 82 Name += Separator + EnumValueInCategory->Mnemonic.str(); 83 Separator = "|"; 84 } 85 ++EnumValueInCategory; 86 } 87 88 return Name; 89 } 90 91 uint32_t 92 getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category, 93 uint32_t Value) { 94 const SPIRV::SymbolicOperand *Lookup = 95 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value); 96 97 if (Lookup) 98 return Lookup->MinVersion; 99 100 return 0; 101 } 102 103 uint32_t 104 getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category, 105 uint32_t Value) { 106 const SPIRV::SymbolicOperand *Lookup = 107 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value); 108 109 if (Lookup) 110 return Lookup->MaxVersion; 111 112 return 0; 113 } 114 115 CapabilityList 116 getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category, 117 uint32_t Value) { 118 const SPIRV::CapabilityEntry *Capability = 119 SPIRV::lookupCapabilityByCategoryAndValue(Category, Value); 120 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)); 126 ++Capability; 127 } 128 129 return Capabilities; 130 } 131 132 ExtensionList 133 getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category, 134 uint32_t Value) { 135 const SPIRV::ExtensionEntry *Extension = 136 SPIRV::lookupExtensionByCategoryAndValue(Category, Value); 137 138 ExtensionList Extensions; 139 while (Extension && Extension->Category == Category && 140 Extension->Value == Value) { 141 Extensions.push_back( 142 static_cast<SPIRV::Extension::Extension>(Extension->ReqExtension)); 143 ++Extension; 144 } 145 146 return Extensions; 147 } 148 149 std::string getLinkStringForBuiltIn(SPIRV::BuiltIn::BuiltIn BuiltInValue) { 150 const SPIRV::SymbolicOperand *Lookup = 151 SPIRV::lookupSymbolicOperandByCategoryAndValue( 152 SPIRV::OperandCategory::BuiltInOperand, BuiltInValue); 153 154 if (Lookup) 155 return "__spirv_BuiltIn" + Lookup->Mnemonic.str(); 156 return "UNKNOWN_BUILTIN"; 157 } 158 159 bool getSpirvBuiltInIdByName(llvm::StringRef Name, 160 SPIRV::BuiltIn::BuiltIn &BI) { 161 const std::string Prefix = "__spirv_BuiltIn"; 162 if (!Name.startswith(Prefix)) 163 return false; 164 165 const SPIRV::SymbolicOperand *Lookup = 166 SPIRV::lookupSymbolicOperandByCategoryAndMnemonic( 167 SPIRV::OperandCategory::BuiltInOperand, 168 Name.drop_front(Prefix.length())); 169 170 if (!Lookup) 171 return false; 172 173 BI = static_cast<SPIRV::BuiltIn::BuiltIn>(Lookup->Value); 174 return true; 175 } 176 177 std::string getExtInstSetName(SPIRV::InstructionSet::InstructionSet Set) { 178 switch (Set) { 179 case SPIRV::InstructionSet::OpenCL_std: 180 return "OpenCL.std"; 181 case SPIRV::InstructionSet::GLSL_std_450: 182 return "GLSL.std.450"; 183 case SPIRV::InstructionSet::SPV_AMD_shader_trinary_minmax: 184 return "SPV_AMD_shader_trinary_minmax"; 185 } 186 return "UNKNOWN_EXT_INST_SET"; 187 } 188 189 SPIRV::InstructionSet::InstructionSet 190 getExtInstSetFromString(std::string SetName) { 191 for (auto Set : {SPIRV::InstructionSet::GLSL_std_450, 192 SPIRV::InstructionSet::OpenCL_std}) { 193 if (SetName == getExtInstSetName(Set)) 194 return Set; 195 } 196 llvm_unreachable("UNKNOWN_EXT_INST_SET"); 197 } 198 199 std::string getExtInstName(SPIRV::InstructionSet::InstructionSet Set, 200 uint32_t InstructionNumber) { 201 const SPIRV::ExtendedBuiltin *Lookup = 202 SPIRV::lookupExtendedBuiltinBySetAndNumber( 203 SPIRV::InstructionSet::OpenCL_std, InstructionNumber); 204 205 if (!Lookup) 206 return "UNKNOWN_EXT_INST"; 207 208 return Lookup->Name.str(); 209 } 210 } // namespace llvm 211