1fd4e5da5Sopenharmony_ci// Copyright (c) 2015-2016 The Khronos Group Inc.
2fd4e5da5Sopenharmony_ci//
3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
6fd4e5da5Sopenharmony_ci//
7fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
13fd4e5da5Sopenharmony_ci// limitations under the License.
14fd4e5da5Sopenharmony_ci
15fd4e5da5Sopenharmony_ci// Assembler tests for instructions in the "Barrier Instructions" section
16fd4e5da5Sopenharmony_ci// of the SPIR-V spec.
17fd4e5da5Sopenharmony_ci
18fd4e5da5Sopenharmony_ci#include <string>
19fd4e5da5Sopenharmony_ci
20fd4e5da5Sopenharmony_ci#include "gmock/gmock.h"
21fd4e5da5Sopenharmony_ci#include "test/test_fixture.h"
22fd4e5da5Sopenharmony_ci#include "test/unit_spirv.h"
23fd4e5da5Sopenharmony_ci
24fd4e5da5Sopenharmony_cinamespace spvtools {
25fd4e5da5Sopenharmony_cinamespace {
26fd4e5da5Sopenharmony_ci
27fd4e5da5Sopenharmony_ciusing spvtest::MakeInstruction;
28fd4e5da5Sopenharmony_ciusing spvtest::TextToBinaryTest;
29fd4e5da5Sopenharmony_ciusing ::testing::_;
30fd4e5da5Sopenharmony_ciusing ::testing::ElementsAre;
31fd4e5da5Sopenharmony_ciusing ::testing::Eq;
32fd4e5da5Sopenharmony_ci
33fd4e5da5Sopenharmony_ci// Test OpMemoryBarrier
34fd4e5da5Sopenharmony_ci
35fd4e5da5Sopenharmony_ciusing OpMemoryBarrier = spvtest::TextToBinaryTest;
36fd4e5da5Sopenharmony_ci
37fd4e5da5Sopenharmony_ciTEST_F(OpMemoryBarrier, Good) {
38fd4e5da5Sopenharmony_ci  const std::string input = "OpMemoryBarrier %1 %2\n";
39fd4e5da5Sopenharmony_ci  EXPECT_THAT(CompiledInstructions(input),
40fd4e5da5Sopenharmony_ci              Eq(MakeInstruction(spv::Op::OpMemoryBarrier, {1, 2})));
41fd4e5da5Sopenharmony_ci  EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(input));
42fd4e5da5Sopenharmony_ci}
43fd4e5da5Sopenharmony_ci
44fd4e5da5Sopenharmony_ciTEST_F(OpMemoryBarrier, BadMissingScopeId) {
45fd4e5da5Sopenharmony_ci  const std::string input = "OpMemoryBarrier\n";
46fd4e5da5Sopenharmony_ci  EXPECT_THAT(CompileFailure(input),
47fd4e5da5Sopenharmony_ci              Eq("Expected operand for OpMemoryBarrier instruction, but found "
48fd4e5da5Sopenharmony_ci                 "the end of the stream."));
49fd4e5da5Sopenharmony_ci}
50fd4e5da5Sopenharmony_ci
51fd4e5da5Sopenharmony_ciTEST_F(OpMemoryBarrier, BadInvalidScopeId) {
52fd4e5da5Sopenharmony_ci  const std::string input = "OpMemoryBarrier 99\n";
53fd4e5da5Sopenharmony_ci  EXPECT_THAT(CompileFailure(input), Eq("Expected id to start with %."));
54fd4e5da5Sopenharmony_ci}
55fd4e5da5Sopenharmony_ci
56fd4e5da5Sopenharmony_ciTEST_F(OpMemoryBarrier, BadMissingMemorySemanticsId) {
57fd4e5da5Sopenharmony_ci  const std::string input = "OpMemoryBarrier %scope\n";
58fd4e5da5Sopenharmony_ci  EXPECT_THAT(CompileFailure(input),
59fd4e5da5Sopenharmony_ci              Eq("Expected operand for OpMemoryBarrier instruction, but found "
60fd4e5da5Sopenharmony_ci                 "the end of the stream."));
61fd4e5da5Sopenharmony_ci}
62fd4e5da5Sopenharmony_ci
63fd4e5da5Sopenharmony_ciTEST_F(OpMemoryBarrier, BadInvalidMemorySemanticsId) {
64fd4e5da5Sopenharmony_ci  const std::string input = "OpMemoryBarrier %scope 14\n";
65fd4e5da5Sopenharmony_ci  EXPECT_THAT(CompileFailure(input), Eq("Expected id to start with %."));
66fd4e5da5Sopenharmony_ci}
67fd4e5da5Sopenharmony_ci
68fd4e5da5Sopenharmony_ci// TODO(dneto): OpControlBarrier
69fd4e5da5Sopenharmony_ci// TODO(dneto): OpGroupAsyncCopy
70fd4e5da5Sopenharmony_ci// TODO(dneto): OpGroupWaitEvents
71fd4e5da5Sopenharmony_ci// TODO(dneto): OpGroupAll
72fd4e5da5Sopenharmony_ci// TODO(dneto): OpGroupAny
73fd4e5da5Sopenharmony_ci// TODO(dneto): OpGroupBroadcast
74fd4e5da5Sopenharmony_ci// TODO(dneto): OpGroupIAdd
75fd4e5da5Sopenharmony_ci// TODO(dneto): OpGroupFAdd
76fd4e5da5Sopenharmony_ci// TODO(dneto): OpGroupFMin
77fd4e5da5Sopenharmony_ci// TODO(dneto): OpGroupUMin
78fd4e5da5Sopenharmony_ci// TODO(dneto): OpGroupSMin
79fd4e5da5Sopenharmony_ci// TODO(dneto): OpGroupFMax
80fd4e5da5Sopenharmony_ci// TODO(dneto): OpGroupUMax
81fd4e5da5Sopenharmony_ci// TODO(dneto): OpGroupSMax
82fd4e5da5Sopenharmony_ci
83fd4e5da5Sopenharmony_ciusing NamedMemoryBarrierTest = spvtest::TextToBinaryTest;
84fd4e5da5Sopenharmony_ci
85fd4e5da5Sopenharmony_ci// OpMemoryNamedBarrier is not in 1.0, but it is enabled by a capability.
86fd4e5da5Sopenharmony_ci// We should be able to assemble it.  Validation checks are in another test
87fd4e5da5Sopenharmony_ci// file.
88fd4e5da5Sopenharmony_ciTEST_F(NamedMemoryBarrierTest, OpcodeAssemblesInV10) {
89fd4e5da5Sopenharmony_ci  EXPECT_THAT(
90fd4e5da5Sopenharmony_ci      CompiledInstructions("OpMemoryNamedBarrier %bar %scope %semantics",
91fd4e5da5Sopenharmony_ci                           SPV_ENV_UNIVERSAL_1_0),
92fd4e5da5Sopenharmony_ci      ElementsAre(spvOpcodeMake(4, spv::Op::OpMemoryNamedBarrier), _, _, _));
93fd4e5da5Sopenharmony_ci}
94fd4e5da5Sopenharmony_ci
95fd4e5da5Sopenharmony_ciTEST_F(NamedMemoryBarrierTest, ArgumentCount) {
96fd4e5da5Sopenharmony_ci  EXPECT_THAT(CompileFailure("OpMemoryNamedBarrier", SPV_ENV_UNIVERSAL_1_1),
97fd4e5da5Sopenharmony_ci              Eq("Expected operand for OpMemoryNamedBarrier instruction, but "
98fd4e5da5Sopenharmony_ci                 "found the end of the stream."));
99fd4e5da5Sopenharmony_ci  EXPECT_THAT(
100fd4e5da5Sopenharmony_ci      CompileFailure("OpMemoryNamedBarrier %bar", SPV_ENV_UNIVERSAL_1_1),
101fd4e5da5Sopenharmony_ci      Eq("Expected operand for OpMemoryNamedBarrier instruction, but found the "
102fd4e5da5Sopenharmony_ci         "end of the stream."));
103fd4e5da5Sopenharmony_ci  EXPECT_THAT(
104fd4e5da5Sopenharmony_ci      CompileFailure("OpMemoryNamedBarrier %bar %scope", SPV_ENV_UNIVERSAL_1_1),
105fd4e5da5Sopenharmony_ci      Eq("Expected operand for OpMemoryNamedBarrier instruction, but found the "
106fd4e5da5Sopenharmony_ci         "end of the stream."));
107fd4e5da5Sopenharmony_ci  EXPECT_THAT(
108fd4e5da5Sopenharmony_ci      CompiledInstructions("OpMemoryNamedBarrier %bar %scope %semantics",
109fd4e5da5Sopenharmony_ci                           SPV_ENV_UNIVERSAL_1_1),
110fd4e5da5Sopenharmony_ci      ElementsAre(spvOpcodeMake(4, spv::Op::OpMemoryNamedBarrier), _, _, _));
111fd4e5da5Sopenharmony_ci  EXPECT_THAT(
112fd4e5da5Sopenharmony_ci      CompileFailure("OpMemoryNamedBarrier %bar %scope %semantics %extra",
113fd4e5da5Sopenharmony_ci                     SPV_ENV_UNIVERSAL_1_1),
114fd4e5da5Sopenharmony_ci      Eq("Expected '=', found end of stream."));
115fd4e5da5Sopenharmony_ci}
116fd4e5da5Sopenharmony_ci
117fd4e5da5Sopenharmony_ciTEST_F(NamedMemoryBarrierTest, ArgumentTypes) {
118fd4e5da5Sopenharmony_ci  EXPECT_THAT(CompileFailure("OpMemoryNamedBarrier 123 %scope %semantics",
119fd4e5da5Sopenharmony_ci                             SPV_ENV_UNIVERSAL_1_1),
120fd4e5da5Sopenharmony_ci              Eq("Expected id to start with %."));
121fd4e5da5Sopenharmony_ci  EXPECT_THAT(CompileFailure("OpMemoryNamedBarrier %bar %scope \"semantics\"",
122fd4e5da5Sopenharmony_ci                             SPV_ENV_UNIVERSAL_1_1),
123fd4e5da5Sopenharmony_ci              Eq("Expected id to start with %."));
124fd4e5da5Sopenharmony_ci}
125fd4e5da5Sopenharmony_ci
126fd4e5da5Sopenharmony_ciusing TypeNamedBarrierTest = spvtest::TextToBinaryTest;
127fd4e5da5Sopenharmony_ci
128fd4e5da5Sopenharmony_ciTEST_F(TypeNamedBarrierTest, OpcodeAssemblesInV10) {
129fd4e5da5Sopenharmony_ci  EXPECT_THAT(
130fd4e5da5Sopenharmony_ci      CompiledInstructions("%t = OpTypeNamedBarrier", SPV_ENV_UNIVERSAL_1_0),
131fd4e5da5Sopenharmony_ci      ElementsAre(spvOpcodeMake(2, spv::Op::OpTypeNamedBarrier), _));
132fd4e5da5Sopenharmony_ci}
133fd4e5da5Sopenharmony_ci
134fd4e5da5Sopenharmony_ciTEST_F(TypeNamedBarrierTest, ArgumentCount) {
135fd4e5da5Sopenharmony_ci  EXPECT_THAT(CompileFailure("OpTypeNamedBarrier", SPV_ENV_UNIVERSAL_1_1),
136fd4e5da5Sopenharmony_ci              Eq("Expected <result-id> at the beginning of an instruction, "
137fd4e5da5Sopenharmony_ci                 "found 'OpTypeNamedBarrier'."));
138fd4e5da5Sopenharmony_ci  EXPECT_THAT(
139fd4e5da5Sopenharmony_ci      CompiledInstructions("%t = OpTypeNamedBarrier", SPV_ENV_UNIVERSAL_1_1),
140fd4e5da5Sopenharmony_ci      ElementsAre(spvOpcodeMake(2, spv::Op::OpTypeNamedBarrier), _));
141fd4e5da5Sopenharmony_ci  EXPECT_THAT(
142fd4e5da5Sopenharmony_ci      CompileFailure("%t = OpTypeNamedBarrier 1 2 3", SPV_ENV_UNIVERSAL_1_1),
143fd4e5da5Sopenharmony_ci      Eq("Expected <opcode> or <result-id> at the beginning of an instruction, "
144fd4e5da5Sopenharmony_ci         "found '1'."));
145fd4e5da5Sopenharmony_ci}
146fd4e5da5Sopenharmony_ci
147fd4e5da5Sopenharmony_ciusing NamedBarrierInitializeTest = spvtest::TextToBinaryTest;
148fd4e5da5Sopenharmony_ci
149fd4e5da5Sopenharmony_ciTEST_F(NamedBarrierInitializeTest, OpcodeAssemblesInV10) {
150fd4e5da5Sopenharmony_ci  EXPECT_THAT(
151fd4e5da5Sopenharmony_ci      CompiledInstructions("%bar = OpNamedBarrierInitialize %type %count",
152fd4e5da5Sopenharmony_ci                           SPV_ENV_UNIVERSAL_1_0),
153fd4e5da5Sopenharmony_ci      ElementsAre(spvOpcodeMake(4, spv::Op::OpNamedBarrierInitialize), _, _,
154fd4e5da5Sopenharmony_ci                  _));
155fd4e5da5Sopenharmony_ci}
156fd4e5da5Sopenharmony_ci
157fd4e5da5Sopenharmony_ciTEST_F(NamedBarrierInitializeTest, ArgumentCount) {
158fd4e5da5Sopenharmony_ci  EXPECT_THAT(
159fd4e5da5Sopenharmony_ci      CompileFailure("%bar = OpNamedBarrierInitialize", SPV_ENV_UNIVERSAL_1_1),
160fd4e5da5Sopenharmony_ci      Eq("Expected operand for OpNamedBarrierInitialize instruction, but found "
161fd4e5da5Sopenharmony_ci         "the end of the stream."));
162fd4e5da5Sopenharmony_ci  EXPECT_THAT(CompileFailure("%bar = OpNamedBarrierInitialize %ype",
163fd4e5da5Sopenharmony_ci                             SPV_ENV_UNIVERSAL_1_1),
164fd4e5da5Sopenharmony_ci              Eq("Expected operand for OpNamedBarrierInitialize instruction, "
165fd4e5da5Sopenharmony_ci                 "but found the end of the stream."));
166fd4e5da5Sopenharmony_ci  EXPECT_THAT(
167fd4e5da5Sopenharmony_ci      CompiledInstructions("%bar = OpNamedBarrierInitialize %type %count",
168fd4e5da5Sopenharmony_ci                           SPV_ENV_UNIVERSAL_1_1),
169fd4e5da5Sopenharmony_ci      ElementsAre(spvOpcodeMake(4, spv::Op::OpNamedBarrierInitialize), _, _,
170fd4e5da5Sopenharmony_ci                  _));
171fd4e5da5Sopenharmony_ci  EXPECT_THAT(
172fd4e5da5Sopenharmony_ci      CompileFailure("%bar = OpNamedBarrierInitialize %type %count \"extra\"",
173fd4e5da5Sopenharmony_ci                     SPV_ENV_UNIVERSAL_1_1),
174fd4e5da5Sopenharmony_ci      Eq("Expected <opcode> or <result-id> at the beginning of an instruction, "
175fd4e5da5Sopenharmony_ci         "found '\"extra\"'."));
176fd4e5da5Sopenharmony_ci}
177fd4e5da5Sopenharmony_ci
178fd4e5da5Sopenharmony_ci}  // namespace
179fd4e5da5Sopenharmony_ci}  // namespace spvtools
180