SPV_FORCE_32_BIT_ENUM(spv_binary_to_text_options_t)
} spv_binary_to_text_options_t;
-typedef enum spv_assembly_syntax_format_t {
- SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT, // Assignment Assembly Format
- SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL, // Canonical Assembly Format
- SPV_ASSEMBLY_SYNTAX_FORMAT_DEFAULT = SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT,
-} spv_assembly_syntax_format_t;
-
typedef enum spv_validate_options_t {
SPV_VALIDATE_BASIC_BIT = SPV_BIT(0),
SPV_VALIDATE_LAYOUT_BIT = SPV_BIT(1),
const spv_ext_inst_table extInstTable,
spv_binary* pBinary, spv_diagnostic* pDiagnostic);
-/// @brief Entry point to covert text form to binary form
-///
-/// @param[in] text input text
-/// @param[in] length of the input text
-/// @param[in] format the assembly syntax format of text
-/// @param[in] opcodeTable of specified Opcodes
-/// @param[in] operandTable of specified operands
-/// @param[in] extInstTable of specified extended instructions
-/// @param[out] pBinary the binary module
-/// @param[out] pDiagnostic contains diagnostic on failure
-///
-/// @return result code
-spv_result_t spvTextWithFormatToBinary(const char* text, const uint64_t length,
- spv_assembly_syntax_format_t format,
- const spv_opcode_table opcodeTable,
- const spv_operand_table operandTable,
- const spv_ext_inst_table extInstTable,
- spv_binary* pBinary,
- spv_diagnostic* pDiagnostic);
-
/// @brief Free an allocated text stream
///
/// This is a no-op if the text parameter is a null pointer.
const spv_ext_inst_table extInstTable,
spv_text* pText, spv_diagnostic* pDiagnostic);
-/// @brief Entry point to convert binary to text form
-///
-/// @param[in] binary the input binary
-/// @param[in] wordCount the number of input words
-/// @param[in] options bitfield of spv_binary_to_text_options_t values
-/// @param[in] opcodeTable table of specified Opcodes
-/// @param[in] operandTable table of specified operands
-/// @param[in] extInstTable of specified extended instructions
-/// @param[in] format the assembly syntax format of text
-/// @param[out] pText the textual form
-/// @param[out] pDiagnostic contains diagnostic on failure
-///
-/// @return result code
-spv_result_t spvBinaryToTextWithFormat(
- const uint32_t* binary, const uint64_t wordCount, const uint32_t options,
- const spv_opcode_table opcodeTable, const spv_operand_table operandTable,
- const spv_ext_inst_table extInstTable, spv_assembly_syntax_format_t format,
- spv_text* pText, spv_diagnostic* pDiagnostic);
-
/// @brief Free a binary stream from memory.
///
/// This is a no-op if binary is a null pointer.
class Disassembler {
public:
Disassembler(const libspirv::AssemblyGrammar& grammar, uint32_t const* words,
- size_t num_words, spv_assembly_syntax_format_t format,
- uint32_t options)
+ size_t num_words, uint32_t options)
: words_(words),
num_words_(num_words),
grammar_(grammar),
- format_(format),
print_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_PRINT, options)),
color_(print_ &&
spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_COLOR, options)),
// Emits a mask expression for the given mask word of the specified type.
void EmitMaskOperand(const spv_operand_type_t type, const uint32_t word);
- // Returns true if using the assignment-oriented format.
- // Otherwise, emit canonical form.
- bool IsAssignmentForm() const {
- return format_ == SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT;
- }
-
// Resets the output color, if color is turned on.
void ResetColor() {
if (color_) out_.get() << clr::reset();
const uint32_t* const words_;
const size_t num_words_;
const libspirv::AssemblyGrammar& grammar_;
- const spv_assembly_syntax_format_t format_;
const bool print_; // Should we also print to the standard output stream?
const bool color_; // Should we print in colour?
spv_endianness_t endian_; // The detected endianness of the binary.
spv_result_t Disassembler::HandleInstruction(
const spv_parsed_instruction_t& inst) {
- if (IsAssignmentForm() && inst.result_id) {
+ if (inst.result_id) {
SetBlue();
stream_ << "%" << inst.result_id << " = ";
ResetColor();
for (uint16_t i = 0; i < inst.num_operands; i++) {
const spv_operand_type_t type = inst.operands[i].type;
assert(type != SPV_OPERAND_TYPE_NONE);
- if (type == SPV_OPERAND_TYPE_RESULT_ID && IsAssignmentForm()) continue;
+ if (type == SPV_OPERAND_TYPE_RESULT_ID) continue;
stream_ << " ";
EmitOperand(inst, i);
}
const uint32_t word = spvFixWord(words_[index], endian_);
switch (operand.type) {
case SPV_OPERAND_TYPE_RESULT_ID:
+ assert(false && "<result-id> is not supposed to be handled here");
SetBlue();
stream_ << "%" << word;
break;
spv_result_t spvBinaryToText(const uint32_t* code, const uint64_t wordCount,
const uint32_t options,
- const spv_opcode_table opcodeTable,
- const spv_operand_table operandTable,
- const spv_ext_inst_table extInstTable,
+ const spv_opcode_table opcode_table,
+ const spv_operand_table operand_table,
+ const spv_ext_inst_table ext_inst_table,
spv_text* pText, spv_diagnostic* pDiagnostic) {
- return spvBinaryToTextWithFormat(
- code, wordCount, options, opcodeTable, operandTable, extInstTable,
- SPV_ASSEMBLY_SYNTAX_FORMAT_DEFAULT, pText, pDiagnostic);
-}
-
-spv_result_t spvBinaryToTextWithFormat(
- uint32_t const* code, const uint64_t wordCount, const uint32_t options,
- const spv_opcode_table opcode_table, const spv_operand_table operand_table,
- const spv_ext_inst_table ext_inst_table,
- spv_assembly_syntax_format_t format, spv_text* pText,
- spv_diagnostic* pDiagnostic) {
// Invalid arguments return error codes, but don't necessarily generate
// diagnostics. These are programmer errors, not user errors.
if (!pDiagnostic) return SPV_ERROR_INVALID_DIAGNOSTIC;
ext_inst_table);
if (!grammar.isValid()) return SPV_ERROR_INVALID_TABLE;
- Disassembler disassembler(grammar, code, wordCount, format, options);
+ Disassembler disassembler(grammar, code, wordCount, options);
if (auto error =
spvBinaryParse(&disassembler, code, wordCount, DisassembleHeader,
DisassembleInstruction, pDiagnostic)) {
/// @param[in] grammar the grammar to use for compilation
/// @param[in, out] context the dynamic compilation info
/// @param[in] text stream to translate
-/// @param[in] format the assembly syntax format of text
/// @param[out] pInst returned binary Opcode
/// @param[in,out] pPosition in the text stream
///
/// @return result code
spv_result_t spvTextEncodeOpcode(const libspirv::AssemblyGrammar& grammar,
libspirv::AssemblyContext* context,
- spv_assembly_syntax_format_t format,
spv_instruction_t* pInst) {
// Check for !<integer> first.
if ('!' == context->peek()) {
return encodeInstructionStartingWithImmediate(grammar, context, pInst);
}
- // An assembly instruction has two possible formats:
- // 1(CAF): <opcode> <operand>..., e.g., "OpTypeVoid %void".
- // 2(AAF): <result-id> = <opcode> <operand>..., e.g., "%void = OpTypeVoid".
-
std::string firstWord;
spv_position_t nextPosition = {};
spv_result_t error = context->getWord(firstWord, &nextPosition);
if (context->startsWithOp()) {
opcodeName = firstWord;
} else {
- // If the first word of this instruction is not an opcode, we must be
- // processing AAF now.
- if (SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT != format) {
- return context->diagnostic()
- << "Expected <opcode> at the beginning of an instruction, found '"
- << firstWord << "'.";
- }
-
result_id = firstWord;
if ('%' != result_id.front()) {
return context->diagnostic()
return context->diagnostic(error) << "Invalid Opcode name '"
<< context->getWord() << "'";
}
- if (SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT == format) {
- // If this instruction has <result-id>, check it follows AAF.
- if (opcodeEntry->hasResult && result_id.empty()) {
- return context->diagnostic()
- << "Expected <result-id> at the beginning of an "
- "instruction, found '"
- << firstWord << "'.";
- }
+ if (opcodeEntry->hasResult && result_id.empty()) {
+ return context->diagnostic()
+ << "Expected <result-id> at the beginning of an instruction, found '"
+ << firstWord << "'.";
}
pInst->opcode = opcodeEntry->opcode;
context->setPosition(nextPosition);
// If a diagnostic is generated, it is not yet marked as being
// for a text-based input.
spv_result_t spvTextToBinaryInternal(const libspirv::AssemblyGrammar& grammar,
- const spv_text text,
- spv_assembly_syntax_format_t format,
- spv_binary* pBinary,
+ const spv_text text, spv_binary* pBinary,
spv_diagnostic* pDiagnostic) {
if (!pDiagnostic) return SPV_ERROR_INVALID_DIAGNOSTIC;
libspirv::AssemblyContext context(text, pDiagnostic);
spv_instruction_t& inst = instructions.back();
inst.extInstType = extInstType;
- if (spvTextEncodeOpcode(grammar, &context, format, &inst)) {
+ if (spvTextEncodeOpcode(grammar, &context, &inst)) {
return SPV_ERROR_INVALID_TEXT;
}
extInstType = inst.extInstType;
const spv_operand_table operandTable,
const spv_ext_inst_table extInstTable,
spv_binary* pBinary, spv_diagnostic* pDiagnostic) {
- return spvTextWithFormatToBinary(
- input_text, input_text_size, SPV_ASSEMBLY_SYNTAX_FORMAT_DEFAULT,
- opcodeTable, operandTable, extInstTable, pBinary, pDiagnostic);
-}
-
-spv_result_t spvTextWithFormatToBinary(
- const char* input_text, const uint64_t input_text_size,
- spv_assembly_syntax_format_t format, const spv_opcode_table opcodeTable,
- const spv_operand_table operandTable, const spv_ext_inst_table extInstTable,
- spv_binary* pBinary, spv_diagnostic* pDiagnostic) {
spv_text_t text = {input_text, input_text_size};
-
libspirv::AssemblyGrammar grammar(operandTable, opcodeTable, extInstTable);
+
spv_result_t result =
- spvTextToBinaryInternal(grammar, &text, format, pBinary, pDiagnostic);
+ spvTextToBinaryInternal(grammar, &text, pBinary, pDiagnostic);
if (pDiagnostic && *pDiagnostic) (*pDiagnostic)->isTextSource = true;
return result;
using spvtest::TextToBinaryTest;
-TEST_F(TextToBinaryTest, EncodeAAFTextAsAAF) {
- SetText("%2 = OpTypeMatrix %1 1000");
- EXPECT_EQ(SPV_SUCCESS,
- spvTextWithFormatToBinary(
- text.str, text.length, SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT,
- opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
- if (diagnostic) {
- spvDiagnosticPrint(diagnostic);
- }
-}
-
-TEST_F(TextToBinaryTest, EncodeAAFTextAsCAF) {
- SetText("%2 = OpTypeMatrix %1 1000");
- EXPECT_EQ(SPV_ERROR_INVALID_TEXT,
- spvTextWithFormatToBinary(
- text.str, text.length, SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL,
- opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
- ASSERT_NE(nullptr, diagnostic);
- EXPECT_STREQ(
- "Expected <opcode> at the beginning of an instruction, found '%2'.",
- diagnostic->error);
- EXPECT_EQ(0, diagnostic->position.line);
-}
-
-TEST_F(TextToBinaryTest, EncodeCAFTextAsCAF) {
+TEST_F(TextToBinaryTest, NotPlacingResultIDAtTheBeginning) {
SetText("OpTypeMatrix %1 %2 1000");
- EXPECT_EQ(SPV_SUCCESS,
- spvTextWithFormatToBinary(
- text.str, text.length, SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL,
- opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
- if (diagnostic) {
- spvDiagnosticPrint(diagnostic);
- }
-}
-
-TEST_F(TextToBinaryTest, EncodeCAFTextAsAAF) {
- SetText("OpTypeMatrix %1 %2 1000");
- EXPECT_EQ(SPV_ERROR_INVALID_TEXT,
- spvTextWithFormatToBinary(
- text.str, text.length, SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT,
- opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
- ASSERT_NE(nullptr, diagnostic);
- EXPECT_STREQ(
- "Expected <result-id> at the beginning of an instruction, found "
- "'OpTypeMatrix'.",
- diagnostic->error);
- EXPECT_EQ(0, diagnostic->position.line);
-}
-
-TEST_F(TextToBinaryTest, EncodeMixedTextAsAAF) {
- SetText("OpTypeMatrix %1 %2 1000\n%3 = OpTypeMatrix %1 2000");
EXPECT_EQ(SPV_ERROR_INVALID_TEXT,
- spvTextWithFormatToBinary(
- text.str, text.length, SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT,
- opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
+ spvTextToBinary(text.str, text.length, opcodeTable, operandTable,
+ extInstTable, &binary, &diagnostic));
ASSERT_NE(nullptr, diagnostic);
EXPECT_STREQ(
"Expected <result-id> at the beginning of an instruction, found "
EXPECT_EQ(0, diagnostic->position.line);
}
-TEST_F(TextToBinaryTest, EncodeMixedTextAsCAF) {
- SetText("OpTypeMatrix %1 %2 1000\n%3 = OpTypeMatrix %1 2000");
- EXPECT_EQ(SPV_ERROR_INVALID_TEXT,
- spvTextWithFormatToBinary(
- text.str, text.length, SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL,
- opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
- ASSERT_NE(nullptr, diagnostic);
- EXPECT_STREQ(
- "Expected <opcode> at the beginning of an instruction, found '%3'.",
- diagnostic->error);
- EXPECT_EQ(1, diagnostic->position.line);
-}
-
-const char* kBound4Preamble =
- "; SPIR-V\n; Version: 99\n; Generator: Khronos\n; Bound: 4\n; Schema: 0\n";
-
-TEST_F(TextToBinaryTest, DecodeAAFAsAAF) {
- const std::string assembly =
- "%1 = OpTypeMatrix %2 1000\n%3 = OpTypeMatrix %2 2000\n";
- SetText(assembly);
- EXPECT_EQ(SPV_SUCCESS,
- spvTextWithFormatToBinary(
- text.str, text.length, SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT,
- opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
- spv_text decoded_text;
- EXPECT_EQ(SPV_SUCCESS,
- spvBinaryToTextWithFormat(binary->code, binary->wordCount,
- SPV_BINARY_TO_TEXT_OPTION_NONE,
- opcodeTable, operandTable, extInstTable,
- SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT,
- &decoded_text, &diagnostic));
- EXPECT_EQ(kBound4Preamble + assembly, decoded_text->str);
- spvTextDestroy(decoded_text);
-}
-
-TEST_F(TextToBinaryTest, DecodeAAFAsCAF) {
- const std::string assembly =
- "%1 = OpTypeMatrix %2 1000\n%3 = OpTypeMatrix %2 2000\n";
- SetText(assembly);
- EXPECT_EQ(SPV_SUCCESS,
- spvTextWithFormatToBinary(
- text.str, text.length, SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT,
- opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
- spv_text decoded_text;
- EXPECT_EQ(SPV_SUCCESS,
- spvBinaryToTextWithFormat(binary->code, binary->wordCount,
- SPV_BINARY_TO_TEXT_OPTION_NONE,
- opcodeTable, operandTable, extInstTable,
- SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL,
- &decoded_text, &diagnostic));
- EXPECT_EQ(std::string(kBound4Preamble) +
- "OpTypeMatrix %1 %2 1000\nOpTypeMatrix %3 %2 2000\n",
- decoded_text->str);
- spvTextDestroy(decoded_text);
-}
-
-TEST_F(TextToBinaryTest, DecodeCAFAsAAF) {
- const std::string assembly =
- "OpTypeMatrix %1 %2 1000\nOpTypeMatrix %3 %2 2000\n";
- SetText(assembly);
- EXPECT_EQ(SPV_SUCCESS,
- spvTextWithFormatToBinary(
- text.str, text.length, SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL,
- opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
- spv_text decoded_text;
- EXPECT_EQ(SPV_SUCCESS,
- spvBinaryToTextWithFormat(binary->code, binary->wordCount,
- SPV_BINARY_TO_TEXT_OPTION_NONE,
- opcodeTable, operandTable, extInstTable,
- SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT,
- &decoded_text, &diagnostic));
- EXPECT_EQ(std::string(kBound4Preamble) +
- "%1 = OpTypeMatrix %2 1000\n%3 = OpTypeMatrix %2 2000\n",
- decoded_text->str);
- spvTextDestroy(decoded_text);
-}
-
-TEST_F(TextToBinaryTest, DecodeCAFAsCAF) {
- const std::string assembly =
- "OpTypeMatrix %1 %2 1000\nOpTypeMatrix %3 %2 2000\n";
- SetText(assembly);
- EXPECT_EQ(SPV_SUCCESS,
- spvTextWithFormatToBinary(
- text.str, text.length, SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL,
- opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
- spv_text decoded_text;
- EXPECT_EQ(SPV_SUCCESS,
- spvBinaryToTextWithFormat(binary->code, binary->wordCount,
- SPV_BINARY_TO_TEXT_OPTION_NONE,
- opcodeTable, operandTable, extInstTable,
- SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL,
- &decoded_text, &diagnostic));
- EXPECT_EQ(std::string(kBound4Preamble) +
- "OpTypeMatrix %1 %2 1000\nOpTypeMatrix %3 %2 2000\n",
- decoded_text->str);
- spvTextDestroy(decoded_text);
-}
-
} // anonymous namespace
using ::testing::HasSubstr;
using ::testing::StrEq;
-const auto kCAF = SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL;
-
TEST_F(TextToBinaryTest, ImmediateIntOpCode) {
SetText("!0x00FF00FF");
ASSERT_EQ(SPV_SUCCESS,
using ImmediateIntTest = TextToBinaryTest;
TEST_F(ImmediateIntTest, AnyWordInSimpleStatement) {
- EXPECT_THAT(CompiledInstructions("!0x00040018 %a %b %123", kCAF),
+ EXPECT_THAT(CompiledInstructions("!0x00040018 %a %b %123"),
Eq(MakeInstruction(SpvOpTypeMatrix, {1, 2, 3})));
- EXPECT_THAT(CompiledInstructions("OpTypeMatrix !1 %b %123", kCAF),
+ EXPECT_THAT(CompiledInstructions("!0x00040018 !1 %b %123"),
Eq(MakeInstruction(SpvOpTypeMatrix, {1, 1, 2})));
- EXPECT_THAT(CompiledInstructions("OpTypeMatrix %1 !2 %123", kCAF),
+ EXPECT_THAT(CompiledInstructions("%a = OpTypeMatrix !2 %123"),
Eq(MakeInstruction(SpvOpTypeMatrix, {1, 2, 2})));
- EXPECT_THAT(CompiledInstructions("OpTypeMatrix %a %b !123", kCAF),
+ EXPECT_THAT(CompiledInstructions("%a = OpTypeMatrix %b !123"),
Eq(MakeInstruction(SpvOpTypeMatrix, {1, 2, 123})));
- EXPECT_THAT(CompiledInstructions("!0x00040018 %1 !2 %123", kCAF),
+ EXPECT_THAT(CompiledInstructions("!0x00040018 %a !2 %123"),
Eq(MakeInstruction(SpvOpTypeMatrix, {1, 2, 2})));
- EXPECT_THAT(CompiledInstructions("OpTypeMatrix !1 %b !123", kCAF),
+ EXPECT_THAT(CompiledInstructions("!0x00040018 !1 %b !123"),
Eq(MakeInstruction(SpvOpTypeMatrix, {1, 1, 123})));
- EXPECT_THAT(CompiledInstructions("!0x00040018 !1 !2 !123", kCAF),
+ EXPECT_THAT(CompiledInstructions("!0x00040018 !1 !2 !123"),
Eq(MakeInstruction(SpvOpTypeMatrix, {1, 2, 123})));
}
// Literal integers after !<integer> are handled correctly.
TEST_F(ImmediateIntTest, IntegerFollowingImmediate) {
- const SpirvVector original = CompiledInstructions("OpTypeInt %1 8 1", kCAF);
- EXPECT_EQ(original, CompiledInstructions("!0x00040015 1 8 1", kCAF));
- EXPECT_EQ(original, CompiledInstructions("OpTypeInt !1 8 1", kCAF));
+ const SpirvVector original = CompiledInstructions("%1 = OpTypeInt 8 1");
+ EXPECT_EQ(original, CompiledInstructions("!0x00040015 1 8 1"));
+ EXPECT_EQ(original, CompiledInstructions("!0x00040015 !1 8 1"));
// With !<integer>, we can (and can only) accept 32-bit number literals,
// even when we declare the return type is 64-bit.
MakeInstruction(SpvOpTypeInt, {1, 64, 0}),
MakeInstruction(SpvOpConstant, {1, 2, 4294967295}),
}),
- CompiledInstructions("OpTypeInt %i64 64 0\n"
- "OpConstant %i64 !2 4294967295",
- kCAF));
+ CompiledInstructions("%i64 = OpTypeInt 64 0\n"
+ "!0x0004002b %i64 !2 4294967295"));
// 64-bit integer literal.
EXPECT_EQ("Invalid word following !<integer>: 5000000000",
- CompileFailure("OpConstant !1 %2 5000000000", kCAF));
+ CompileFailure("%2 = OpConstant !1 5000000000"));
EXPECT_EQ("Invalid word following !<integer>: 5000000000",
- CompileFailure("OpTypeInt %i64 64 0\n"
- "OpConstant %i64 !2 5000000000",
- kCAF));
+ CompileFailure("%i64 = OpTypeInt 64 0\n"
+ "!0x0005002b %i64 !2 5000000000"));
// Negative integer.
- EXPECT_EQ(CompiledInstructions("OpTypeInt %i64 32 1\n"
- "OpConstant %i64 %2 -123",
- kCAF),
- CompiledInstructions("OpTypeInt %i64 32 1\n"
- "OpConstant %i64 !2 -123",
- kCAF));
+ EXPECT_EQ(CompiledInstructions("%i64 = OpTypeInt 32 1\n"
+ "%2 = OpConstant %i64 -123"),
+ CompiledInstructions("%i64 = OpTypeInt 32 1\n"
+ "!0x0004002b %i64 !2 -123"));
// TODO(deki): uncomment assertions below and make them pass.
// Hex value(s).
- // EXPECT_EQ(CompileSuccessfully("OpConstant %10 %1 0x12345678", kCAF),
+ // EXPECT_EQ(CompileSuccessfully("%1 = OpConstant %10 0x12345678"),
// CompileSuccessfully("OpConstant %10 !1 0x12345678", kCAF));
// EXPECT_EQ(
- // CompileSuccessfully("OpConstant %10 %1 0x12345678 0x87654321", kCAF),
+ // CompileSuccessfully("%1 = OpConstant %10 0x12345678 0x87654321"),
// CompileSuccessfully("OpConstant %10 !1 0x12345678 0x87654321", kCAF));
}
// Literal floats after !<integer> are handled correctly.
TEST_F(ImmediateIntTest, FloatFollowingImmediate) {
EXPECT_EQ(
- CompiledInstructions("OpTypeFloat %1 32\nOpConstant %1 %2 0.123", kCAF),
- CompiledInstructions("OpTypeFloat %1 32\nOpConstant %1 !2 0.123", kCAF));
+ CompiledInstructions("%1 = OpTypeFloat 32\n%2 = OpConstant %1 0.123"),
+ CompiledInstructions("%1 = OpTypeFloat 32\n!0x0004002b %1 !2 0.123"));
EXPECT_EQ(
- CompiledInstructions("OpTypeFloat %1 32\nOpConstant %1 %2 -0.5", kCAF),
- CompiledInstructions("OpTypeFloat %1 32\nOpConstant %1 !2 -0.5", kCAF));
+ CompiledInstructions("%1 = OpTypeFloat 32\n%2 = OpConstant %1 -0.5"),
+ CompiledInstructions("%1 = OpTypeFloat 32\n!0x0004002b %1 !2 -0.5"));
EXPECT_EQ(
- CompiledInstructions("OpTypeFloat %1 32\nOpConstant %1 %2 0.123", kCAF),
- CompiledInstructions("OpTypeFloat %1 32\n!0x0004002b %1 %2 0.123", kCAF));
+ CompiledInstructions("%1 = OpTypeFloat 32\n%2 = OpConstant %1 0.123"),
+ CompiledInstructions("%1 = OpTypeFloat 32\n!0x0004002b %1 %2 0.123"));
EXPECT_EQ(
- CompiledInstructions("OpTypeFloat %1 32\nOpConstant %1 %2 -0.5", kCAF),
- CompiledInstructions("OpTypeFloat %1 32\n!0x0004002b %1 %2 -0.5", kCAF));
+ CompiledInstructions("%1 = OpTypeFloat 32\n%2 = OpConstant %1 -0.5"),
+ CompiledInstructions("%1 = OpTypeFloat 32\n!0x0004002b %1 %2 -0.5"));
EXPECT_EQ(Concatenate({
MakeInstruction(SpvOpTypeInt, {1, 64, 0}),
// Try a variety of strings, including empty and single-character.
for (std::string name : {"", "s", "longish", "really looooooooooooooooong"}) {
const SpirvVector original =
- CompiledInstructions("OpMemberName %10 4 \"" + name + "\"", kCAF);
- EXPECT_EQ(original, CompiledInstructions(
- "OpMemberName %10 !4 \"" + name + "\"", kCAF))
+ CompiledInstructions("OpMemberName %10 4 \"" + name + "\"");
+ EXPECT_EQ(original,
+ CompiledInstructions("OpMemberName %10 !4 \"" + name + "\""))
<< name;
EXPECT_EQ(original,
- CompiledInstructions("OpMemberName !1 !4 \"" + name + "\"", kCAF))
+ CompiledInstructions("OpMemberName !1 !4 \"" + name + "\""))
<< name;
const uint32_t wordCount = 4 + name.size() / 4;
const uint32_t firstWord = spvOpcodeMake(wordCount, SpvOpMemberName);
EXPECT_EQ(original, CompiledInstructions("!" + std::to_string(firstWord) +
- " %10 !4 \"" + name + "\"",
- kCAF))
+ " %10 !4 \"" + name + "\""))
<< name;
}
}
// IDs after !<integer> are handled correctly.
TEST_F(ImmediateIntTest, IdFollowingImmediate) {
- EXPECT_EQ(CompileSuccessfully("OpDecorationGroup %123", kCAF),
- CompileSuccessfully("!0x00020049 %123", kCAF));
- EXPECT_EQ(CompileSuccessfully("OpDecorationGroup %group", kCAF),
- CompileSuccessfully("!0x00020049 %group", kCAF));
+ EXPECT_EQ(CompileSuccessfully("%123 = OpDecorationGroup"),
+ CompileSuccessfully("!0x00020049 %123"));
+ EXPECT_EQ(CompileSuccessfully("%group = OpDecorationGroup"),
+ CompileSuccessfully("!0x00020049 %group"));
}
// !<integer> after !<integer> is handled correctly.
TEST_F(ImmediateIntTest, ImmediateFollowingImmediate) {
- const SpirvVector original =
- CompiledInstructions("OpTypeMatrix %a %b 7", kCAF);
- EXPECT_EQ(original, CompiledInstructions("OpTypeMatrix %a !2 !7", kCAF));
- EXPECT_EQ(original, CompiledInstructions("!0x00040018 %a !2 !7", kCAF));
+ const SpirvVector original = CompiledInstructions("%a = OpTypeMatrix %b 7");
+ EXPECT_EQ(original, CompiledInstructions("%a = OpTypeMatrix !2 !7"));
+ EXPECT_EQ(original, CompiledInstructions("!0x00040018 %a !2 !7"));
}
TEST_F(ImmediateIntTest, InvalidStatement) {
- EXPECT_THAT(
- Subvector(CompileSuccessfully("!4 !3 !2 !1", kCAF), kFirstInstruction),
- ElementsAre(4, 3, 2, 1));
+ EXPECT_THAT(Subvector(CompileSuccessfully("!4 !3 !2 !1"), kFirstInstruction),
+ ElementsAre(4, 3, 2, 1));
}
TEST_F(ImmediateIntTest, InvalidStatementBetweenValidOnes) {
EXPECT_THAT(Subvector(CompileSuccessfully(
- "OpTypeFloat %10 32 !5 !6 !7 OpEmitVertex", kCAF),
+ "%10 = OpTypeFloat 32 !5 !6 !7 OpEmitVertex"),
kFirstInstruction),
ElementsAre(spvOpcodeMake(3, SpvOpTypeFloat), 1, 32, 5, 6, 7,
spvOpcodeMake(1, SpvOpEmitVertex)));
TEST_F(ImmediateIntTest, NextOpcodeRecognized) {
const SpirvVector original = CompileSuccessfully(R"(
-OpLoad %10 %1 %2 Volatile
-OpCompositeInsert %11 %4 %1 %3 0 1 2
-)",
- kCAF);
+%1 = OpLoad %10 %2 Volatile
+%4 = OpCompositeInsert %11 %1 %3 0 1 2
+)");
const SpirvVector alternate = CompileSuccessfully(R"(
-OpLoad %10 %1 %2 !1
-OpCompositeInsert %11 %4 %1 %3 0 1 2
-)",
- kCAF);
+%1 = OpLoad %10 %2 !1
+%4 = OpCompositeInsert %11 %1 %3 0 1 2
+)");
EXPECT_EQ(original, alternate);
}
TEST_F(ImmediateIntTest, WrongLengthButNextOpcodeStillRecognized) {
const SpirvVector original = CompileSuccessfully(R"(
-OpLoad %10 %1 %2 Volatile
+%1 = OpLoad %10 %2 Volatile
OpCopyMemorySized %3 %4 %1
-)",
- kCAF);
+)");
const SpirvVector alternate = CompileSuccessfully(R"(
!0x0002003D %10 %1 %2 !1
OpCopyMemorySized %3 %4 %1
-)",
- kCAF);
+)");
EXPECT_EQ(0x0002003D, alternate[kFirstInstruction]);
EXPECT_EQ(Subvector(original, kFirstInstruction + 1),
Subvector(alternate, kFirstInstruction + 1));
// Compiles SPIR-V text in the given assembly syntax format, asserting
// compilation success. Returns the compiled code.
- SpirvVector CompileSuccessfully(const std::string& text,
- spv_assembly_syntax_format_t format =
- SPV_ASSEMBLY_SYNTAX_FORMAT_DEFAULT) {
- spv_result_t status = spvTextWithFormatToBinary(
- text.c_str(), text.size(), format, opcodeTable, operandTable,
- extInstTable, &binary, &diagnostic);
+ SpirvVector CompileSuccessfully(const std::string& text) {
+ spv_result_t status =
+ spvTextToBinary(text.c_str(), text.size(), opcodeTable, operandTable,
+ extInstTable, &binary, &diagnostic);
EXPECT_EQ(SPV_SUCCESS, status) << text;
SpirvVector code_copy;
if (status == SPV_SUCCESS) {
// Compiles SPIR-V text with the given format, asserting compilation failure.
// Returns the error message(s).
- std::string CompileFailure(const std::string& text,
- spv_assembly_syntax_format_t format =
- SPV_ASSEMBLY_SYNTAX_FORMAT_DEFAULT) {
+ std::string CompileFailure(const std::string& text) {
EXPECT_NE(SPV_SUCCESS,
- spvTextWithFormatToBinary(text.c_str(), text.size(), format,
- opcodeTable, operandTable, extInstTable,
- &binary, &diagnostic))
+ spvTextToBinary(text.c_str(), text.size(), opcodeTable,
+ operandTable, extInstTable, &binary, &diagnostic))
<< text;
DestroyBinary();
return diagnostic->error;
// Returns the error message.
std::string EncodeSuccessfullyDecodeFailed(
const std::string& text, const SpirvVector& words_to_append) {
- SpirvVector code = spvtest::Concatenate(
- {CompileSuccessfully(text, SPV_ASSEMBLY_SYNTAX_FORMAT_DEFAULT),
- words_to_append});
+ SpirvVector code =
+ spvtest::Concatenate({CompileSuccessfully(text), words_to_append});
spv_text decoded_text;
EXPECT_NE(SPV_SUCCESS,
// Compiles SPIR-V text, asserts success, and returns the words representing
// the instructions. In particular, skip the words in the SPIR-V header.
- SpirvVector CompiledInstructions(const std::string& text,
- spv_assembly_syntax_format_t format) {
- const SpirvVector code = CompileSuccessfully(text, format);
+ SpirvVector CompiledInstructions(const std::string& text) {
+ const SpirvVector code = CompileSuccessfully(text);
SpirvVector result;
// Extract just the instructions.
// If the code fails to compile, then return the empty vector.
return result;
}
- // Compiles SPIR-V text with the default assembly format, asserts success, and
- // returns the words representing the instructions. In particular, skip the
- // words in the SPIR-V header.
- SpirvVector CompiledInstructions(const std::string& text) {
- return CompiledInstructions(text, SPV_ASSEMBLY_SYNTAX_FORMAT_DEFAULT);
- }
-
void SetText(const std::string& code) {
textString = code;
text.str = textString.c_str();
OpSourceExtension "PlaceholderExtensionName"
OpEntryPoint Kernel %0 ""
OpExecutionMode %0 LocalSizeHint 1 1 1
- OpTypeVoid %1
- OpTypeBool %2
- OpTypeInt %3 8 0
- OpTypeInt %4 8 1
- OpTypeInt %5 16 0
- OpTypeInt %6 16 1
- OpTypeInt %7 32 0
- OpTypeInt %8 32 1
- OpTypeInt %9 64 0
- OpTypeInt %10 64 1
- OpTypeFloat %11 16
- OpTypeFloat %12 32
- OpTypeFloat %13 64
- OpTypeVector %14 %3 2
+ %1 = OpTypeVoid
+ %2 = OpTypeBool
+ %3 = OpTypeInt 8 0
+ %4 = OpTypeInt 8 1
+ %5 = OpTypeInt 16 0
+ %6 = OpTypeInt 16 1
+ %7 = OpTypeInt 32 0
+ %8 = OpTypeInt 32 1
+ %9 = OpTypeInt 64 0
+ %10 = OpTypeInt 64 1
+ %11 = OpTypeFloat 16
+ %12 = OpTypeFloat 32
+ %13 = OpTypeFloat 64
+ %14 = OpTypeVector %3 2
)";
spv_binary binary = nullptr;
spv_diagnostic diagnostic = nullptr;
EXPECT_EQ(SPV_SUCCESS,
- spvTextWithFormatToBinary(
- textStr, strlen(textStr), SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL,
- opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
+ spvTextToBinary(textStr, strlen(textStr), opcodeTable, operandTable,
+ extInstTable, &binary, &diagnostic));
EXPECT_NE(nullptr, binary);
EXPECT_NE(nullptr, binary->code);
EXPECT_NE(0, binary->wordCount);
Eq("Expected id to start with %."));
}
-TEST_F(TextToBinaryTest, SwitchBadInvalidLiteralDefaultFormat) {
+TEST_F(TextToBinaryTest, SwitchBadInvalidLiteral) {
// The assembler recognizes "OpSwitch %selector %default" as a complete
- // instruction. Then it tries to parse "%abc" as the start of an
- // assignment form instruction, but can't since it hits the end
- // of stream.
+ // instruction. Then it tries to parse "%abc" as the start of a new
+ // instruction, but can't since it hits the end of stream.
const auto input = R"(%i32 = OpTypeInt 32 0
%selector = OpConstant %i32 42
OpSwitch %selector %default %abc)";
EXPECT_THAT(CompileFailure(input), Eq("Expected '=', found end of stream."));
}
-TEST_F(TextToBinaryTest, SwitchBadInvalidLiteralCanonicalFormat) {
- const auto input = R"(OpTypeInt %i32 32 0
- OpConstant %i32 %selector 42
- OpSwitch %selector %default %abc)";
- EXPECT_THAT(CompileFailure(input, SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL),
- Eq("Expected <opcode> at the beginning of an instruction, found "
- "'%abc'."));
-}
-
TEST_F(TextToBinaryTest, SwitchBadMissingTarget) {
EXPECT_THAT(CompileFailure("%1 = OpTypeInt 32 0\n"
"%2 = OpConstant %1 52\n"
#include <libspirv/libspirv.h>
#include <stdio.h>
-#include <string.h>
#include <vector>
void print_usage(char* argv0) {
printf(
"Assemble a *.svasm file into a *.sv binary.\n\n"
"USAGE: %s [options] <filename>\n\n"
- " --assembly-format=[assignment|canonical]\n"
- " set accepted assembly syntax format (default: assignment)\n"
" -o set the output filename\n",
argv0);
}
const char* inFile = nullptr;
const char* outFile = nullptr;
- const char* assembly_format_prefix = "--assembly-format=";
- spv_assembly_syntax_format_t format = SPV_ASSEMBLY_SYNTAX_FORMAT_DEFAULT;
-
for (int argi = 1; argi < argc; ++argi) {
if ('-' == argv[argi][0]) {
- if (!strncmp(assembly_format_prefix, argv[argi],
- strlen(assembly_format_prefix))) {
- const char* parameter = argv[argi] + strlen(assembly_format_prefix);
- if (!strcmp("canonical", parameter)) {
- format = SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL;
- } else if (!strcmp("assignment", parameter)) {
- format = SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT;
- } else {
- print_usage(argv[0]);
- return 1;
- }
- } else {
- switch (argv[argi][1]) {
- case 'o': {
- if (!outFile && argi + 1 < argc) {
- outFile = argv[++argi];
- } else {
- print_usage(argv[0]);
- return 1;
- }
- } break;
- default:
+ switch (argv[argi][1]) {
+ case 'o': {
+ if (!outFile && argi + 1 < argc) {
+ outFile = argv[++argi];
+ } else {
print_usage(argv[0]);
return 1;
- }
+ }
+ } break;
+ default:
+ print_usage(argv[0]);
+ return 1;
}
} else {
if (!inFile) {
spv_binary binary;
spv_diagnostic diagnostic = nullptr;
- error = spvTextWithFormatToBinary(contents.data(), contents.size(), format,
- opcodeTable, operandTable, extInstTable,
- &binary, &diagnostic);
+ error = spvTextToBinary(contents.data(), contents.size(), opcodeTable,
+ operandTable, extInstTable, &binary, &diagnostic);
if (error) {
spvDiagnosticPrint(diagnostic);
spvDiagnosticDestroy(diagnostic);
#include <libspirv/libspirv.h>
#include <stdio.h>
-#include <string.h>
#include <vector>
void print_usage(char* argv0) {
printf(
"Dissassemble a *.sv file into a *.svasm text file.\n\n"
"USAGE: %s [options] <filename>\n\n"
- " --assembly-format=[assignment|canonical]\n"
- " set decoded assembly syntax format\n"
- " (default: assignment)\n"
" -o <filename> set the output filename\n"
" -p print dissassembly to stdout, this\n"
" overrides file output\n",
const char* inFile = nullptr;
const char* outFile = nullptr;
- const char* assembly_format_prefix = "--assembly-format=";
- spv_assembly_syntax_format_t format = SPV_ASSEMBLY_SYNTAX_FORMAT_DEFAULT;
-
for (int argi = 1; argi < argc; ++argi) {
if ('-' == argv[argi][0]) {
- if (!strncmp(assembly_format_prefix, argv[argi],
- strlen(assembly_format_prefix))) {
- const char* parameter = argv[argi] + strlen(assembly_format_prefix);
- if (!strcmp("canonical", parameter)) {
- format = SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL;
- } else if (!strcmp("assignment", parameter)) {
- format = SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT;
- } else {
- print_usage(argv[0]);
- return 1;
- }
- } else {
- switch (argv[argi][1]) {
- case 'o': {
- if (!outFile && argi + 1 < argc) {
- outFile = argv[++argi];
- } else {
- print_usage(argv[0]);
- return 1;
- }
- } break;
- case 'p': {
- options |= SPV_BINARY_TO_TEXT_OPTION_PRINT;
-#ifdef SPV_COLOR_TERMINAL
- options |= SPV_BINARY_TO_TEXT_OPTION_COLOR;
-#endif
- } break;
- default:
+ switch (argv[argi][1]) {
+ case 'o': {
+ if (!outFile && argi + 1 < argc) {
+ outFile = argv[++argi];
+ } else {
print_usage(argv[0]);
return 1;
- }
+ }
+ } break;
+ case 'p': {
+ options |= SPV_BINARY_TO_TEXT_OPTION_PRINT;
+#ifdef SPV_COLOR_TERMINAL
+ options |= SPV_BINARY_TO_TEXT_OPTION_COLOR;
+#endif
+ } break;
+ default:
+ print_usage(argv[0]);
+ return 1;
}
} else {
if (!inFile) {
spv_text text;
spv_text* textOrNull = printOptionOn ? nullptr : &text;
spv_diagnostic diagnostic = nullptr;
- error = spvBinaryToTextWithFormat(contents.data(), contents.size(), options,
- opcodeTable, operandTable, extInstTable,
- format, textOrNull, &diagnostic);
+ error =
+ spvBinaryToText(contents.data(), contents.size(), options, opcodeTable,
+ operandTable, extInstTable, textOrNull, &diagnostic);
if (error) {
spvDiagnosticPrint(diagnostic);
spvDiagnosticDestroy(diagnostic);