Add an API parameter to choose assembly syntax format for assembler.
authorLei Zhang <antiagainst@google.com>
Thu, 10 Sep 2015 18:00:00 +0000 (14:00 -0400)
committerDavid Neto <dneto@google.com>
Mon, 26 Oct 2015 16:54:39 +0000 (12:54 -0400)
Added a new enum for supported assembly syntax formats:
Canonical Assembly Format (CAF) and Assignment Assembly Format (AAF).

Updated assembler interface functions to support choice of assembly
syntax format.

CMakeLists.txt
include/libspirv/libspirv.h
source/text.cpp
source/text.h
test/AssemblyFormat.cpp [new file with mode: 0644]
test/ImmediateInt.cpp
test/TestFixture.h
test/TextDestroy.cpp
test/TextToBinary.cpp
test/ValidateID.cpp

index 1dea1c8..eab48a2 100644 (file)
@@ -162,6 +162,7 @@ if (NOT ${SPIRV_SKIP_EXECUTABLES})
       ${CMAKE_CURRENT_SOURCE_DIR}/test/TestFixture.h
       ${CMAKE_CURRENT_SOURCE_DIR}/test/UnitSPIRV.h
 
+      ${CMAKE_CURRENT_SOURCE_DIR}/test/AssemblyFormat.cpp
       ${CMAKE_CURRENT_SOURCE_DIR}/test/BinaryDestroy.cpp
       ${CMAKE_CURRENT_SOURCE_DIR}/test/BinaryEndianness.cpp
       ${CMAKE_CURRENT_SOURCE_DIR}/test/BinaryHeaderGet.cpp
index 025175c..9a66354 100644 (file)
@@ -244,6 +244,12 @@ typedef enum spv_binary_to_text_options_t {
   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),
@@ -412,13 +418,32 @@ spv_result_t spvExtInstTableGet(spv_ext_inst_table *pTable);
 /// @param[out] pDiagnostic contains diagnostic on failure
 ///
 /// @return result code
