Generator word now has two 16-bit components

The high 16-bits are a registered generator tool.
These are registered at
https://www.khronos.org/registry/spir-v/api/spir-v.xml

The low 16-bits are tool-specific.  It might be a version number,
for example, but is not constrained by the spec or by the registration
process.

The disassembler prints the tool name when we know it.
If we don't, print "Unknown" and then the numeric tool number
in parentheses.
In all cases, the disassembler prints lower 16-bit number on the
same line but after the tool name.

Also add newly registered generators:
  6: Khronos LLVM/SPIR-V Translator
  7: Khronos SPIR-V Tools Assembler
This commit is contained in:
David Neto 2015-11-12 18:33:47 -05:00
Родитель 5f7ed91e18
Коммит 14b93e49ed
7 изменённых файлов: 94 добавлений и 8 удалений

Просмотреть файл

@ -39,6 +39,7 @@
#include "libspirv/libspirv.h"
#include "opcode.h"
#include "print.h"
#include "spirv_constant.h"
#include "util/hex_float.h"
namespace {
@ -131,9 +132,18 @@ spv_result_t Disassembler::HandleHeader(spv_endianness_t endian,
endian_ = endian;
SetGrey();
const char* generator_tool =
spvGeneratorStr(SPV_GENERATOR_TOOL_PART(generator));
stream_ << "; SPIR-V\n"
<< "; Version: " << version << "\n"
<< "; Generator: " << spvGeneratorStr(generator) << "\n"
<< "; Generator: " << generator_tool;
// For unknown tools, print the numeric tool value.
if (0 == strcmp("Unknown", generator_tool)) {
stream_ << "(" << SPV_GENERATOR_TOOL_PART(generator) << ")";
}
// Print the miscellaneous part of the generator word on the same
// line as the tool name.
stream_ << "; " << SPV_GENERATOR_MISC_PART(generator) << "\n"
<< "; Bound: " << id_bound << "\n"
<< "; Schema: " << schema << "\n";
ResetColor();

Просмотреть файл

@ -298,6 +298,10 @@ const char* spvGeneratorStr(uint32_t generator) {
return "NVIDIA";
case SPV_GENERATOR_ARM:
return "ARM";
case SPV_GENERATOR_KHRONOS_LLVM_TRANSLATOR:
return "Khronos LLVM/SPIR-V Translator";
case SPV_GENERATOR_KHRONOS_ASSEMBLER:
return "Khronos SPIR-V Tools Assembler";
default:
return "Unknown";
}

Просмотреть файл

@ -69,16 +69,31 @@
// Enumerations
// Values mapping to registered vendors. See the registry at
// Values mapping to registered tools. See the registry at
// https://www.khronos.org/registry/spir-v/api/spir-v.xml
// These values occupy the higher order 16 bits of the generator magic word.
typedef enum spv_generator_t {
// TODO(dneto) Values 0 through 5 were registered only as vendor.
SPV_GENERATOR_KHRONOS = 0,
SPV_GENERATOR_LUNARG = 1,
SPV_GENERATOR_VALVE = 2,
SPV_GENERATOR_CODEPLAY = 3,
SPV_GENERATOR_NVIDIA = 4,
SPV_GENERATOR_ARM = 5,
SPV_FORCE_32_BIT_ENUM(spv_generator_t)
// These are vendor and tool.
SPV_GENERATOR_KHRONOS_LLVM_TRANSLATOR = 6,
SPV_GENERATOR_KHRONOS_ASSEMBLER = 7,
SPV_GENERATOR_NUM_ENTRIES,
SPV_FORCE_16_BIT_ENUM(spv_generator_t)
} spv_generator_t;
// Evaluates to a well-formed generator magic word from a tool value and
// miscellaneous 16-bit value.
#define SPV_GENERATOR_WORD(TOOL, MISC) \
((uint32_t(uint16_t(TOOL)) << 16) | uint16_t(MISC))
// Returns the tool component of the generator word.
#define SPV_GENERATOR_TOOL_PART(WORD) (uint32_t(WORD) >> 16)
// Returns the misc part of the generator word.
#define SPV_GENERATOR_MISC_PART(WORD) (uint32_t(WORD) & 0xFFFF)
#endif // LIBSPIRV_SPIRV_CONSTANT_H_

Просмотреть файл

@ -652,18 +652,24 @@ spv_result_t spvTextEncodeOpcode(const libspirv::AssemblyGrammar& grammar,
namespace {
enum {
kAssemblerVersion = 0
};
/// @brief Populate a binary stream's words with this generator's header.
///
/// @param[in,out] words the array of words
/// @param[in] bound the upper ID bound
///
/// @return result code
spv_result_t SetHeader(uint32_t* words, const uint32_t bound) {
spv_result_t
SetHeader(uint32_t* words, const uint32_t bound) {
if (!words) return SPV_ERROR_INVALID_BINARY;
words[SPV_INDEX_MAGIC_NUMBER] = SpvMagicNumber;
words[SPV_INDEX_VERSION_NUMBER] = SpvVersion;
words[SPV_INDEX_GENERATOR_NUMBER] = SPV_GENERATOR_KHRONOS;
words[SPV_INDEX_GENERATOR_NUMBER] =
SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_ASSEMBLER, kAssemblerVersion);
words[SPV_INDEX_BOUND] = bound;
words[SPV_INDEX_SCHEMA] = 0; // NOTE: Reserved

Просмотреть файл

@ -30,10 +30,11 @@
#include "gmock/gmock.h"
#include "TestFixture.h"
#include "../source/spirv_constant.h"
#include "TestFixture.h"
using ::testing::Eq;
using ::testing::HasSubstr;
using spvtest::AutoText;
using spvtest::TextToBinaryTest;
@ -394,4 +395,51 @@ OpStore %2 %3 Aligned|Volatile 4 ; bogus, but not indented
expected);
}
// Test generator string.
// A test case for the generator string. This allows us to
// test both of the 16-bit components of the generator word.
struct GeneratorStringCase {
uint16_t generator;
uint16_t misc;
std::string expected;
};
using GeneratorStringTest = spvtest::TextToBinaryTestBase<
::testing::TestWithParam<GeneratorStringCase>>;
TEST_P(GeneratorStringTest, Sample) {
auto words = CompileSuccessfully("");
EXPECT_EQ(SPV_INDEX_GENERATOR_NUMBER, 2);
words[SPV_INDEX_GENERATOR_NUMBER] =
SPV_GENERATOR_WORD(GetParam().generator, GetParam().misc);
spv_text decoded_text = nullptr;
spv_diagnostic diagnostic = nullptr;
EXPECT_THAT(spvBinaryToText(context, words.data(), words.size(),
SPV_BINARY_TO_TEXT_OPTION_NONE, &decoded_text,
&diagnostic),
Eq(SPV_SUCCESS));
EXPECT_THAT(diagnostic, Eq(nullptr));
EXPECT_THAT(std::string(decoded_text->str), HasSubstr(GetParam().expected));
spvTextDestroy(decoded_text);
}
INSTANTIATE_TEST_CASE_P(GeneratorStrings, GeneratorStringTest,
::testing::ValuesIn(std::vector<GeneratorStringCase>{
{SPV_GENERATOR_KHRONOS, 12, "Khronos; 12"},
{SPV_GENERATOR_LUNARG, 99, "LunarG; 99"},
{SPV_GENERATOR_VALVE, 1, "Valve; 1"},
{SPV_GENERATOR_CODEPLAY, 65535,
"Codeplay Software Ltd.; 65535"},
{SPV_GENERATOR_NVIDIA, 19, "NVIDIA; 19"},
{SPV_GENERATOR_ARM, 1000, "ARM; 1000"},
{SPV_GENERATOR_KHRONOS_LLVM_TRANSLATOR, 38,
"Khronos LLVM/SPIR-V Translator; 38"},
{SPV_GENERATOR_KHRONOS_ASSEMBLER, 2,
"Khronos SPIR-V Tools Assembler; 2"},
{9, 18, "Unknown(9); 18"},
{65535, 32767, "Unknown(65535); 32767"},
}));
} // anonymous namespace

Просмотреть файл

@ -67,7 +67,7 @@ OpFunctionEnd
const std::string spirv_header =
R"(; SPIR-V
; Version: 100
; Generator: Khronos
; Generator: Khronos SPIR-V Tools Assembler; 0
; Bound: 9
; Schema: 0)";
spv_binary binary;

Просмотреть файл

@ -52,13 +52,16 @@ INSTANTIATE_TEST_CASE_P(
{SPV_GENERATOR_CODEPLAY, "Codeplay Software Ltd."},
{SPV_GENERATOR_NVIDIA, "NVIDIA"},
{SPV_GENERATOR_ARM, "ARM"},
{SPV_GENERATOR_KHRONOS_LLVM_TRANSLATOR,
"Khronos LLVM/SPIR-V Translator"},
{SPV_GENERATOR_KHRONOS_ASSEMBLER, "Khronos SPIR-V Tools Assembler"},
}));
INSTANTIATE_TEST_CASE_P(
Unregistered, GeneratorMagicNumberTest,
::testing::ValuesIn(std::vector<EnumCase<spv_generator_t>>{
// Currently value 6 and beyond are unregiestered.
{spv_generator_t(6), "Unknown"},
{spv_generator_t(8), "Unknown"},
{spv_generator_t(9999), "Unknown"},
}));
} // anonymous namespace