// numCapabilities - we only handle 0 or 1 required capabilities
// Capability(<capability-name>) - capability required to use this instruction. Might be None.
// There can be Capability2(a,b) for dependence on two capabilities.
-// {0|1} - whether the instruction is variable number of words
+// {0|1} - whether the instruction is variable number of logical operands
// EmptyList or List(...) - list of classes of logical operands
// Example use:
// #define EmptyList {}
Instruction(TypeFloat, 1, 0, 1, 0, Capability(None), 0, List(OperandLiteralNumber))
Instruction(TypeVector, 1, 0, 2, 0, Capability(None), 0, List(OperandId, OperandLiteralNumber))
Instruction(TypeMatrix, 1, 0, 2, 1, Capability(Matrix), 0, List(OperandId, OperandLiteralNumber))
-Instruction(TypeImage, 1, 0, 8, 0, Capability(None), 1, List(OperandId, OperandDimensionality, OperandLiteralNumber, OperandLiteralNumber, OperandLiteralNumber, OperandLiteralNumber, OperandSamplerImageFormat, OperandOptionalLiteral))
+Instruction(TypeImage, 1, 0, 8, 0, Capability(None), 1, List(OperandId, OperandDimensionality, OperandLiteralNumber, OperandLiteralNumber, OperandLiteralNumber, OperandLiteralNumber, OperandSamplerImageFormat, OperandOptionalAccessQualifier))
Instruction(TypeSampler, 1, 0, 0, 0, Capability(None), 0, EmptyList)
Instruction(TypeSampledImage, 1, 0, 1, 0, Capability(None), 0, List(OperandId))
Instruction(TypeArray, 1, 0, 2, 0, Capability(None), 0, List(OperandId, OperandId))
Instruction(FunctionCall, 1, 1, 2, 0, Capability(None), 1, List(OperandId, OperandVariableIds))
Instruction(Variable, 1, 1, 2, 0, Capability(None), 1, List(OperandStorage, OperandOptionalId))
Instruction(ImageTexelPointer, 1, 1, 3, 0, Capability(None), 0, List(OperandId, OperandId, OperandId))
-Instruction(Load, 1, 1, 2, 0, Capability(None), 1, List(OperandId, OperandOptionalLiteral))
-Instruction(Store, 0, 0, 3, 0, Capability(None), 1, List(OperandId, OperandId, OperandOptionalLiteral))
-Instruction(CopyMemory, 0, 0, 3, 0, Capability(None), 1, List(OperandId, OperandId, OperandOptionalLiteral))
-Instruction(CopyMemorySized, 0, 0, 4, 1, Capability(Addresses), 1, List(OperandId, OperandId, OperandId, OperandOptionalLiteral))
+Instruction(Load, 1, 1, 2, 0, Capability(None), 1, List(OperandId, OperandOptionalMemoryAccess))
+Instruction(Store, 0, 0, 3, 0, Capability(None), 1, List(OperandId, OperandId, OperandOptionalMemoryAccess))
+Instruction(CopyMemory, 0, 0, 3, 0, Capability(None), 1, List(OperandId, OperandId, OperandOptionalMemoryAccess))
+Instruction(CopyMemorySized, 0, 0, 4, 1, Capability(Addresses), 1, List(OperandId, OperandId, OperandId, OperandOptionalMemoryAccess))
Instruction(AccessChain, 1, 1, 2, 0, Capability(None), 1, List(OperandId, OperandVariableIds))
Instruction(InBoundsAccessChain, 1, 1, 2, 0, Capability(None), 1, List(OperandId, OperandVariableIds))
Instruction(PtrAccessChain, 1, 1, 3, 1, Capability(Addresses), 1, List(OperandId, OperandId, OperandVariableIds))
Instruction(CopyObject, 1, 1, 1, 0, Capability(None), 0, List(OperandId))
Instruction(Transpose, 1, 1, 1, 1, Capability(Matrix), 0, List(OperandId))
Instruction(SampledImage, 1, 1, 2, 0, Capability(None), 0, List(OperandId, OperandId))
-Instruction(ImageSampleImplicitLod, 1, 1, 3, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSampleExplicitLod, 1, 1, 3, 0, Capability(None), 1, List(OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSampleDrefImplicitLod, 1, 1, 4, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSampleDrefExplicitLod, 1, 1, 4, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSampleProjImplicitLod, 1, 1, 3, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSampleProjExplicitLod, 1, 1, 3, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSampleProjDrefImplicitLod, 1, 1, 4, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSampleProjDrefExplicitLod, 1, 1, 4, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageFetch, 1, 1, 3, 0, Capability(None), 1, List(OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageGather, 1, 1, 4, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageDrefGather, 1, 1, 4, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageRead, 1, 1, 3, 0, Capability(None), 1, List(OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageWrite, 0, 0, 4, 0, Capability(None), 1, List(OperandId, OperandId, OperandId, OperandOptionalImage))
+Instruction(ImageSampleImplicitLod, 1, 1, 4, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandOptionalImageOperands))
+Instruction(ImageSampleExplicitLod, 1, 1, 5, 0, Capability(None), 1, List(OperandId, OperandId, OperandImageOperands))
+Instruction(ImageSampleDrefImplicitLod, 1, 1, 5, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandId, OperandOptionalImageOperands))
+Instruction(ImageSampleDrefExplicitLod, 1, 1, 6, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandId, OperandImageOperands))
+Instruction(ImageSampleProjImplicitLod, 1, 1, 4, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandOptionalImageOperands))
+Instruction(ImageSampleProjExplicitLod, 1, 1, 5, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandImageOperands))
+Instruction(ImageSampleProjDrefImplicitLod, 1, 1, 5, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandId, OperandOptionalImageOperands))
+Instruction(ImageSampleProjDrefExplicitLod, 1, 1, 6, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandId, OperandImageOperands))
+Instruction(ImageFetch, 1, 1, 4, 0, Capability(None), 1, List(OperandId, OperandId, OperandOptionalImageOperands))
+Instruction(ImageGather, 1, 1, 5, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandId, OperandOptionalImageOperands))
+Instruction(ImageDrefGather, 1, 1, 5, 1, Capability(Shader), 1, List(OperandId, OperandId, OperandId, OperandOptionalImageOperands))
+Instruction(ImageRead, 1, 1, 4, 0, Capability(None), 1, List(OperandId, OperandId, OperandOptionalImageOperands))
+Instruction(ImageWrite, 0, 0, 5, 0, Capability(None), 1, List(OperandId, OperandId, OperandId, OperandOptionalImageOperands))
Instruction(Image, 1, 1, 1, 0, Capability(None), 0, List(OperandId))
Instruction(ImageQueryFormat, 1, 1, 1, 1, Capability(Kernel), 0, List(OperandId))
Instruction(ImageQueryOrder, 1, 1, 1, 1, Capability(Kernel), 0, List(OperandId))
Instruction(CaptureEventProfilingInfo, 0, 0, 3, 1, Capability(DeviceEnqueue), 0, List(OperandId, OperandId, OperandId))
Instruction(GetDefaultQueue, 1, 1, 0, 1, Capability(DeviceEnqueue), 0, EmptyList)
Instruction(BuildNDRange, 1, 1, 3, 1, Capability(DeviceEnqueue), 0, List(OperandId, OperandId, OperandId))
-Instruction(ImageSparseSampleImplicitLod, 1, 1, 3, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSparseSampleExplicitLod, 1, 1, 3, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSparseSampleDrefImplicitLod, 1, 1, 4, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSparseSampleDrefExplicitLod, 1, 1, 4, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSparseSampleProjImplicitLod, 1, 1, 3, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSparseSampleProjExplicitLod, 1, 1, 3, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSparseSampleProjDrefImplicitLod, 1, 1, 4, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSparseSampleProjDrefExplicitLod, 1, 1, 4, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSparseFetch, 1, 1, 3, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSparseGather, 1, 1, 4, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandId, OperandOptionalImage))
-Instruction(ImageSparseDrefGather, 1, 1, 4, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandId, OperandOptionalImage))
+Instruction(ImageSparseSampleImplicitLod, 1, 1, 4, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandOptionalImageOperands))
+Instruction(ImageSparseSampleExplicitLod, 1, 1, 5, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandImageOperands))
+Instruction(ImageSparseSampleDrefImplicitLod, 1, 1, 5, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandId, OperandOptionalImageOperands))
+Instruction(ImageSparseSampleDrefExplicitLod, 1, 1, 6, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandId, OperandImageOperands))
+Instruction(ImageSparseSampleProjImplicitLod, 1, 1, 4, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandOptionalImageOperands))
+Instruction(ImageSparseSampleProjExplicitLod, 1, 1, 5, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandImageOperands))
+Instruction(ImageSparseSampleProjDrefImplicitLod, 1, 1, 5, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandId, OperandOptionalImageOperands))
+Instruction(ImageSparseSampleProjDrefExplicitLod, 1, 1, 6, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandId, OperandImageOperands))
+Instruction(ImageSparseFetch, 1, 1, 4, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandOptionalImageOperands))
+Instruction(ImageSparseGather, 1, 1, 5, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandId, OperandOptionalImageOperands))
+Instruction(ImageSparseDrefGather, 1, 1, 5, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandId, OperandOptionalImageOperands))
Instruction(ImageSparseTexelsResident, 1, 1, 1, 1, Capability(SparseResidency), 0, List(OperandId))
Instruction(NoLine, 0, 0, 0, 0, Capability(None), 0, EmptyList)
Instruction(AtomicFlagTestAndSet, 1, 1, 3, 1, Capability(Kernel), 0, List(OperandId, OperandScope, OperandMemorySemantics))
Instruction(AtomicFlagClear, 0, 0, 3, 1, Capability(Kernel), 0, List(OperandId, OperandScope, OperandMemorySemantics))
+Instruction(ImageSparseRead, 1, 1, 4, 1, Capability(SparseResidency), 1, List(OperandId, OperandId, OperandOptionalImageOperands))
header.cpp
doc.cpp
diff --git a/tools/spirv/OclDoc.cpp b/tools/spirv/OclDoc.cpp
-index c94eae2..ea47d42 100644
+index 1f25221..ff2c7c6 100644
--- a/tools/spirv/OclDoc.cpp
+++ b/tools/spirv/OclDoc.cpp
@@ -28,11 +28,14 @@
#include <algorithm>
#include <map>
-@@ -2358,4 +2361,27 @@ void PrintOclCommonDoc()
+@@ -2187,4 +2190,31 @@ void PrintOclCommonDoc()
PrintOclDoc(SPIROpenCLCommonVersion);
}
+ assert(inst.hasType());
+ assert(inst.hasResult());
+ out << "ExtInst(" << inst.opName << ", " << i << ", ";
-+ PrintOperandClasses(inst.operands.classes(), out);
++ std::vector<OperandClassInfo> classes_info;
++ for (const auto& operand_class : inst.operands.classes()) {
++ classes_info.push_back({operand_class, false /* not optional */});
++ }
++ PrintOperandClasses(classes_info, out);
+ out << ")" << std::endl;
+ }
+}
}; // end namespace spv
diff --git a/tools/spirv/assembler_table.cpp b/tools/spirv/assembler_table.cpp
new file mode 100644
-index 0000000..85bca89
+index 0000000..8dd8fa1
--- /dev/null
+++ b/tools/spirv/assembler_table.cpp
-@@ -0,0 +1,214 @@
+@@ -0,0 +1,229 @@
+// Copyright (c) 2015-2016 The Khronos Group Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+ const OperandParameters& operands = inst.operands;
+ for (int i = 0; i < operands.getNum() ; i++) {
+ switch (operands.getClass(i)) {
-+ case spv::OperandOptionalId:
-+ case spv::OperandOptionalImage:
+ case spv::OperandVariableIds:
+ case spv::OperandOptionalLiteral:
+ case spv::OperandOptionalLiteralString:
+ default:
+ break;
+ }
++ if (operands.isOptional(i)) return true;
+ }
+ return false;
+}
+#define CASE(X) case X: return #X;
+ CASE(OperandNone)
+ CASE(OperandId)
-+ CASE(OperandOptionalId)
-+ CASE(OperandOptionalImage)
+ CASE(OperandVariableIds)
+ CASE(OperandOptionalLiteral)
+ CASE(OperandOptionalLiteralString)
+// Prints a listing of the operand kinds for the given instruction.
+// If the list is empty, then emit just "EmptyList",
+// otherwise the output looks like a call to the "List" macro.
-+void PrintOperandClasses(const std::vector<OperandClass>& classes, std::ostream& out) {
++void PrintOperandClasses(const std::vector<OperandClassInfo>& classes, std::ostream& out) {
+ std::stringstream contents;
+ int numPrinted = 0;
-+ for (auto operandClass : classes) {
-+ if (const char* name = GetOperandClassString(operandClass)) {
++ for (auto class_info : classes) {
++ if (const char* name = GetOperandClassString(class_info.value)) {
+ if (numPrinted) contents << ", ";
-+ contents << name;
++ switch (class_info.value) {
++ case OperandId:
++ case OperandImageOperands:
++ case OperandLiteralString:
++ case OperandMemoryAccess:
++ case OperandAccessQualifier:
++ if (class_info.is_optional) {
++ contents << "OperandOptional" << (name + strlen("Operand"));
++ } else {
++ contents << name;
++ }
++ break;
++ default:
++ contents << name;
++ break;
++ }
+ numPrinted++;
++ if (class_info.value == OperandImageOperands) {
++ // There are Id and/or VariableIds after this. Skip them
++ // because the bits in an OperandImageOperands determine
++ // exactly the number of Ids required to follow.
++ break;
++ }
+ }
+ }
+
+} // namespace spv
+
+namespace spv {
-+namespace {
+
+// Prints a listing of the operand kinds for the given instruction.
+// If the list is empty, then emit just "EmptyList",
+// otherwise the output looks like a call to the "List" macro.
+void PrintOperandClassesForInstruction(const InstructionParameters& inst,
+ std::ostream& out) {
-+ std::vector<OperandClass> result;
++ std::vector<OperandClassInfo> result;
+
+ const OperandParameters& operands = inst.operands;
+ for (int i = 0; i < operands.getNum(); i++) {
-+ result.push_back(operands.getClass(i));
++ result.push_back({operands.getClass(i), operands.isOptional(i)});
+ }
+ PrintOperandClasses(result, out);
+}
+ }
+}
+
-+} // anonymous namespace
-+
+void PrintAssemblerTable(std::ostream& out) {
+ out << "// Instruction fields are:\n"
+ << "// name - skips the \"Op\" prefix\n"
+ << "// numCapabilities - we only handle 0 or 1 required capabilities\n"
+ << "// Capability(<capability-name>) - capability required to use this instruction. Might be None.\n"
+ << "// There can be Capability2(a,b) for dependence on two capabilities.\n"
-+ << "// {0|1} - whether the instruction is variable number of words\n"
++ << "// {0|1} - whether the instruction is variable number of logical operands\n"
+ << "// EmptyList or List(...) - list of classes of logical operands\n"
+ << "// Example use:\n"
+ << "// #define EmptyList {}\n"
+}
diff --git a/tools/spirv/assembler_table.h b/tools/spirv/assembler_table.h
new file mode 100644
-index 0000000..b98303a
+index 0000000..16ea384
--- /dev/null
+++ b/tools/spirv/assembler_table.h
-@@ -0,0 +1,49 @@
+@@ -0,0 +1,55 @@
+// Copyright (c) 2015-2016 The Khronos Group Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+
+namespace spv {
+
++ // Relevant facts about an operand class value.
++ struct OperandClassInfo {
++ OperandClass value;
++ bool is_optional;
++ };
++
+ // Prints the tables used to define the structure of instructions.
+ // Assumes that parameterization has already occurred
+ void PrintAssemblerTable(std::ostream& out);
+ // Prints a listing of the operand kinds.
+ // If the list is empty, then emit just "EmptyList",
+ // otherwise the output looks like a call to the "List" macro.
-+ void PrintOperandClasses(const std::vector<OperandClass>& classes, std::ostream& out);
++ void PrintOperandClasses(const std::vector<OperandClassInfo>& classes, std::ostream& out);
+
+}; // end namespace spv
+
+#endif // ASSEMBLER_TABLE_H
diff --git a/tools/spirv/doc.h b/tools/spirv/doc.h
-index 78b1031..a182509 100644
+index 4c11d3b..6e1718a 100644
--- a/tools/spirv/doc.h
+++ b/tools/spirv/doc.h
@@ -32,6 +32,9 @@
// For grouping opcodes into subsections
enum OpcodeClass {
-@@ -159,6 +163,10 @@ enum OperandClass {
+@@ -157,6 +161,10 @@ enum OperandClass {
OperandOpcode,
OperandCount
};
-@@ -257,3 +265,5 @@ const char* AccessQualifierString(int attr);
+@@ -259,3 +267,5 @@ const char* AccessQualifierString(int attr);
void PrintOperands(const OperandParameters& operands, int reservedOperands);
}; // end namespace spv