-spv_result_t spvTextToBinary(const char* text,
-                             const uint64_t length,
+spv_result_t spvTextToBinary(const char *text, const uint64_t length,
                              const spv_opcode_table opcodeTable,
                              const spv_operand_table operandTable,
                              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.
index 49dbbdc..8e23b88 100644 (file)
@@ -524,55 +524,64 @@ spv_result_t spvTextEncodeOperand(
 }
 
 spv_result_t spvTextEncodeOpcode(
-    const spv_text text, const spv_opcode_table opcodeTable,
-    const spv_operand_table operandTable, const spv_ext_inst_table extInstTable,
-    spv_named_id_table namedIdTable, uint32_t *pBound, spv_instruction_t *pInst,
-    spv_position position, spv_diagnostic *pDiagnostic) {
+    const spv_text text, spv_assembly_syntax_format_t format,
+    const spv_opcode_table opcodeTable, const spv_operand_table operandTable,
+    const spv_ext_inst_table extInstTable, spv_named_id_table namedIdTable,
+    uint32_t *pBound, spv_instruction_t *pInst, spv_position position,
+    spv_diagnostic *pDiagnostic) {
   // An assembly instruction has two possible formats:
-  // 1. <opcode> <operand>.., e.g., "OpMemoryModel Physical64 OpenCL".
-  // 2. <result-id> = <opcode> <operand>.., e.g., "%void = OpTypeVoid".
+  // 1(CAF): <opcode> <operand>..., e.g., "OpTypeVoid %void".
+  // 2(AAF): <result-id> = <opcode> <operand>..., e.g., "%void = OpTypeVoid".
 
-  // Assume it's the first format at the beginning.
-  std::string opcodeName;
+  std::string firstWord;
   spv_position_t nextPosition = {};
-  spv_result_t error =
-      spvTextWordGet(text, position, opcodeName, &nextPosition);
+  spv_result_t error = spvTextWordGet(text, position, firstWord, &nextPosition);
   spvCheck(error, DIAGNOSTIC << "Internal Error"; return error);
 
   // NOTE: Handle insertion of an immediate integer into the binary stream
   if ('!' == text->str[position->index]) {
-    const char *begin = opcodeName.data() + 1;
+    const char *begin = firstWord.data() + 1;
     char *end = nullptr;
     uint32_t immediateInt = strtoul(begin, &end, 0);
-    size_t size = opcodeName.size() - 1;
+    size_t size = firstWord.size() - 1;
     spvCheck(size != (size_t)(end - begin),
-             DIAGNOSTIC << "Invalid immediate integer '" << opcodeName << "'.";
+             DIAGNOSTIC << "Invalid immediate integer '" << firstWord << "'.";
              return SPV_ERROR_INVALID_TEXT);
-    position->column += opcodeName.size();
-    position->index += opcodeName.size();
+    position->column += firstWord.size();
+    position->index += firstWord.size();
     pInst->words[0] = immediateInt;
     pInst->wordCount = 1;
     return SPV_SUCCESS;
   }
 
-  // Handle value generating instructions (the second format above) here.
+  std::string opcodeName;
   std::string result_id;
   spv_position_t result_id_position = {};
-  // If the word we get doesn't start with "Op", assume it's an <result-id>
-  // from now.
-  spvCheck(!spvStartsWithOp(text, position), result_id = opcodeName);
-  if (!result_id.empty()) {
+  if (spvStartsWithOp(text, position)) {
+    opcodeName = firstWord;
+  } else {
+    // If the first word of this instruction is not an opcode, we must be
+    // processing AAF now.
+    spvCheck(
+        SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT != format,
+        DIAGNOSTIC
+            << "Expected <opcode> at the beginning of an instruction, found '"
+            << firstWord << "'.";
+        return SPV_ERROR_INVALID_TEXT);
+
+    result_id = firstWord;
     spvCheck('%' != result_id.front(),
              DIAGNOSTIC << "Expected <opcode> or <result-id> at the beginning "
                            "of an instruction, found '"
                         << result_id << "'.";
              return SPV_ERROR_INVALID_TEXT);
     result_id_position = *position;
+
+    // The '=' sign.
     *position = nextPosition;
     spvCheck(spvTextAdvance(text, position),
              DIAGNOSTIC << "Expected '=', found end of stream.";
              return SPV_ERROR_INVALID_TEXT);
-    // The '=' sign.
     std::string equal_sign;
     error = spvTextWordGet(text, position, equal_sign, &nextPosition);
     spvCheck("=" != equal_sign, DIAGNOSTIC << "'=' expected after result id.";
@@ -598,6 +607,14 @@ spv_result_t spvTextEncodeOpcode(
   spvCheck(error, DIAGNOSTIC << "Invalid Opcode name '"
                              << getWord(text->str + position->index) << "'";
            return error);
+  if (SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT == format) {
+    // If this instruction has <result-id>, check it follows AAF.
+    spvCheck(opcodeEntry->hasResult && result_id.empty(),
+             DIAGNOSTIC << "Expected <result-id> at the beginning of an "
+                           "instruction, found '"
+                        << firstWord << "'.";
+             return SPV_ERROR_INVALID_TEXT);
+  }
   pInst->opcode = opcodeEntry->opcode;
   *position = nextPosition;
   pInst->wordCount++;
@@ -669,7 +686,6 @@ spv_result_t spvTextEncodeOpcode(
       spvCheck(error, return error);
 
       *position = nextPosition;
-
     }
   }
 
@@ -684,6 +700,7 @@ namespace {
 // If a diagnostic is generated, it is not yet marked as being
 // for a text-based input.
 spv_result_t spvTextToBinaryInternal(const spv_text text,
+                                     spv_assembly_syntax_format_t format,
                                      const spv_opcode_table opcodeTable,
                                      const spv_operand_table operandTable,
                                      const spv_ext_inst_table extInstTable,
@@ -716,9 +733,9 @@ spv_result_t spvTextToBinaryInternal(const spv_text text,
     spv_instruction_t inst = {};
     inst.extInstType = extInstType;
 
-    spvCheck(spvTextEncodeOpcode(text, opcodeTable, operandTable, extInstTable,
-                                 namedIdTable, &bound, &inst, &position,
-                                 pDiagnostic),
+    spvCheck(spvTextEncodeOpcode(text, format, opcodeTable, operandTable,
+                                 extInstTable, namedIdTable, &bound, &inst,
+                                 &position, pDiagnostic),
              spvNamedIdTableDestory(namedIdTable);
              return SPV_ERROR_INVALID_TEXT);
     extInstType = inst.extInstType;
@@ -758,16 +775,27 @@ spv_result_t spvTextToBinaryInternal(const spv_text text,
 
 } // anonymous namespace
 
-spv_result_t spvTextToBinary(const charinput_text,
+spv_result_t spvTextToBinary(const char *input_text,
                              const uint64_t input_text_size,
                              const spv_opcode_table opcodeTable,
                              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};
 
-  spv_result_t result = spvTextToBinaryInternal(
-      &text, opcodeTable, operandTable, extInstTable, pBinary, pDiagnostic);
+  spv_result_t result =
+      spvTextToBinaryInternal(&text, format, opcodeTable, operandTable,
+                              extInstTable, pBinary, pDiagnostic);
   if (pDiagnostic && *pDiagnostic) (*pDiagnostic)->isTextSource = true;
 
   return result;
index 944416c..197f89f 100644 (file)
@@ -191,6 +191,7 @@ spv_result_t spvTextEncodeOperand(
 /// @brief Translate single Opcode and operands to binary form
 ///
 /// @param[in] text stream to translate
+/// @param[in] format the assembly syntax format of text
 /// @param[in] opcodeTable Opcode lookup table
 /// @param[in] operandTable operand lookup table
 /// @param[in,out] namedIdTable table of named ID's
@@ -201,9 +202,10 @@ spv_result_t spvTextEncodeOperand(
 ///
 /// @return result code
 spv_result_t spvTextEncodeOpcode(
-    const spv_text text, const spv_opcode_table opcodeTable,
-    const spv_operand_table operandTable, const spv_ext_inst_table extInstTable,
-    spv_named_id_table namedIdTable, uint32_t *pBound, spv_instruction_t *pInst,
-    spv_position_t *pPosition, spv_diagnostic *pDiagnostic);
+    const spv_text text, spv_assembly_syntax_format_t format,
+    const spv_opcode_table opcodeTable, const spv_operand_table operandTable,
+    const spv_ext_inst_table extInstTable, spv_named_id_table namedIdTable,
+    uint32_t *pBound, spv_instruction_t *pInst, spv_position_t *pPosition,
+    spv_diagnostic *pDiagnostic);
 
 #endif
diff --git a/test/AssemblyFormat.cpp b/test/AssemblyFormat.cpp
new file mode 100644 (file)
index 0000000..1ee133c
--- /dev/null
@@ -0,0 +1,109 @@
+// Copyright (c) 2015 The Khronos Group Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and/or associated documentation files (the
+// "Materials"), to deal in the Materials without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Materials, and to
+// permit persons to whom the Materials are furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Materials.
+//
+// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
+// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
+// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
+//    https://www.khronos.org/registry/
+//
+// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+
+#include "TestFixture.h"
+
+namespace {
+
+using test_fixture::TextToBinaryTest;
+
+TEST_F(TextToBinaryTest, EncodeAAFTextAsAAF) {
+  SetText("%2 = OpConstant %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 = OpConstant %1 1000");
+  EXPECT_EQ(SPV_ERROR_INVALID_TEXT,
+            spvTextWithFormatToBinary(
+                text.str, text.length, SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL,
+                opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
+  ASSERT_TRUE(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) {
+  SetText("OpConstant %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("OpConstant %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_TRUE(diagnostic);
+  EXPECT_STREQ(
+      "Expected <result-id> at the beginning of an instruction, found "
+      "'OpConstant'.",
+      diagnostic->error);
+  EXPECT_EQ(0, diagnostic->position.line);
+}
+
+TEST_F(TextToBinaryTest, EncodeMixedTextAsAAF) {
+  SetText("OpConstant %1 %2 1000\n%3 = OpConstant %1 2000");
+  EXPECT_EQ(SPV_ERROR_INVALID_TEXT,
+            spvTextWithFormatToBinary(
+                text.str, text.length, SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT,
+                opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
+  ASSERT_TRUE(diagnostic);
+  EXPECT_STREQ(
+      "Expected <result-id> at the beginning of an instruction, found "
+      "'OpConstant'.",
+      diagnostic->error);
+  EXPECT_EQ(0, diagnostic->position.line);
+}
+
+TEST_F(TextToBinaryTest, EncodeMixedTextAsCAF) {
+  SetText("OpConstant %1 %2 1000\n%3 = OpConstant %1 2000");
+  EXPECT_EQ(SPV_ERROR_INVALID_TEXT,
+            spvTextWithFormatToBinary(
+                text.str, text.length, SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL,
+                opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
+  ASSERT_TRUE(diagnostic);
+  EXPECT_STREQ(
+      "Expected <opcode> at the beginning of an instruction, found '%3'.",
+      diagnostic->error);
+  EXPECT_EQ(1, diagnostic->position.line);
+}
+
+}  // anonymous namespace
index eafb3e4..5260a69 100644 (file)
@@ -62,15 +62,15 @@ TEST_F(TextToBinaryTest, ImmediateIntOperand) {
 using ImmediateIntTest = TextToBinaryTest;
 
 TEST_F(ImmediateIntTest, AnyWordInSimpleStatement) {
-  const SpirvVector original = CompileSuccessfully("OpConstant %1 %2 123");
+  const SpirvVector original = CompileCAFSuccessfully("OpConstant %1 %2 123");
   // TODO(deki): uncomment assertions below and make them pass.
-  // EXPECT_EQ(original, CompileSuccessfully("!0x0004002B %1 %2 123"));
-  EXPECT_EQ(original, CompileSuccessfully("OpConstant !1 %2 123"));
-  // EXPECT_EQ(original, CompileSuccessfully("OpConstant %1 !2 123"));
-  EXPECT_EQ(original, CompileSuccessfully("OpConstant %1 %2 !123"));
-  // EXPECT_EQ(original, CompileSuccessfully("!0x0004002B %1 !2 123"));
-  EXPECT_EQ(original, CompileSuccessfully("OpConstant !1 %2 !123"));
-  // EXPECT_EQ(original, CompileSuccessfully("!0x0004002B !1 !2 !123"));
+  // EXPECT_EQ(original, CompileCAFSuccessfully("!0x0004002B %1 %2 123"));
+  EXPECT_EQ(original, CompileCAFSuccessfully("OpConstant !1 %2 123"));
+  // EXPECT_EQ(original, CompileCAFSuccessfully("OpConstant %1 !2 123"));
+  EXPECT_EQ(original, CompileCAFSuccessfully("OpConstant %1 %2 !123"));
+  // EXPECT_EQ(original, CompileCAFSuccessfully("!0x0004002B %1 !2 123"));
+  EXPECT_EQ(original, CompileCAFSuccessfully("OpConstant !1 %2 !123"));
+  // EXPECT_EQ(original, CompileCAFSuccessfully("!0x0004002B !1 !2 !123"));
 }
 
 TEST_F(ImmediateIntTest, AnyWordInAssignmentStatement) {
@@ -90,37 +90,37 @@ TEST_F(ImmediateIntTest, AnyWordInAssignmentStatement) {
 
 // Literal integers after !<integer> are handled correctly.
 TEST_F(ImmediateIntTest, IntegerFollowingImmediate) {
-  const SpirvVector original = CompileSuccessfully("OpTypeInt %1 8 1");
+  const SpirvVector original = CompileCAFSuccessfully("OpTypeInt %1 8 1");
   // TODO(deki): uncomment assertions below and make them pass.
-  // EXPECT_EQ(original, CompileSuccessfully("!0x00040015 1 8 1"));
-  // EXPECT_EQ(original, CompileSuccessfully("OpTypeInt !1 8 1"));
+  // EXPECT_EQ(original, CompileCAFSuccessfully("!0x00040015 1 8 1"));
+  // EXPECT_EQ(original, CompileCAFSuccessfully("OpTypeInt !1 8 1"));
 
   // 64-bit integer literal.
-  EXPECT_EQ(CompileSuccessfully("OpConstant %10 %1 5000000000"),
-            CompileSuccessfully("OpConstant %10 !1 5000000000"));
+  EXPECT_EQ(CompileCAFSuccessfully("OpConstant %10 %1 5000000000"),
+            CompileCAFSuccessfully("OpConstant %10 !1 5000000000"));
 
   // Negative integer.
-  EXPECT_EQ(CompileSuccessfully("OpConstant %10 %1 -123"),
-            CompileSuccessfully("OpConstant %10 !1 -123"));
+  EXPECT_EQ(CompileCAFSuccessfully("OpConstant %10 %1 -123"),
+            CompileCAFSuccessfully("OpConstant %10 !1 -123"));
 
   // Hex value(s).
-  // EXPECT_EQ(CompileSuccessfully("OpConstant %10 %1 0x12345678"),
-  //           CompileSuccessfully("OpConstant %10 !1 0x12345678"));
-  // EXPECT_EQ(CompileSuccessfully("OpConstant %10 %1 0x12345678 0x87654321"),
-  //           CompileSuccessfully("OpConstant %10 !1 0x12345678 0x87654321"));
+  // EXPECT_EQ(CompileCAFSuccessfully("OpConstant %10 %1 0x12345678"),
+  //           CompileCAFSuccessfully("OpConstant %10 !1 0x12345678"));
+  // EXPECT_EQ(CompileCAFSuccessfully("OpConstant %10 %1 0x12345678 0x87654321"),
+  //           CompileCAFSuccessfully("OpConstant %10 !1 0x12345678 0x87654321"));
 }
 
 // Literal floats after !<integer> are handled correctly.
 TEST_F(ImmediateIntTest, FloatFollowingImmediate) {
-  EXPECT_EQ(CompileSuccessfully("OpConstant %10 %1 0.123"),
-            CompileSuccessfully("OpConstant %10 !1 0.123"));
-  EXPECT_EQ(CompileSuccessfully("OpConstant %10 %1 -0.5"),
-            CompileSuccessfully("OpConstant %10 !1 -0.5"));
+  EXPECT_EQ(CompileCAFSuccessfully("OpConstant %10 %1 0.123"),
+            CompileCAFSuccessfully("OpConstant %10 !1 0.123"));
+  EXPECT_EQ(CompileCAFSuccessfully("OpConstant %10 %1 -0.5"),
+            CompileCAFSuccessfully("OpConstant %10 !1 -0.5"));
   // 64-bit float.
   EXPECT_EQ(
-      CompileSuccessfully(
+      CompileCAFSuccessfully(
           "OpConstant %10 %1 9999999999999999999999999999999999999999.9"),
-      CompileSuccessfully(
+      CompileCAFSuccessfully(
           "OpConstant %10 !1 9999999999999999999999999999999999999999.9"));
 }
 
@@ -129,12 +129,11 @@ TEST_F(ImmediateIntTest, StringFollowingImmediate) {
   // Try a variety of strings, including empty and single-character.
   for (std::string name : {"", "s", "longish"}) {
     const SpirvVector original =
-        CompileSuccessfully("OpMemberName %10 4 \"" + name + "\"");
+        CompileCAFSuccessfully("OpMemberName %10 4 \"" + name + "\"");
     EXPECT_EQ(original,
-              CompileSuccessfully("OpMemberName %10 !4 \"" + name + "\""));
+              CompileCAFSuccessfully("OpMemberName %10 !4 \"" + name + "\""));
     // TODO(deki): uncomment assertions below and make them pass.
-    // EXPECT_EQ(original,
-    //           CompileSuccessfully("!0x00040006 !10 4 \"" + name + "\""));
+    // EXPECT_EQ(original, CompileCAFSuccessfully("!0x00040006 !10 4 \"" + name + "\""));
   }
 }
 
@@ -142,40 +141,41 @@ TEST_F(ImmediateIntTest, StringFollowingImmediate) {
 TEST_F(ImmediateIntTest, IdFollowingImmediate) {
 // TODO(deki): uncomment assertions below and make them pass.
 #if 0
-  EXPECT_EQ(CompileSuccessfully("OpDecorationGroup %123"),
-            CompileSuccessfully("!0x00020049 %123"));
-  EXPECT_EQ(CompileSuccessfully("OpDecorationGroup %group"),
-            CompileSuccessfully("!0x00020049 %group"));
+  EXPECT_EQ(CompileCAFSuccessfully("OpDecorationGroup %123"),
+            CompileCAFSuccessfully("!0x00020049 %123"));
+  EXPECT_EQ(CompileCAFSuccessfully("OpDecorationGroup %group"),
+            CompileCAFSuccessfully("!0x00020049 %group"));
 #endif
 }
 
 // !<integer> after !<integer> is handled correctly.
 TEST_F(ImmediateIntTest, ImmediateFollowingImmediate) {
-  const SpirvVector original = CompileSuccessfully("OpTypeMatrix %11 %10 7");
-  EXPECT_EQ(original, CompileSuccessfully("OpTypeMatrix %11 !10 !7"));
+  const SpirvVector original = CompileCAFSuccessfully("OpTypeMatrix %11 %10 7");
+  EXPECT_EQ(original, CompileCAFSuccessfully("OpTypeMatrix %11 !10 !7"));
   // TODO(deki): uncomment assertions below and make them pass.
-  // EXPECT_EQ(original, CompileSuccessfully("!0x00040018 %11 !10 !7"));
+  // EXPECT_EQ(original, CompileCAFSuccessfully("!0x00040018 %11 !10 !7"));
 }
 
 TEST_F(ImmediateIntTest, InvalidStatement) {
-  EXPECT_THAT(Subvector(CompileSuccessfully("!4 !3 !2 !1"), kFirstInstruction),
-              ElementsAre(4, 3, 2, 1));
+  EXPECT_THAT(
+      Subvector(CompileCAFSuccessfully("!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"),
-                kFirstInstruction),
-      ElementsAre(spvOpcodeMake(3, spv::OpTypeFloat), 10, 32, 5, 6, 7,
-                  spvOpcodeMake(1, spv::OpEmitVertex)));
+  EXPECT_THAT(Subvector(CompileCAFSuccessfully(
+                            "OpTypeFloat %10 32 !5 !6 !7 OpEmitVertex"),
+                        kFirstInstruction),
+              ElementsAre(spvOpcodeMake(3, spv::OpTypeFloat), 10, 32, 5, 6, 7,
+                          spvOpcodeMake(1, spv::OpEmitVertex)));
 }
 
 TEST_F(ImmediateIntTest, NextOpcodeRecognized) {
-  const SpirvVector original = CompileSuccessfully(R"(
+  const SpirvVector original = CompileCAFSuccessfully(R"(
 OpLoad %10 %1 %2 Volatile
 OpCompositeInsert %11 %4 %1 %3 0 1 2
 )");
-  const SpirvVector alternate = CompileSuccessfully(R"(
+  const SpirvVector alternate = CompileCAFSuccessfully(R"(
 OpLoad %10 %1 %2 !1
 OpCompositeInsert %11 %4 %1 %3 0 1 2
 )");
@@ -183,13 +183,13 @@ OpCompositeInsert %11 %4 %1 %3 0 1 2
 }
 
 TEST_F(ImmediateIntTest, WrongLengthButNextOpcodeStillRecognized) {
-  const SpirvVector original = CompileSuccessfully(R"(
+  const SpirvVector original = CompileCAFSuccessfully(R"(
 OpLoad %10 %1 %2 Volatile
 OpCopyMemorySized %3 %4 %1
 )");
 // TODO(deki): uncomment assertions below and make them pass.
 #if 0
-  const SpirvVector alternate = CompileSuccessfully(R"(
+  const SpirvVector alternate = CompileCAFSuccessfully(R"(
 !0x0002003D %10 %1 %2 !1
 OpCopyMemorySized %3 %4 %1
 )");
@@ -200,13 +200,15 @@ OpCopyMemorySized %3 %4 %1
 }
 
 // Like NextOpcodeRecognized, but next statement is in assignment form.
-TEST_F(ImmediateIntTest, NextAssignmentRecognized) {
+// TODO(deki): enable this after adding proper support for !<integer> at the
+// beginning of an instruction.
+TEST_F(ImmediateIntTest, DISABLED_NextAssignmentRecognized) {
   const SpirvVector original = CompileSuccessfully(R"(
-OpLoad %10 %1 %2 None
+%1 = OpLoad %10 %2 None
 %4 = OpFunctionCall %10 %3 123
 )");
   const SpirvVector alternate = CompileSuccessfully(R"(
-OpLoad %10 !1 %2 !0
+!1 = OpLoad %10 %2 !0
 %4 = OpFunctionCall %10 %3 123
 )");
   EXPECT_EQ(original, alternate);
@@ -215,8 +217,8 @@ OpLoad %10 !1 %2 !0
 // Two instructions in a row each have !<integer> opcode.
 TEST_F(ImmediateIntTest, ConsecutiveImmediateOpcodes) {
   const SpirvVector original = CompileSuccessfully(R"(
-OpConstantSampler %10 %1 Clamp 78 Linear
-OpFRem %11 %4 %3 %2
+%1 = OpConstantSampler %10 Clamp 78 Linear
+%4 = OpFRem %11 %3 %2
 %5 = OpIsValidEvent %12 %2
 )");
 // TODO(deki): uncomment assertions below and make them pass.
index bbc2580..2754b3e 100644 (file)
@@ -65,12 +65,13 @@ class TextToBinaryTestBase : public T {
     return SpirvVector(v.begin() + from, v.end());
   }
 
-  // Compiles SPIR-V text, asserting compilation success.  Returns the compiled
-  // code.
-  SpirvVector CompileSuccessfully(const std::string& text) {
-    spv_result_t status =
-        spvTextToBinary(text.c_str(), text.size(), opcodeTable, operandTable,
-                        extInstTable, &binary, &diagnostic);
+  // Compiles SPIR-V text in the given assembly syntax format, asserting
+  // compilation success. Returns the compiled code.
+  SpirvVector CompileWithFormatSuccessfully(
+      const std::string& text, spv_assembly_syntax_format_t format) {
+    spv_result_t status = spvTextWithFormatToBinary(
+        text.c_str(), text.size(), format, opcodeTable, operandTable,
+        extInstTable, &binary, &diagnostic);
     EXPECT_EQ(SPV_SUCCESS, status) << text;
     SpirvVector code_copy;
     if (status == SPV_SUCCESS) {
@@ -81,6 +82,18 @@ class TextToBinaryTestBase : public T {
     }
     return code_copy;
   }
+  // Compiles SPIR-V text in the Assignment Assembly Format, asserting success.
+  // Returns the compiled code.
+  SpirvVector CompileSuccessfully(const std::string& text) {
+    return CompileWithFormatSuccessfully(text,
+                                         SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT);
+  }
+  // Compiles SPIR-V text in the Canonical Assembly Format, asserting success.
+  // Returns the compiled code.
+  SpirvVector CompileCAFSuccessfully(const std::string& text) {
+    return CompileWithFormatSuccessfully(text,
+                                         SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL);
+  }
 
   // Compiles SPIR-V text, asserting compilation failure.  Returns the error
   // message(s).
index 023d932..e1e99b7 100644 (file)
@@ -28,9 +28,7 @@
 
 namespace {
 
-TEST(TextDestroy, DestroyNull) {
-  spvBinaryDestroy(nullptr);
-}
+TEST(TextDestroy, DestroyNull) { spvBinaryDestroy(nullptr); }
 
 TEST(TextDestroy, Default) {
   spv_opcode_table opcodeTable;
@@ -67,8 +65,9 @@ TEST(TextDestroy, Default) {
   spv_binary binary = nullptr;
   spv_diagnostic diagnostic = nullptr;
   EXPECT_EQ(SPV_SUCCESS,
-            spvTextToBinary(textStr, strlen(textStr), opcodeTable, operandTable,
-                            extInstTable, &binary, &diagnostic));
+            spvTextWithFormatToBinary(
+                textStr, strlen(textStr), SPV_ASSEMBLY_SYNTAX_FORMAT_CANONICAL,
+                opcodeTable, operandTable, extInstTable, &binary, &diagnostic));
   EXPECT_NE(nullptr, binary);
   EXPECT_NE(nullptr, binary->code);
   EXPECT_NE(0, binary->wordCount);
index 64c484b..7fc7327 100644 (file)
@@ -262,37 +262,6 @@ TEST_F(TextToBinaryTest, StringSpace) {
   }
 }
 
-// TODO(antiagainst): we might not want to support both instruction formats in
-// the future. Only the "<result-id> = <opcode> <operand>.." one may survive.
-TEST_F(TextToBinaryTest, InstructionTwoFormats) {
-  SetText(R"(
-            OpCapability Shader
- %glsl450 = OpExtInstImport "GLSL.std.450"
-            OpMemoryModel Logical Simple
-            OpTypeBool %3
-       %4 = OpTypeInt 8 0
-            OpTypeInt %5 8 1
-       %6 = OpTypeInt 16 0
-            OpTypeInt %7 16 1
-    %void = OpTypeVoid
-            OpTypeFloat %float 32
-%const1.5 = OpConstant %float 1.5
-            OpTypeFunction %fnMain %void
-    %main = OpFunction %void None %fnMain
-            OpLabel %lbMain
-  %result = OpExtInst $float $glsl450 Round $const1.5
-            OpReturn
-            OpFunctionEnd
-)");
-
-  EXPECT_EQ(SPV_SUCCESS,
-            spvTextToBinary(text.str, text.length, opcodeTable, operandTable,
-                            extInstTable, &binary, &diagnostic));
-  if (diagnostic) {
-    spvDiagnosticPrint(diagnostic);
-  }
-}
-
 TEST_F(TextToBinaryTest, UnknownBeginningOfInstruction) {
   SetText(R"(
      OpSource OpenCL 12
@@ -357,8 +326,7 @@ TEST_F(TextToBinaryTest, WrongOpCode) {
 }
 
 TEST_F(TextToBinaryTest, GoodSwitch) {
-  const SpirvVector code = CompileSuccessfully(
-      R"(
+  const SpirvVector code = CompileSuccessfully(R"(
 %i32      = OpTypeInt 32 0
 %fortytwo = OpConstant %i32 42
 %twelve   = OpConstant %i32 12
index 8bcec99..2c6bc04 100644 (file)
@@ -411,7 +411,7 @@ TEST_F(ValidateID, OpConstantTrueBad) {
 
 TEST_F(ValidateID, OpConstantFalseGood) {
   const char *spirv = R"(
-OpTypeBool %1
+%1 = OpTypeBool
 %2 = OpConstantTrue %1)";
   CHECK(spirv, SPV_SUCCESS);
 }