1 // Copyright (c) 2015-2016 The Khronos Group Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // Assembler tests for instructions in the "Function" section of the
16 // SPIR-V spec.
17 
18 #include <string>
19 #include <vector>
20 
21 #include "gmock/gmock.h"
22 #include "test/test_fixture.h"
23 #include "test/unit_spirv.h"
24 
25 namespace spvtools {
26 namespace {
27 
28 using spvtest::EnumCase;
29 using spvtest::MakeInstruction;
30 using spvtest::TextToBinaryTest;
31 using ::testing::Eq;
32 
33 // Test OpFunction
34 
35 using OpFunctionControlTest = spvtest::TextToBinaryTestBase<
36     ::testing::TestWithParam<EnumCase<SpvFunctionControlMask>>>;
37 
TEST_P(OpFunctionControlTest,AnySingleFunctionControlMask)38 TEST_P(OpFunctionControlTest, AnySingleFunctionControlMask) {
39   const std::string input = "%result_id = OpFunction %result_type " +
40                             GetParam().name() + " %function_type ";
41   EXPECT_THAT(
42       CompiledInstructions(input),
43       Eq(MakeInstruction(SpvOpFunction, {1, 2, GetParam().value(), 3})));
44 }
45 
46 // clang-format off
47 #define CASE(VALUE,NAME) { SpvFunctionControl##VALUE, NAME }
48 INSTANTIATE_TEST_SUITE_P(TextToBinaryFunctionTest, OpFunctionControlTest,
49                         ::testing::ValuesIn(std::vector<EnumCase<SpvFunctionControlMask>>{
50                             CASE(MaskNone, "None"),
51                             CASE(InlineMask, "Inline"),
52                             CASE(DontInlineMask, "DontInline"),
53                             CASE(PureMask, "Pure"),
54                             CASE(ConstMask, "Const"),
55                         }));
56 #undef CASE
57 // clang-format on
58 
TEST_F(OpFunctionControlTest,CombinedFunctionControlMask)59 TEST_F(OpFunctionControlTest, CombinedFunctionControlMask) {
60   // Sample a single combination.  This ensures we've integrated
61   // the instruction parsing logic with spvTextParseMask.
62   const std::string input =
63       "%result_id = OpFunction %result_type Inline|Pure|Const %function_type";
64   const uint32_t expected_mask = SpvFunctionControlInlineMask |
65                                  SpvFunctionControlPureMask |
66                                  SpvFunctionControlConstMask;
67   EXPECT_THAT(CompiledInstructions(input),
68               Eq(MakeInstruction(SpvOpFunction, {1, 2, expected_mask, 3})));
69 }
70 
TEST_F(OpFunctionControlTest,WrongFunctionControl)71 TEST_F(OpFunctionControlTest, WrongFunctionControl) {
72   EXPECT_THAT(CompileFailure("%r = OpFunction %t Inline|Unroll %ft"),
73               Eq("Invalid function control operand 'Inline|Unroll'."));
74 }
75 
76 // TODO(dneto): OpFunctionParameter
77 // TODO(dneto): OpFunctionEnd
78 // TODO(dneto): OpFunctionCall
79 
80 }  // namespace
81 }  // namespace spvtools
82