| //===-- SPIRVBaseInfo.cpp - Top level SPIRV definitions ---------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file contains the implementation for helper mnemonic lookup functions, |
| // versioning/capabilities/extensions getters for symbolic/named operands used |
| // in various SPIR-V instructions. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "SPIRVBaseInfo.h" |
| #include "llvm/ADT/ArrayRef.h" |
| #include "llvm/ADT/StringRef.h" |
| |
| namespace llvm { |
| namespace SPIRV { |
| struct SymbolicOperand { |
| OperandCategory::OperandCategory Category; |
| uint32_t Value; |
| StringRef Mnemonic; |
| uint32_t MinVersion; |
| uint32_t MaxVersion; |
| }; |
| |
| struct ExtensionEntry { |
| OperandCategory::OperandCategory Category; |
| uint32_t Value; |
| Extension::Extension ReqExtension; |
| }; |
| |
| struct CapabilityEntry { |
| OperandCategory::OperandCategory Category; |
| uint32_t Value; |
| Capability::Capability ReqCapability; |
| }; |
| |
| using namespace OperandCategory; |
| using namespace Extension; |
| using namespace Capability; |
| using namespace InstructionSet; |
| #define GET_SymbolicOperands_DECL |
| #define GET_SymbolicOperands_IMPL |
| #define GET_ExtensionEntries_DECL |
| #define GET_ExtensionEntries_IMPL |
| #define GET_CapabilityEntries_DECL |
| #define GET_CapabilityEntries_IMPL |
| #define GET_ExtendedBuiltins_DECL |
| #define GET_ExtendedBuiltins_IMPL |
| #include "SPIRVGenTables.inc" |
| } // namespace SPIRV |
| |
| std::string |
| getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category, |
| int32_t Value) { |
| const SPIRV::SymbolicOperand *Lookup = |
| SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value); |
| // Value that encodes just one enum value. |
| if (Lookup) |
| return Lookup->Mnemonic.str(); |
| if (Category != SPIRV::OperandCategory::ImageOperandOperand && |
| Category != SPIRV::OperandCategory::FPFastMathModeOperand && |
| Category != SPIRV::OperandCategory::SelectionControlOperand && |
| Category != SPIRV::OperandCategory::LoopControlOperand && |
| Category != SPIRV::OperandCategory::FunctionControlOperand && |
| Category != SPIRV::OperandCategory::MemorySemanticsOperand && |
| Category != SPIRV::OperandCategory::MemoryOperandOperand && |
| Category != SPIRV::OperandCategory::KernelProfilingInfoOperand) |
| return "UNKNOWN"; |
| // Value that encodes many enum values (one bit per enum value). |
| std::string Name; |
| std::string Separator; |
| const SPIRV::SymbolicOperand *EnumValueInCategory = |
| SPIRV::lookupSymbolicOperandByCategory(Category); |
| |
| while (EnumValueInCategory && EnumValueInCategory->Category == Category) { |
| if ((EnumValueInCategory->Value != 0) && |
| (Value & EnumValueInCategory->Value)) { |
| Name += Separator + EnumValueInCategory->Mnemonic.str(); |
| Separator = "|"; |
| } |
| ++EnumValueInCategory; |
| } |
| |
| return Name; |
| } |
| |
| uint32_t |
| getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category, |
| uint32_t Value) { |
| const SPIRV::SymbolicOperand *Lookup = |
| SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value); |
| |
| if (Lookup) |
| return Lookup->MinVersion; |
| |
| return 0; |
| } |
| |
| uint32_t |
| getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category, |
| uint32_t Value) { |
| const SPIRV::SymbolicOperand *Lookup = |
| SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value); |
| |
| if (Lookup) |
| return Lookup->MaxVersion; |
| |
| return 0; |
| } |
| |
| CapabilityList |
| getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category, |
| uint32_t Value) { |
| const SPIRV::CapabilityEntry *Capability = |
| SPIRV::lookupCapabilityByCategoryAndValue(Category, Value); |
| |
| CapabilityList Capabilities; |
| while (Capability && Capability->Category == Category && |
| Capability->Value == Value) { |
| Capabilities.push_back( |
| static_cast<SPIRV::Capability::Capability>(Capability->ReqCapability)); |
| ++Capability; |
| } |
| |
| return Capabilities; |
| } |
| |
| ExtensionList |
| getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category, |
| uint32_t Value) { |
| const SPIRV::ExtensionEntry *Extension = |
| SPIRV::lookupExtensionByCategoryAndValue(Category, Value); |
| |
| ExtensionList Extensions; |
| while (Extension && Extension->Category == Category && |
| Extension->Value == Value) { |
| Extensions.push_back( |
| static_cast<SPIRV::Extension::Extension>(Extension->ReqExtension)); |
| ++Extension; |
| } |
| |
| return Extensions; |
| } |
| |
| std::string getLinkStringForBuiltIn(SPIRV::BuiltIn::BuiltIn BuiltInValue) { |
| const SPIRV::SymbolicOperand *Lookup = |
| SPIRV::lookupSymbolicOperandByCategoryAndValue( |
| SPIRV::OperandCategory::BuiltInOperand, BuiltInValue); |
| |
| if (Lookup) |
| return "__spirv_BuiltIn" + Lookup->Mnemonic.str(); |
| return "UNKNOWN_BUILTIN"; |
| } |
| |
| bool getSpirvBuiltInIdByName(llvm::StringRef Name, |
| SPIRV::BuiltIn::BuiltIn &BI) { |
| const std::string Prefix = "__spirv_BuiltIn"; |
| if (!Name.startswith(Prefix)) |
| return false; |
| |
| const SPIRV::SymbolicOperand *Lookup = |
| SPIRV::lookupSymbolicOperandByCategoryAndMnemonic( |
| SPIRV::OperandCategory::BuiltInOperand, |
| Name.drop_front(Prefix.length())); |
| |
| if (!Lookup) |
| return false; |
| |
| BI = static_cast<SPIRV::BuiltIn::BuiltIn>(Lookup->Value); |
| return true; |
| } |
| |
| std::string getExtInstSetName(SPIRV::InstructionSet::InstructionSet Set) { |
| switch (Set) { |
| case SPIRV::InstructionSet::OpenCL_std: |
| return "OpenCL.std"; |
| case SPIRV::InstructionSet::GLSL_std_450: |
| return "GLSL.std.450"; |
| case SPIRV::InstructionSet::SPV_AMD_shader_trinary_minmax: |
| return "SPV_AMD_shader_trinary_minmax"; |
| } |
| return "UNKNOWN_EXT_INST_SET"; |
| } |
| |
| SPIRV::InstructionSet::InstructionSet |
| getExtInstSetFromString(std::string SetName) { |
| for (auto Set : {SPIRV::InstructionSet::GLSL_std_450, |
| SPIRV::InstructionSet::OpenCL_std}) { |
| if (SetName == getExtInstSetName(Set)) |
| return Set; |
| } |
| llvm_unreachable("UNKNOWN_EXT_INST_SET"); |
| } |
| |
| std::string getExtInstName(SPIRV::InstructionSet::InstructionSet Set, |
| uint32_t InstructionNumber) { |
| const SPIRV::ExtendedBuiltin *Lookup = |
| SPIRV::lookupExtendedBuiltinBySetAndNumber( |
| SPIRV::InstructionSet::OpenCL_std, InstructionNumber); |
| |
| if (!Lookup) |
| return "UNKNOWN_EXT_INST"; |
| |
| return Lookup->Name.str(); |
| } |
| } // namespace llvm |