Commit b40d6ac9 by John Kessenich

glslang AST -> SPIR-V: Move to new auto-generated official headers, and for the…

glslang AST -> SPIR-V: Move to new auto-generated official headers, and for the disassembler, mirror the split done between the auto-generation header database and the specification. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@30434 e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent 1f77cacd
......@@ -124,7 +124,7 @@ enum Entrypoints {
inline void GetDebugNames(const char** names)
{
for (int i = 0; i < Count; ++i)
names[i] = "unknown";
names[i] = "Unknown";
names[Round] = "round";
names[RoundEven] = "roundEven";
......
......@@ -106,14 +106,14 @@ public:
samplerContentImage,
samplerContentTextureFilter
};
Id makeSampler(Id sampledType, Dimensionality, samplerContent, bool arrayed, bool shadow, bool ms);
Id makeSampler(Id sampledType, Dim, samplerContent, bool arrayed, bool shadow, bool ms);
// For querying about types.
Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
Id getDerefTypeId(Id resultId) const;
OpCode getOpCode(Id id) const { return module.getInstruction(id)->getOpCode(); }
OpCode getTypeClass(Id typeId) const { return getOpCode(typeId); }
OpCode getMostBasicTypeClass(Id typeId) const;
Op getOpCode(Id id) const { return module.getInstruction(id)->getOpCode(); }
Op getTypeClass(Id typeId) const { return getOpCode(typeId); }
Op getMostBasicTypeClass(Id typeId) const;
int getNumComponents(Id resultId) const { return getNumTypeComponents(getTypeId(resultId)); }
int getNumTypeComponents(Id typeId) const;
Id getScalarTypeId(Id typeId) const;
......@@ -151,10 +151,10 @@ public:
}
int getNumRows(Id resultId) const { return getTypeNumRows(getTypeId(resultId)); }
Dimensionality getDimensionality(Id resultId) const
Dim getDimensionality(Id resultId) const
{
assert(isSamplerType(getTypeId(resultId)));
return (Dimensionality)module.getInstruction(getTypeId(resultId))->getImmediateOperand(1);
return (Dim)module.getInstruction(getTypeId(resultId))->getImmediateOperand(1);
}
bool isArrayedSampler(Id resultId) const
{
......@@ -228,14 +228,14 @@ public:
Id createCompositeInsert(Id object, Id composite, Id typeId, unsigned index);
Id createCompositeInsert(Id object, Id composite, Id typeId, std::vector<unsigned>& indexes);
void createNoResultOp(OpCode);
void createNoResultOp(OpCode, Id operand);
void createNoResultOp(Op);
void createNoResultOp(Op, Id operand);
void createControlBarrier(unsigned executionScope);
void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
Id createUnaryOp(OpCode, Id typeId, Id operand);
Id createBinOp(OpCode, Id typeId, Id operand1, Id operand2);
Id createTriOp(OpCode, Id typeId, Id operand1, Id operand2, Id operand3);
Id createTernaryOp(OpCode, Id typeId, Id operand1, Id operand2, Id operand3);
Id createUnaryOp(Op, Id typeId, Id operand);
Id createBinOp(Op, Id typeId, Id operand1, Id operand2);
Id createTriOp(Op, Id typeId, Id operand1, Id operand2, Id operand3);
Id createTernaryOp(Op, Id typeId, Id operand1, Id operand2, Id operand3);
Id createFunctionCall(spv::Function*, std::vector<spv::Id>&);
// Take an rvalue (source) and a set of channels to extract from it to
......@@ -289,7 +289,7 @@ public:
// Emit the OpTextureQuery* instruction that was passed in.
// Figure out the right return value and type, and return it.
Id createTextureQueryCall(OpCode, const TextureParameters&);
Id createTextureQueryCall(Op, const TextureParameters&);
Id createSamplePositionCall(Decoration precision, Id, Id);
......@@ -461,13 +461,13 @@ public:
void dump(std::vector<unsigned int>&) const;
protected:
Id findScalarConstant(OpCode typeClass, Id typeId, unsigned value) const;
Id findCompositeConstant(OpCode typeClass, std::vector<Id>& comps) const;
Id findScalarConstant(Op typeClass, Id typeId, unsigned value) const;
Id findCompositeConstant(Op typeClass, std::vector<Id>& comps) const;
Id collapseAccessChain();
void simplifyAccessChainSwizzle();
void createAndSetNoPredecessorBlock(const char*);
void createBranch(Block* block);
void createMerge(OpCode, Block*, unsigned int control);
void createMerge(Op, Block*, unsigned int control);
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
void dumpInstructions(std::vector<unsigned int>&, const std::vector<Instruction*>&) const;
......
......@@ -40,10 +40,11 @@
// Disassembler for SPIR-V.
//
#include <stdlib.h>
#include <assert.h>
#include <iomanip>
#include <stack>
#include <sstream>
#include "stdlib.h"
#include "GLSL450Lib.h"
extern const char* GlslStd450DebugNames[GLSL_STD_450::Count];
......@@ -69,7 +70,7 @@ public:
void processInstructions();
protected:
OpCode getOpCode(int id) const { return idInstruction[id] ? (OpCode)(stream[idInstruction[id]] & OpCodeMask) : OpNop; }
Op getOpCode(int id) const { return idInstruction[id] ? (Op)(stream[idInstruction[id]] & OpCodeMask) : OpNop; }
// Output methods
void outputIndent();
......@@ -80,7 +81,7 @@ protected:
void disassembleImmediates(int numOperands);
void disassembleIds(int numOperands);
void disassembleString();
void disassembleInstruction(Id resultId, Id typeId, OpCode opCode, int numOperands);
void disassembleInstruction(Id resultId, Id typeId, Op opCode, int numOperands);
// Data
std::ostream& out; // where to write the disassembly
......@@ -144,7 +145,7 @@ void SpirvStream::processInstructions()
// Instruction wordCount and opcode
unsigned int firstWord = stream[word];
unsigned wordCount = firstWord >> WordCountShift;
OpCode opCode = (OpCode)(firstWord & OpCodeMask);
Op opCode = (Op)(firstWord & OpCodeMask);
int nextInst = word + wordCount;
++word;
......@@ -176,7 +177,7 @@ void SpirvStream::processInstructions()
outputTypeId(typeId);
outputIndent();
// Hand off the OpCode and all its operands
// Hand off the Op and all its operands
disassembleInstruction(resultId, typeId, opCode, numOperands);
if (word != nextInst) {
out << " ERROR, incorrect number of operands consumed. At " << word << " instead of " << nextInst << " instruction start was " << instructionStart;
......@@ -277,14 +278,11 @@ void SpirvStream::disassembleString()
out << "\"";
}
void SpirvStream::disassembleInstruction(Id resultId, Id typeId, OpCode opCode, int numOperands)
void SpirvStream::disassembleInstruction(Id resultId, Id typeId, Op opCode, int numOperands)
{
// Process the opcode
if (opCode < 0 || opCode >= OpCount)
Kill(out, "Bad opcode");
else
out << InstructionDesc[opCode].opName + 2; // Skip the "Op"
out << (OpcodeString(opCode) + 2); // leave out the "Op"
if (opCode == OpLoopMerge || opCode == OpSelectionMerge)
nextNestedControl = stream[word];
......@@ -339,7 +337,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id typeId, OpCode opCode,
// Handle textures specially, so can put out helpful strings.
if (opCode == OpTypeSampler) {
disassembleIds(1);
out << " " << DimensionString((Dimensionality)stream[word++]);
out << " " << DimensionString((Dim)stream[word++]);
switch (stream[word++]) {
case 0: out << " texture"; break;
case 1: out << " image"; break;
......@@ -354,7 +352,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id typeId, OpCode opCode,
// Handle all the parameterized operands
for (int op = 0; op < InstructionDesc[opCode].operands.getNum(); ++op) {
out << " ";
switch (InstructionDesc[opCode].operands.getClass(op)) {
OperandClass operandClass = InstructionDesc[opCode].operands.getClass(op);
switch (operandClass) {
case OperandId:
disassembleIds(1);
// Get names for printing "(XXX)" for readability, *after* this id
......@@ -366,7 +365,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id typeId, OpCode opCode,
disassembleIds(numOperands);
return;
case OperandVariableLiterals:
if (opCode == OpDecorate && stream[word - 1] == DecBuiltIn) {
if (opCode == OpDecorate && stream[word - 1] == DecorationBuiltIn) {
out << BuiltInString(stream[word++]);
--numOperands;
++op;
......@@ -376,8 +375,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id typeId, OpCode opCode,
case OperandVariableLiteralId:
while (numOperands > 0) {
out << std::endl;
outputResultId(NoResult);
outputTypeId(NoType);
outputResultId(0);
outputTypeId(0);
outputIndent();
out << " case ";
disassembleImmediates(1);
......@@ -397,76 +396,23 @@ void SpirvStream::disassembleInstruction(Id resultId, Id typeId, OpCode opCode,
case OperandLiteralString:
disassembleString();
return;
case OperandSource:
out << SourceString((SourceLanguage)stream[word++]);
break;
case OperandExecutionModel:
out << ExecutionModelString((ExecutionModel)stream[word++]);
break;
case OperandAddressing:
out << AddressingString((AddressingModel)stream[word++]);
break;
case OperandMemory:
out << MemoryString((MemoryModel)stream[word++]);
break;
case OperandExecutionMode:
out << ExecutionModeString((ExecutionMode)stream[word++]);
break;
case OperandStorage:
out << StorageClassString((StorageClass)stream[word++]);
break;
case OperandDimensionality:
out << DimensionString((Dimensionality)stream[word++]);
break;
case OperandDecoration:
out << DecorationString((Decoration)stream[word++]);
break;
case OperandBuiltIn:
out << BuiltInString((BuiltIn)stream[word++]);
break;
case OperandSelect:
out << SelectControlString((SelectControl)stream[word++]);
break;
case OperandLoop:
out << LoopControlString((LoopControl)stream[word++]);
break;
case OperandFunction:
{
unsigned int control = stream[word++];
if (control == 0)
out << FunctionControlString(control);
else {
for (int m = 0; m < FunctionControlCount; ++m) {
if (control & (1 << m))
out << FunctionControlString(m);
}
}
break;
}
case OperandMemorySemantics:
for (int shift = 0; shift < MemorySemanticsCount; ++shift) {
unsigned lit = (stream[word] & (1 << shift));
if (lit)
out << MemorySemanticsString(lit) << " ";
}
word++;
break;
case OperandMemoryAccess:
out << MemoryAccessString(stream[word++]);
break;
case OperandExecutionScope:
out << ExecutionScopeString(stream[word++]);
break;
case OperandGroupOperation:
out << GroupOperationString(stream[word++]);
break;
case OperandKernelEnqueueFlags:
out << KernelEnqueueFlagsString(stream[word++]);
break;
case OperandKernelProfilingInfo:
out << KernelProfilingInfoString(stream[word++]);
break;
default:
assert(operandClass >= OperandSource && operandClass < OperandOpcode);
if (OperandClassParams[operandClass].bitmask) {
unsigned int mask = stream[word++];
if (mask == 0)
out << "None";
else {
for (int m = 0; m < OperandClassParams[operandClass].ceiling; ++m) {
if (mask & (1 << m))
out << OperandClassParams[operandClass].getName(m) << " ";
}
}
break;
} else
out << OperandClassParams[operandClass].getName(stream[word++]);
break;
}
--numOperands;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -37,8 +37,7 @@
//
//
// Return English versions of instruction/operand information.
// This can be used for disassembly, printing documentation, etc.
// Parameterize the SPIR-V enumerants.
//
#include "spirv.h"
......@@ -47,7 +46,7 @@
namespace spv {
// Fill in all the parameters of the instruction set
// Fill in all the parameters
void Parameterize();
// Return the English names of all the enums.
......@@ -76,6 +75,35 @@ const char* ExecutionScopeString(int);
const char* GroupOperationString(int);
const char* KernelEnqueueFlagsString(int);
const char* KernelProfilingInfoString(int);
const char* OpcodeString(int);
// For grouping opcodes into subsections
enum OpcodeClass {
OpClassMisc, // default, until opcode is classified
OpClassDebug,
OpClassAnnotate,
OpClassExtension,
OpClassMode,
OpClassType,
OpClassConstant,
OpClassMemory,
OpClassFunction,
OpClassTexture,
OpClassConvert,
OpClassComposite,
OpClassArithmetic,
OpClassRelationalLogical,
OpClassDerivative,
OpClassFlowControl,
OpClassAtomic,
OpClassPrimitive,
OpClassBarrier,
OpClassGroup,
OpClassDeviceSideEnqueue,
OpClassPipe,
OpClassCount
};
// For parameterizing operands.
enum OperandClass {
......@@ -99,35 +127,85 @@ enum OperandClass {
OperandFPFastMath,
OperandFPRoundingMode,
OperandLinkageType,
OperandAccessQualifier,
OperandFuncParamAttr,
OperandDecoration,
OperandBuiltIn,
OperandSelect,
OperandLoop,
OperandFunction,
OperandAccessQualifier,
OperandMemorySemantics,
OperandMemoryAccess,
OperandExecutionScope,
OperandGroupOperation,
OperandKernelEnqueueFlags,
OperandKernelProfilingInfo,
OperandOpcode,
OperandCount
};
// Set of capabilities. Generally, something is assumed to be in core,
// if nothing else is said. So, these are used to identify when something
// requires a specific capability to be declared.
enum Capability {
CapMatrix,
CapShader,
CapGeom,
CapTess,
CapAddr,
CapLink,
CapKernel
};
// Any specific enum can have a set of capabilities that allow it:
typedef std::vector<Capability> EnumCaps;
// Parameterize a set of operands with their OperandClass(es) and descriptions.
class OperandParameters {
public:
OperandParameters() { }
void push(OperandClass oc)
void push(OperandClass oc, const char* d)
{
opClass.push_back(oc);
desc.push_back(d);
}
OperandClass getClass(int op) const { return opClass[op]; }
const char* getDesc(int op) const { return desc[op]; }
int getNum() const { return (int)opClass.size(); }
protected:
std::vector<OperandClass> opClass;
std::vector<const char*> desc;
};
// Parameterize an enumerant
class EnumParameters {
public:
EnumParameters() : desc(0) { }
EnumCaps caps;
const char* desc;
};
// Parameterize a set of enumerants that form an enum
class EnumDefinition : public EnumParameters {
public:
EnumDefinition() :
ceiling(0), bitmask(false), getName(0), enumParams(0), operandParams(0) { }
void set(int ceil, const char* (*name)(int), EnumParameters* ep, bool mask = false)
{
ceiling = ceil;
getName = name;
bitmask = mask;
enumParams = ep;
}
void setOperands(OperandParameters* op) { operandParams = op; }
int ceiling; // ceiling of enumerants
bool bitmask; // true if these enumerants combine into a bitmask
const char* (*getName)(int); // a function that returns the name for each enumerant value (or shift)
EnumParameters* enumParams; // parameters for each individual enumerant
OperandParameters* operandParams; // sets of operands
};
// Parameterize an instruction's logical format, including its known set of operands,
......@@ -137,7 +215,8 @@ public:
InstructionParameters() :
typePresent(true), // most normal, only exceptions have to be spelled out
resultPresent(true), // most normal, only exceptions have to be spelled out
opName(0)
opDesc(0),
opClass(OpClassMisc)
{ }
void setResultAndType(bool r, bool t)
......@@ -149,7 +228,9 @@ public:
bool hasResult() const { return resultPresent != 0; }
bool hasType() const { return typePresent != 0; }
const char* opName;
const char* opDesc;
EnumCaps capabilities;
OpcodeClass opClass;
OperandParameters operands;
protected:
......@@ -157,8 +238,19 @@ protected:
int resultPresent : 1;
};
const int OpcodeCeiling = 267;
// The set of objects that hold all the instruction/operand
// parameterization information.
extern InstructionParameters InstructionDesc[spv::OpCount];
extern InstructionParameters InstructionDesc[];
// These hold definitions of the enumerants used for operands
extern EnumDefinition OperandClassParams[];
const char* GetOperandDesc(OperandClass operand);
void PrintImmediateRow(int imm, const char* name, const EnumParameters* enumParams, bool caps, bool hex = false);
const char* AccessQualifierString(int attr);
void PrintOperands(const OperandParameters& operands, int reservedOperands);
}; // end namespace spv
......@@ -60,14 +60,21 @@ namespace spv {
class Function;
class Module;
const Id NoResult = 0;
const Id NoType = 0;
const unsigned int BadValue = 0xFFFFFFFF;
const Decoration NoPrecision = (Decoration)BadValue;
const MemorySemanticsMask MemorySemanticsAllMemory = (MemorySemanticsMask)0x3FF;
//
// SPIR-V IR instruction.
//
class Instruction {
public:
Instruction(Id resultId, Id typeId, OpCode opCode) : resultId(resultId), typeId(typeId), opCode(opCode), string(0) { }
explicit Instruction(OpCode opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), string(0) { }
Instruction(Id resultId, Id typeId, Op opCode) : resultId(resultId), typeId(typeId), opCode(opCode), string(0) { }
explicit Instruction(Op opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), string(0) { }
virtual ~Instruction()
{
delete string;
......@@ -103,7 +110,7 @@ public:
originalString = str;
}
OpCode getOpCode() const { return opCode; }
Op getOpCode() const { return opCode; }
int getNumOperands() const { return operands.size(); }
Id getResultId() const { return resultId; }
Id getTypeId() const { return typeId; }
......@@ -143,7 +150,7 @@ protected:
Instruction(const Instruction&);
Id resultId;
Id typeId;
OpCode opCode;
Op opCode;
std::vector<Id> operands;
std::vector<unsigned int>* string; // usually non-existent
std::string originalString; // could be optimized away; convenience for getting string operand
......@@ -310,7 +317,7 @@ __inline Function::Function(Id id, Id resultType, Id functionType, Id firstParam
: parent(parent), functionInstruction(id, resultType, OpFunction)
{
// OpFunction
functionInstruction.addImmediateOperand(FunctionControlNone);
functionInstruction.addImmediateOperand(FunctionControlMaskNone);
functionInstruction.addIdOperand(functionType);
parent.mapInstruction(&functionInstruction);
parent.addFunction(this);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment