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 "Group Instrucions" section of the 16fd4e5da5Sopenharmony_ci// SPIR-V spec. 17fd4e5da5Sopenharmony_ci 18fd4e5da5Sopenharmony_ci#include <cstdint> 19fd4e5da5Sopenharmony_ci#include <limits> 20fd4e5da5Sopenharmony_ci#include <string> 21fd4e5da5Sopenharmony_ci#include <vector> 22fd4e5da5Sopenharmony_ci 23fd4e5da5Sopenharmony_ci#include "gmock/gmock.h" 24fd4e5da5Sopenharmony_ci#include "test/test_fixture.h" 25fd4e5da5Sopenharmony_ci#include "test/unit_spirv.h" 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_cinamespace spvtools { 28fd4e5da5Sopenharmony_cinamespace { 29fd4e5da5Sopenharmony_ci 30fd4e5da5Sopenharmony_ciusing spvtest::Concatenate; 31fd4e5da5Sopenharmony_ciusing spvtest::EnumCase; 32fd4e5da5Sopenharmony_ciusing spvtest::MakeInstruction; 33fd4e5da5Sopenharmony_ciusing ::testing::Eq; 34fd4e5da5Sopenharmony_ci 35fd4e5da5Sopenharmony_ci// Test Sampler Addressing Mode enum values 36fd4e5da5Sopenharmony_ci 37fd4e5da5Sopenharmony_ciusing SamplerAddressingModeTest = spvtest::TextToBinaryTestBase< 38fd4e5da5Sopenharmony_ci ::testing::TestWithParam<EnumCase<spv::SamplerAddressingMode>>>; 39fd4e5da5Sopenharmony_ci 40fd4e5da5Sopenharmony_ciTEST_P(SamplerAddressingModeTest, AnySamplerAddressingMode) { 41fd4e5da5Sopenharmony_ci const std::string input = 42fd4e5da5Sopenharmony_ci "%result = OpConstantSampler %type " + GetParam().name() + " 0 Nearest"; 43fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(input), 44fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpConstantSampler, 45fd4e5da5Sopenharmony_ci {1, 2, uint32_t(GetParam().value()), 0, 0}))); 46fd4e5da5Sopenharmony_ci} 47fd4e5da5Sopenharmony_ci 48fd4e5da5Sopenharmony_ci// clang-format off 49fd4e5da5Sopenharmony_ci#define CASE(NAME) { spv::SamplerAddressingMode::NAME, #NAME } 50fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 51fd4e5da5Sopenharmony_ci TextToBinarySamplerAddressingMode, SamplerAddressingModeTest, 52fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<EnumCase<spv::SamplerAddressingMode>>{ 53fd4e5da5Sopenharmony_ci CASE(None), 54fd4e5da5Sopenharmony_ci CASE(ClampToEdge), 55fd4e5da5Sopenharmony_ci CASE(Clamp), 56fd4e5da5Sopenharmony_ci CASE(Repeat), 57fd4e5da5Sopenharmony_ci CASE(RepeatMirrored), 58fd4e5da5Sopenharmony_ci })); 59fd4e5da5Sopenharmony_ci#undef CASE 60fd4e5da5Sopenharmony_ci// clang-format on 61fd4e5da5Sopenharmony_ci 62fd4e5da5Sopenharmony_ciTEST_F(SamplerAddressingModeTest, WrongMode) { 63fd4e5da5Sopenharmony_ci EXPECT_THAT(CompileFailure("%r = OpConstantSampler %t xxyyzz 0 Nearest"), 64fd4e5da5Sopenharmony_ci Eq("Invalid sampler addressing mode 'xxyyzz'.")); 65fd4e5da5Sopenharmony_ci} 66fd4e5da5Sopenharmony_ci 67fd4e5da5Sopenharmony_ci// Test Sampler Filter Mode enum values 68fd4e5da5Sopenharmony_ci 69fd4e5da5Sopenharmony_ciusing SamplerFilterModeTest = spvtest::TextToBinaryTestBase< 70fd4e5da5Sopenharmony_ci ::testing::TestWithParam<EnumCase<spv::SamplerFilterMode>>>; 71fd4e5da5Sopenharmony_ci 72fd4e5da5Sopenharmony_ciTEST_P(SamplerFilterModeTest, AnySamplerFilterMode) { 73fd4e5da5Sopenharmony_ci const std::string input = 74fd4e5da5Sopenharmony_ci "%result = OpConstantSampler %type Clamp 0 " + GetParam().name(); 75fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(input), 76fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpConstantSampler, 77fd4e5da5Sopenharmony_ci {1, 2, 2, 0, uint32_t(GetParam().value())}))); 78fd4e5da5Sopenharmony_ci} 79fd4e5da5Sopenharmony_ci 80fd4e5da5Sopenharmony_ci// clang-format off 81fd4e5da5Sopenharmony_ci#define CASE(NAME) { spv::SamplerFilterMode::NAME, #NAME} 82fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 83fd4e5da5Sopenharmony_ci TextToBinarySamplerFilterMode, SamplerFilterModeTest, 84fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<EnumCase<spv::SamplerFilterMode>>{ 85fd4e5da5Sopenharmony_ci CASE(Nearest), 86fd4e5da5Sopenharmony_ci CASE(Linear), 87fd4e5da5Sopenharmony_ci })); 88fd4e5da5Sopenharmony_ci#undef CASE 89fd4e5da5Sopenharmony_ci// clang-format on 90fd4e5da5Sopenharmony_ci 91fd4e5da5Sopenharmony_ciTEST_F(SamplerFilterModeTest, WrongMode) { 92fd4e5da5Sopenharmony_ci EXPECT_THAT(CompileFailure("%r = OpConstantSampler %t Clamp 0 xxyyzz"), 93fd4e5da5Sopenharmony_ci Eq("Invalid sampler filter mode 'xxyyzz'.")); 94fd4e5da5Sopenharmony_ci} 95fd4e5da5Sopenharmony_ci 96fd4e5da5Sopenharmony_cistruct ConstantTestCase { 97fd4e5da5Sopenharmony_ci std::string constant_type; 98fd4e5da5Sopenharmony_ci std::string constant_value; 99fd4e5da5Sopenharmony_ci std::vector<uint32_t> expected_instructions; 100fd4e5da5Sopenharmony_ci}; 101fd4e5da5Sopenharmony_ci 102fd4e5da5Sopenharmony_ciusing OpConstantValidTest = 103fd4e5da5Sopenharmony_ci spvtest::TextToBinaryTestBase<::testing::TestWithParam<ConstantTestCase>>; 104fd4e5da5Sopenharmony_ci 105fd4e5da5Sopenharmony_ciTEST_P(OpConstantValidTest, ValidTypes) { 106fd4e5da5Sopenharmony_ci const std::string input = "%1 = " + GetParam().constant_type + 107fd4e5da5Sopenharmony_ci "\n" 108fd4e5da5Sopenharmony_ci "%2 = OpConstant %1 " + 109fd4e5da5Sopenharmony_ci GetParam().constant_value + "\n"; 110fd4e5da5Sopenharmony_ci std::vector<uint32_t> instructions; 111fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(input), Eq(GetParam().expected_instructions)) 112fd4e5da5Sopenharmony_ci << " type: " << GetParam().constant_type 113fd4e5da5Sopenharmony_ci << " literal: " << GetParam().constant_value; 114fd4e5da5Sopenharmony_ci} 115fd4e5da5Sopenharmony_ci 116fd4e5da5Sopenharmony_ci// clang-format off 117fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 118fd4e5da5Sopenharmony_ci TextToBinaryOpConstantValid, OpConstantValidTest, 119fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<ConstantTestCase>{ 120fd4e5da5Sopenharmony_ci // Check 16 bits 121fd4e5da5Sopenharmony_ci {"OpTypeInt 16 0", "0x1234", 122fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}), 123fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0x1234})})}, 124fd4e5da5Sopenharmony_ci {"OpTypeInt 16 0", "0x8000", 125fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}), 126fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0x8000})})}, 127fd4e5da5Sopenharmony_ci {"OpTypeInt 16 0", "0", 128fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}), 129fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})}, 130fd4e5da5Sopenharmony_ci {"OpTypeInt 16 0", "65535", 131fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}), 132fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 65535})})}, 133fd4e5da5Sopenharmony_ci {"OpTypeInt 16 0", "0xffff", 134fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}), 135fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 65535})})}, 136fd4e5da5Sopenharmony_ci {"OpTypeInt 16 1", "0x8000", // Test sign extension. 137fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), 138fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffff8000})})}, 139fd4e5da5Sopenharmony_ci {"OpTypeInt 16 1", "-32", 140fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), 141fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-32)})})}, 142fd4e5da5Sopenharmony_ci {"OpTypeInt 16 1", "0", 143fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), 144fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})}, 145fd4e5da5Sopenharmony_ci {"OpTypeInt 16 1", "-0", 146fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), 147fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})}, 148fd4e5da5Sopenharmony_ci {"OpTypeInt 16 1", "-0x0", 149fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), 150fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})}, 151fd4e5da5Sopenharmony_ci {"OpTypeInt 16 1", "-32768", 152fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), 153fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-32768)})})}, 154fd4e5da5Sopenharmony_ci // Check 32 bits 155fd4e5da5Sopenharmony_ci {"OpTypeInt 32 0", "42", 156fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 0}), 157fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 42})})}, 158fd4e5da5Sopenharmony_ci {"OpTypeInt 32 1", "-32", 159fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), 160fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-32)})})}, 161fd4e5da5Sopenharmony_ci {"OpTypeInt 32 1", "0", 162fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), 163fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})}, 164fd4e5da5Sopenharmony_ci {"OpTypeInt 32 1", "-0", 165fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), 166fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})}, 167fd4e5da5Sopenharmony_ci {"OpTypeInt 32 1", "-0x0", 168fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), 169fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0})})}, 170fd4e5da5Sopenharmony_ci {"OpTypeInt 32 1", "-0x001", 171fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), 172fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-1)})})}, 173fd4e5da5Sopenharmony_ci {"OpTypeInt 32 1", "2147483647", 174fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), 175fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0x7fffffffu})})}, 176fd4e5da5Sopenharmony_ci {"OpTypeInt 32 1", "-2147483648", 177fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), 178fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0x80000000u})})}, 179fd4e5da5Sopenharmony_ci {"OpTypeFloat 32", "1.0", 180fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), 181fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0x3f800000})})}, 182fd4e5da5Sopenharmony_ci {"OpTypeFloat 32", "10.0", 183fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), 184fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0x41200000})})}, 185fd4e5da5Sopenharmony_ci {"OpTypeFloat 32", "-0x1p+128", // -infinity 186fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), 187fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0xFF800000})})}, 188fd4e5da5Sopenharmony_ci {"OpTypeFloat 32", "0x1p+128", // +infinity 189fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), 190fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0x7F800000})})}, 191fd4e5da5Sopenharmony_ci {"OpTypeFloat 32", "-0x1.8p+128", // A -NaN 192fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), 193fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0xFFC00000})})}, 194fd4e5da5Sopenharmony_ci {"OpTypeFloat 32", "-0x1.0002p+128", // A +NaN 195fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), 196fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0xFF800100})})}, 197fd4e5da5Sopenharmony_ci // Check 48 bits 198fd4e5da5Sopenharmony_ci {"OpTypeInt 48 0", "0x1234", 199fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 0}), 200fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0x1234, 0})})}, 201fd4e5da5Sopenharmony_ci {"OpTypeInt 48 0", "0x800000000001", 202fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 0}), 203fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 1, 0x00008000})})}, 204fd4e5da5Sopenharmony_ci {"OpTypeInt 48 1", "0x800000000000", // Test sign extension. 205fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 1}), 206fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0, 0xffff8000})})}, 207fd4e5da5Sopenharmony_ci {"OpTypeInt 48 1", "-32", 208fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 1}), 209fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-32), uint32_t(-1)})})}, 210fd4e5da5Sopenharmony_ci // Check 64 bits 211fd4e5da5Sopenharmony_ci {"OpTypeInt 64 0", "0x1234", 212fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0}), 213fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0x1234, 0})})}, 214fd4e5da5Sopenharmony_ci {"OpTypeInt 64 0", "18446744073709551615", 215fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0}), 216fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffffffffu, 0xffffffffu})})}, 217fd4e5da5Sopenharmony_ci {"OpTypeInt 64 0", "0xffffffffffffffff", 218fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0}), 219fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffffffffu, 0xffffffffu})})}, 220fd4e5da5Sopenharmony_ci {"OpTypeInt 64 1", "0x1234", 221fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}), 222fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0x1234, 0})})}, 223fd4e5da5Sopenharmony_ci {"OpTypeInt 64 1", "-42", 224fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}), 225fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, uint32_t(-42), uint32_t(-1)})})}, 226fd4e5da5Sopenharmony_ci {"OpTypeInt 64 1", "-0x01", 227fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}), 228fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffffffffu, 0xffffffffu})})}, 229fd4e5da5Sopenharmony_ci {"OpTypeInt 64 1", "9223372036854775807", 230fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}), 231fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0xffffffffu, 0x7fffffffu})})}, 232fd4e5da5Sopenharmony_ci {"OpTypeInt 64 1", "0x7fffffff", 233fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}), 234fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpConstant, {1, 2, 0x7fffffffu, 0})})}, 235fd4e5da5Sopenharmony_ci })); 236fd4e5da5Sopenharmony_ci// clang-format on 237fd4e5da5Sopenharmony_ci 238fd4e5da5Sopenharmony_ci// A test case for checking OpConstant with invalid literals with a leading 239fd4e5da5Sopenharmony_ci// minus. 240fd4e5da5Sopenharmony_cistruct InvalidLeadingMinusCase { 241fd4e5da5Sopenharmony_ci std::string type; 242fd4e5da5Sopenharmony_ci std::string literal; 243fd4e5da5Sopenharmony_ci}; 244fd4e5da5Sopenharmony_ci 245fd4e5da5Sopenharmony_ciusing OpConstantInvalidLeadingMinusTest = spvtest::TextToBinaryTestBase< 246fd4e5da5Sopenharmony_ci ::testing::TestWithParam<InvalidLeadingMinusCase>>; 247fd4e5da5Sopenharmony_ci 248fd4e5da5Sopenharmony_ciTEST_P(OpConstantInvalidLeadingMinusTest, InvalidCase) { 249fd4e5da5Sopenharmony_ci const std::string input = "%1 = " + GetParam().type + 250fd4e5da5Sopenharmony_ci "\n" 251fd4e5da5Sopenharmony_ci "%2 = OpConstant %1 " + 252fd4e5da5Sopenharmony_ci GetParam().literal; 253fd4e5da5Sopenharmony_ci EXPECT_THAT(CompileFailure(input), 254fd4e5da5Sopenharmony_ci Eq("Cannot put a negative number in an unsigned literal")); 255fd4e5da5Sopenharmony_ci} 256fd4e5da5Sopenharmony_ci 257fd4e5da5Sopenharmony_ci// clang-format off 258fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 259fd4e5da5Sopenharmony_ci TextToBinaryOpConstantInvalidLeadingMinus, OpConstantInvalidLeadingMinusTest, 260fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<InvalidLeadingMinusCase>{ 261fd4e5da5Sopenharmony_ci {"OpTypeInt 16 0", "-0"}, 262fd4e5da5Sopenharmony_ci {"OpTypeInt 16 0", "-0x0"}, 263fd4e5da5Sopenharmony_ci {"OpTypeInt 16 0", "-1"}, 264fd4e5da5Sopenharmony_ci {"OpTypeInt 32 0", "-0"}, 265fd4e5da5Sopenharmony_ci {"OpTypeInt 32 0", "-0x0"}, 266fd4e5da5Sopenharmony_ci {"OpTypeInt 32 0", "-1"}, 267fd4e5da5Sopenharmony_ci {"OpTypeInt 64 0", "-0"}, 268fd4e5da5Sopenharmony_ci {"OpTypeInt 64 0", "-0x0"}, 269fd4e5da5Sopenharmony_ci {"OpTypeInt 64 0", "-1"}, 270fd4e5da5Sopenharmony_ci })); 271fd4e5da5Sopenharmony_ci// clang-format on 272fd4e5da5Sopenharmony_ci 273fd4e5da5Sopenharmony_ci// A test case for invalid floating point literals. 274fd4e5da5Sopenharmony_cistruct InvalidFloatConstantCase { 275fd4e5da5Sopenharmony_ci uint32_t width; 276fd4e5da5Sopenharmony_ci std::string literal; 277fd4e5da5Sopenharmony_ci}; 278fd4e5da5Sopenharmony_ci 279fd4e5da5Sopenharmony_ciusing OpConstantInvalidFloatConstant = spvtest::TextToBinaryTestBase< 280fd4e5da5Sopenharmony_ci ::testing::TestWithParam<InvalidFloatConstantCase>>; 281fd4e5da5Sopenharmony_ci 282fd4e5da5Sopenharmony_ciTEST_P(OpConstantInvalidFloatConstant, Samples) { 283fd4e5da5Sopenharmony_ci // Check both kinds of instructions that take literal floats. 284fd4e5da5Sopenharmony_ci for (const auto& instruction : {"OpConstant", "OpSpecConstant"}) { 285fd4e5da5Sopenharmony_ci std::stringstream input; 286fd4e5da5Sopenharmony_ci input << "%1 = OpTypeFloat " << GetParam().width << "\n" 287fd4e5da5Sopenharmony_ci << "%2 = " << instruction << " %1 " << GetParam().literal; 288fd4e5da5Sopenharmony_ci std::stringstream expected_error; 289fd4e5da5Sopenharmony_ci expected_error << "Invalid " << GetParam().width 290fd4e5da5Sopenharmony_ci << "-bit float literal: " << GetParam().literal; 291fd4e5da5Sopenharmony_ci EXPECT_THAT(CompileFailure(input.str()), Eq(expected_error.str())); 292fd4e5da5Sopenharmony_ci } 293fd4e5da5Sopenharmony_ci} 294fd4e5da5Sopenharmony_ci 295fd4e5da5Sopenharmony_ci// clang-format off 296fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 297fd4e5da5Sopenharmony_ci TextToBinaryInvalidFloatConstant, OpConstantInvalidFloatConstant, 298fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<InvalidFloatConstantCase>{ 299fd4e5da5Sopenharmony_ci {16, "abc"}, 300fd4e5da5Sopenharmony_ci {16, "--1"}, 301fd4e5da5Sopenharmony_ci {16, "-+1"}, 302fd4e5da5Sopenharmony_ci {16, "+-1"}, 303fd4e5da5Sopenharmony_ci {16, "++1"}, 304fd4e5da5Sopenharmony_ci {16, "1e30"}, // Overflow is an error for 16-bit floats. 305fd4e5da5Sopenharmony_ci {16, "-1e30"}, 306fd4e5da5Sopenharmony_ci {16, "1e40"}, 307fd4e5da5Sopenharmony_ci {16, "-1e40"}, 308fd4e5da5Sopenharmony_ci {16, "1e400"}, 309fd4e5da5Sopenharmony_ci {16, "-1e400"}, 310fd4e5da5Sopenharmony_ci {32, "abc"}, 311fd4e5da5Sopenharmony_ci {32, "--1"}, 312fd4e5da5Sopenharmony_ci {32, "-+1"}, 313fd4e5da5Sopenharmony_ci {32, "+-1"}, 314fd4e5da5Sopenharmony_ci {32, "++1"}, 315fd4e5da5Sopenharmony_ci {32, "1e40"}, // Overflow is an error for 32-bit floats. 316fd4e5da5Sopenharmony_ci {32, "-1e40"}, 317fd4e5da5Sopenharmony_ci {32, "1e400"}, 318fd4e5da5Sopenharmony_ci {32, "-1e400"}, 319fd4e5da5Sopenharmony_ci {64, "abc"}, 320fd4e5da5Sopenharmony_ci {64, "--1"}, 321fd4e5da5Sopenharmony_ci {64, "-+1"}, 322fd4e5da5Sopenharmony_ci {64, "+-1"}, 323fd4e5da5Sopenharmony_ci {64, "++1"}, 324fd4e5da5Sopenharmony_ci {32, "1e400"}, // Overflow is an error for 64-bit floats. 325fd4e5da5Sopenharmony_ci {32, "-1e400"}, 326fd4e5da5Sopenharmony_ci })); 327fd4e5da5Sopenharmony_ci// clang-format on 328fd4e5da5Sopenharmony_ci 329fd4e5da5Sopenharmony_ciusing OpConstantInvalidTypeTest = 330fd4e5da5Sopenharmony_ci spvtest::TextToBinaryTestBase<::testing::TestWithParam<std::string>>; 331fd4e5da5Sopenharmony_ciTEST_P(OpConstantInvalidTypeTest, InvalidTypes) { 332fd4e5da5Sopenharmony_ci const std::string input = "%1 = " + GetParam() + 333fd4e5da5Sopenharmony_ci "\n" 334fd4e5da5Sopenharmony_ci "%2 = OpConstant %1 0\n"; 335fd4e5da5Sopenharmony_ci EXPECT_THAT( 336fd4e5da5Sopenharmony_ci CompileFailure(input), 337fd4e5da5Sopenharmony_ci Eq("Type for Constant must be a scalar floating point or integer type")); 338fd4e5da5Sopenharmony_ci} 339fd4e5da5Sopenharmony_ci 340fd4e5da5Sopenharmony_ci// clang-format off 341fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 342fd4e5da5Sopenharmony_ci TextToBinaryOpConstantInvalidValidType, OpConstantInvalidTypeTest, 343fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<std::string>{ 344fd4e5da5Sopenharmony_ci {"OpTypeVoid", 345fd4e5da5Sopenharmony_ci "OpTypeBool", 346fd4e5da5Sopenharmony_ci "OpTypeVector %a 32", 347fd4e5da5Sopenharmony_ci "OpTypeMatrix %a 32", 348fd4e5da5Sopenharmony_ci "OpTypeImage %a 1D 0 0 0 0 Unknown", 349fd4e5da5Sopenharmony_ci "OpTypeSampler", 350fd4e5da5Sopenharmony_ci "OpTypeSampledImage %a", 351fd4e5da5Sopenharmony_ci "OpTypeArray %a %b", 352fd4e5da5Sopenharmony_ci "OpTypeRuntimeArray %a", 353fd4e5da5Sopenharmony_ci "OpTypeStruct %a", 354fd4e5da5Sopenharmony_ci "OpTypeOpaque \"Foo\"", 355fd4e5da5Sopenharmony_ci "OpTypePointer UniformConstant %a", 356fd4e5da5Sopenharmony_ci "OpTypeFunction %a %b", 357fd4e5da5Sopenharmony_ci "OpTypeEvent", 358fd4e5da5Sopenharmony_ci "OpTypeDeviceEvent", 359fd4e5da5Sopenharmony_ci "OpTypeReserveId", 360fd4e5da5Sopenharmony_ci "OpTypeQueue", 361fd4e5da5Sopenharmony_ci "OpTypePipe ReadOnly", 362fd4e5da5Sopenharmony_ci 363fd4e5da5Sopenharmony_ci // Skip OpTypeForwardPointer doesn't even produce a result ID. 364fd4e5da5Sopenharmony_ci // The assembler errors out if we try to check it in this scenario. 365fd4e5da5Sopenharmony_ci 366fd4e5da5Sopenharmony_ci // Try at least one thing that isn't a type at all 367fd4e5da5Sopenharmony_ci "OpNot %a %b" 368fd4e5da5Sopenharmony_ci }, 369fd4e5da5Sopenharmony_ci })); 370fd4e5da5Sopenharmony_ci// clang-format on 371fd4e5da5Sopenharmony_ci 372fd4e5da5Sopenharmony_ciusing OpSpecConstantValidTest = 373fd4e5da5Sopenharmony_ci spvtest::TextToBinaryTestBase<::testing::TestWithParam<ConstantTestCase>>; 374fd4e5da5Sopenharmony_ci 375fd4e5da5Sopenharmony_ciTEST_P(OpSpecConstantValidTest, ValidTypes) { 376fd4e5da5Sopenharmony_ci const std::string input = "%1 = " + GetParam().constant_type + 377fd4e5da5Sopenharmony_ci "\n" 378fd4e5da5Sopenharmony_ci "%2 = OpSpecConstant %1 " + 379fd4e5da5Sopenharmony_ci GetParam().constant_value + "\n"; 380fd4e5da5Sopenharmony_ci std::vector<uint32_t> instructions; 381fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(input), 382fd4e5da5Sopenharmony_ci Eq(GetParam().expected_instructions)); 383fd4e5da5Sopenharmony_ci} 384fd4e5da5Sopenharmony_ci 385fd4e5da5Sopenharmony_ci// clang-format off 386fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 387fd4e5da5Sopenharmony_ci TextToBinaryOpSpecConstantValid, OpSpecConstantValidTest, 388fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<ConstantTestCase>{ 389fd4e5da5Sopenharmony_ci // Check 16 bits 390fd4e5da5Sopenharmony_ci {"OpTypeInt 16 0", "0x1234", 391fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}), 392fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x1234})})}, 393fd4e5da5Sopenharmony_ci {"OpTypeInt 16 0", "0x8000", 394fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 0}), 395fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x8000})})}, 396fd4e5da5Sopenharmony_ci {"OpTypeInt 16 1", "0x8000", // Test sign extension. 397fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), 398fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0xffff8000})})}, 399fd4e5da5Sopenharmony_ci {"OpTypeInt 16 1", "-32", 400fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 16, 1}), 401fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, uint32_t(-32)})})}, 402fd4e5da5Sopenharmony_ci // Check 32 bits 403fd4e5da5Sopenharmony_ci {"OpTypeInt 32 0", "42", 404fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 0}), 405fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 42})})}, 406fd4e5da5Sopenharmony_ci {"OpTypeInt 32 1", "-32", 407fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 32, 1}), 408fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, uint32_t(-32)})})}, 409fd4e5da5Sopenharmony_ci {"OpTypeFloat 32", "1.0", 410fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), 411fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x3f800000})})}, 412fd4e5da5Sopenharmony_ci {"OpTypeFloat 32", "10.0", 413fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeFloat, {1, 32}), 414fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x41200000})})}, 415fd4e5da5Sopenharmony_ci // Check 48 bits 416fd4e5da5Sopenharmony_ci {"OpTypeInt 48 0", "0x1234", 417fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 0}), 418fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x1234, 0})})}, 419fd4e5da5Sopenharmony_ci {"OpTypeInt 48 0", "0x800000000001", 420fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 0}), 421fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 1, 0x00008000})})}, 422fd4e5da5Sopenharmony_ci {"OpTypeInt 48 1", "0x800000000000", // Test sign extension. 423fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 1}), 424fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0, 0xffff8000})})}, 425fd4e5da5Sopenharmony_ci {"OpTypeInt 48 1", "-32", 426fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 48, 1}), 427fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, uint32_t(-32), uint32_t(-1)})})}, 428fd4e5da5Sopenharmony_ci // Check 64 bits 429fd4e5da5Sopenharmony_ci {"OpTypeInt 64 0", "0x1234", 430fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 0}), 431fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x1234, 0})})}, 432fd4e5da5Sopenharmony_ci {"OpTypeInt 64 1", "0x1234", 433fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}), 434fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, 0x1234, 0})})}, 435fd4e5da5Sopenharmony_ci {"OpTypeInt 64 1", "-42", 436fd4e5da5Sopenharmony_ci Concatenate({MakeInstruction(spv::Op::OpTypeInt, {1, 64, 1}), 437fd4e5da5Sopenharmony_ci MakeInstruction(spv::Op::OpSpecConstant, {1, 2, uint32_t(-42), uint32_t(-1)})})}, 438fd4e5da5Sopenharmony_ci })); 439fd4e5da5Sopenharmony_ci// clang-format on 440fd4e5da5Sopenharmony_ci 441fd4e5da5Sopenharmony_ciusing OpSpecConstantInvalidTypeTest = 442fd4e5da5Sopenharmony_ci spvtest::TextToBinaryTestBase<::testing::TestWithParam<std::string>>; 443fd4e5da5Sopenharmony_ci 444fd4e5da5Sopenharmony_ciTEST_P(OpSpecConstantInvalidTypeTest, InvalidTypes) { 445fd4e5da5Sopenharmony_ci const std::string input = "%1 = " + GetParam() + 446fd4e5da5Sopenharmony_ci "\n" 447fd4e5da5Sopenharmony_ci "%2 = OpSpecConstant %1 0\n"; 448fd4e5da5Sopenharmony_ci EXPECT_THAT(CompileFailure(input), 449fd4e5da5Sopenharmony_ci Eq("Type for SpecConstant must be a scalar floating point or " 450fd4e5da5Sopenharmony_ci "integer type")); 451fd4e5da5Sopenharmony_ci} 452fd4e5da5Sopenharmony_ci 453fd4e5da5Sopenharmony_ci// clang-format off 454fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 455fd4e5da5Sopenharmony_ci TextToBinaryOpSpecConstantInvalidValidType, OpSpecConstantInvalidTypeTest, 456fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<std::string>{ 457fd4e5da5Sopenharmony_ci {"OpTypeVoid", 458fd4e5da5Sopenharmony_ci "OpTypeBool", 459fd4e5da5Sopenharmony_ci "OpTypeVector %a 32", 460fd4e5da5Sopenharmony_ci "OpTypeMatrix %a 32", 461fd4e5da5Sopenharmony_ci "OpTypeImage %a 1D 0 0 0 0 Unknown", 462fd4e5da5Sopenharmony_ci "OpTypeSampler", 463fd4e5da5Sopenharmony_ci "OpTypeSampledImage %a", 464fd4e5da5Sopenharmony_ci "OpTypeArray %a %b", 465fd4e5da5Sopenharmony_ci "OpTypeRuntimeArray %a", 466fd4e5da5Sopenharmony_ci "OpTypeStruct %a", 467fd4e5da5Sopenharmony_ci "OpTypeOpaque \"Foo\"", 468fd4e5da5Sopenharmony_ci "OpTypePointer UniformConstant %a", 469fd4e5da5Sopenharmony_ci "OpTypeFunction %a %b", 470fd4e5da5Sopenharmony_ci "OpTypeEvent", 471fd4e5da5Sopenharmony_ci "OpTypeDeviceEvent", 472fd4e5da5Sopenharmony_ci "OpTypeReserveId", 473fd4e5da5Sopenharmony_ci "OpTypeQueue", 474fd4e5da5Sopenharmony_ci "OpTypePipe ReadOnly", 475fd4e5da5Sopenharmony_ci 476fd4e5da5Sopenharmony_ci // Skip testing OpTypeForwardPointer because it doesn't even produce a result ID. 477fd4e5da5Sopenharmony_ci 478fd4e5da5Sopenharmony_ci // Try at least one thing that isn't a type at all 479fd4e5da5Sopenharmony_ci "OpNot %a %b" 480fd4e5da5Sopenharmony_ci }, 481fd4e5da5Sopenharmony_ci })); 482fd4e5da5Sopenharmony_ci// clang-format on 483fd4e5da5Sopenharmony_ci 484fd4e5da5Sopenharmony_ciconst int64_t kMaxUnsigned48Bit = (int64_t(1) << 48) - 1; 485fd4e5da5Sopenharmony_ciconst int64_t kMaxSigned48Bit = (int64_t(1) << 47) - 1; 486fd4e5da5Sopenharmony_ciconst int64_t kMinSigned48Bit = -kMaxSigned48Bit - 1; 487fd4e5da5Sopenharmony_ci 488fd4e5da5Sopenharmony_ciusing ConstantRoundTripTest = RoundTripTest; 489fd4e5da5Sopenharmony_ci 490fd4e5da5Sopenharmony_ciTEST_P(ConstantRoundTripTest, DisassemblyEqualsAssemblyInput) { 491fd4e5da5Sopenharmony_ci const std::string assembly = GetParam(); 492fd4e5da5Sopenharmony_ci EXPECT_THAT(EncodeAndDecodeSuccessfully(assembly), Eq(assembly)) << assembly; 493fd4e5da5Sopenharmony_ci} 494fd4e5da5Sopenharmony_ci 495fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 496fd4e5da5Sopenharmony_ci OpConstantRoundTrip, ConstantRoundTripTest, 497fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<std::string>{ 498fd4e5da5Sopenharmony_ci // 16 bit 499fd4e5da5Sopenharmony_ci "%1 = OpTypeInt 16 0\n%2 = OpConstant %1 0\n", 500fd4e5da5Sopenharmony_ci "%1 = OpTypeInt 16 0\n%2 = OpConstant %1 65535\n", 501fd4e5da5Sopenharmony_ci "%1 = OpTypeInt 16 1\n%2 = OpConstant %1 -32768\n", 502fd4e5da5Sopenharmony_ci "%1 = OpTypeInt 16 1\n%2 = OpConstant %1 32767\n", 503fd4e5da5Sopenharmony_ci "%1 = OpTypeInt 32 0\n%2 = OpConstant %1 0\n", 504fd4e5da5Sopenharmony_ci // 32 bit 505fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 32 0\n%2 = OpConstant %1 0\n"), 506fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 32 0\n%2 = OpConstant %1 ") + 507fd4e5da5Sopenharmony_ci std::to_string(std::numeric_limits<uint32_t>::max()) + "\n", 508fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 32 1\n%2 = OpConstant %1 ") + 509fd4e5da5Sopenharmony_ci std::to_string(std::numeric_limits<int32_t>::max()) + "\n", 510fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 32 1\n%2 = OpConstant %1 ") + 511fd4e5da5Sopenharmony_ci std::to_string(std::numeric_limits<int32_t>::min()) + "\n", 512fd4e5da5Sopenharmony_ci // 48 bit 513fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 48 0\n%2 = OpConstant %1 0\n"), 514fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 48 0\n%2 = OpConstant %1 ") + 515fd4e5da5Sopenharmony_ci std::to_string(kMaxUnsigned48Bit) + "\n", 516fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 48 1\n%2 = OpConstant %1 ") + 517fd4e5da5Sopenharmony_ci std::to_string(kMaxSigned48Bit) + "\n", 518fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 48 1\n%2 = OpConstant %1 ") + 519fd4e5da5Sopenharmony_ci std::to_string(kMinSigned48Bit) + "\n", 520fd4e5da5Sopenharmony_ci // 64 bit 521fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 64 0\n%2 = OpConstant %1 0\n"), 522fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 64 0\n%2 = OpConstant %1 ") + 523fd4e5da5Sopenharmony_ci std::to_string(std::numeric_limits<uint64_t>::max()) + "\n", 524fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 64 1\n%2 = OpConstant %1 ") + 525fd4e5da5Sopenharmony_ci std::to_string(std::numeric_limits<int64_t>::max()) + "\n", 526fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 64 1\n%2 = OpConstant %1 ") + 527fd4e5da5Sopenharmony_ci std::to_string(std::numeric_limits<int64_t>::min()) + "\n", 528fd4e5da5Sopenharmony_ci // 32-bit float 529fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 0\n", 530fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 13.5\n", 531fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 -12.5\n", 532fd4e5da5Sopenharmony_ci // 64-bit float 533fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 0\n", 534fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 1.79767e+308\n", 535fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 -1.79767e+308\n", 536fd4e5da5Sopenharmony_ci })); 537fd4e5da5Sopenharmony_ci 538fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 539fd4e5da5Sopenharmony_ci OpConstantHalfRoundTrip, ConstantRoundTripTest, 540fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<std::string>{ 541fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x0p+0\n", 542fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x0p+0\n", 543fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1p+0\n", 544fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.1p+0\n", 545fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.01p-1\n", 546fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.8p+1\n", 547fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.ffcp+1\n", 548fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1p+0\n", 549fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.1p+0\n", 550fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.01p-1\n", 551fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.8p+1\n", 552fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.ffcp+1\n", 553fd4e5da5Sopenharmony_ci 554fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1p-16\n", // some denorms 555fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1p-24\n", 556fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1p-24\n", 557fd4e5da5Sopenharmony_ci 558fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1p+16\n", // +inf 559fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1p+16\n", // -inf 560fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.01p+16\n", // -inf 561fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.01p+16\n", // nan 562fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.11p+16\n", // nan 563fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.ffp+16\n", // nan 564fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.ffcp+16\n", // nan 565fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 0x1.004p+16\n", // nan 566fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.01p+16\n", // -nan 567fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.11p+16\n", // -nan 568fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.ffp+16\n", // -nan 569fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.ffcp+16\n", // -nan 570fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 16\n%2 = OpConstant %1 -0x1.004p+16\n", // -nan 571fd4e5da5Sopenharmony_ci })); 572fd4e5da5Sopenharmony_ci 573fd4e5da5Sopenharmony_ci// clang-format off 574fd4e5da5Sopenharmony_ci// (Clang-format really wants to break up these strings across lines. 575fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 576fd4e5da5Sopenharmony_ci OpConstantRoundTripNonFinite, ConstantRoundTripTest, 577fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<std::string>{ 578fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 -0x1p+128\n", // -inf 579fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 0x1p+128\n", // inf 580fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 -0x1.8p+128\n", // -nan 581fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 -0x1.0002p+128\n", // -nan 582fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 -0x1.0018p+128\n", // -nan 583fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 -0x1.01ep+128\n", // -nan 584fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 -0x1.fffffep+128\n", // -nan 585fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 0x1.8p+128\n", // +nan 586fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 0x1.0002p+128\n", // +nan 587fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 0x1.0018p+128\n", // +nan 588fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 0x1.01ep+128\n", // +nan 589fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpConstant %1 0x1.fffffep+128\n", // +nan 590fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 -0x1p+1024\n", // -inf 591fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 0x1p+1024\n", // +inf 592fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 -0x1.8p+1024\n", // -nan 593fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 -0x1.0fp+1024\n", // -nan 594fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 -0x1.0000000000001p+1024\n", // -nan 595fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 -0x1.00003p+1024\n", // -nan 596fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 -0x1.fffffffffffffp+1024\n", // -nan 597fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 0x1.8p+1024\n", // +nan 598fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 0x1.0fp+1024\n", // +nan 599fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 0x1.0000000000001p+1024\n", // -nan 600fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 0x1.00003p+1024\n", // -nan 601fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpConstant %1 0x1.fffffffffffffp+1024\n", // -nan 602fd4e5da5Sopenharmony_ci })); 603fd4e5da5Sopenharmony_ci// clang-format on 604fd4e5da5Sopenharmony_ci 605fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 606fd4e5da5Sopenharmony_ci OpSpecConstantRoundTrip, ConstantRoundTripTest, 607fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<std::string>{ 608fd4e5da5Sopenharmony_ci // 16 bit 609fd4e5da5Sopenharmony_ci "%1 = OpTypeInt 16 0\n%2 = OpSpecConstant %1 0\n", 610fd4e5da5Sopenharmony_ci "%1 = OpTypeInt 16 0\n%2 = OpSpecConstant %1 65535\n", 611fd4e5da5Sopenharmony_ci "%1 = OpTypeInt 16 1\n%2 = OpSpecConstant %1 -32768\n", 612fd4e5da5Sopenharmony_ci "%1 = OpTypeInt 16 1\n%2 = OpSpecConstant %1 32767\n", 613fd4e5da5Sopenharmony_ci "%1 = OpTypeInt 32 0\n%2 = OpSpecConstant %1 0\n", 614fd4e5da5Sopenharmony_ci // 32 bit 615fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 32 0\n%2 = OpSpecConstant %1 0\n"), 616fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 32 0\n%2 = OpSpecConstant %1 ") + 617fd4e5da5Sopenharmony_ci std::to_string(std::numeric_limits<uint32_t>::max()) + "\n", 618fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 32 1\n%2 = OpSpecConstant %1 ") + 619fd4e5da5Sopenharmony_ci std::to_string(std::numeric_limits<int32_t>::max()) + "\n", 620fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 32 1\n%2 = OpSpecConstant %1 ") + 621fd4e5da5Sopenharmony_ci std::to_string(std::numeric_limits<int32_t>::min()) + "\n", 622fd4e5da5Sopenharmony_ci // 48 bit 623fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 48 0\n%2 = OpSpecConstant %1 0\n"), 624fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 48 0\n%2 = OpSpecConstant %1 ") + 625fd4e5da5Sopenharmony_ci std::to_string(kMaxUnsigned48Bit) + "\n", 626fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 48 1\n%2 = OpSpecConstant %1 ") + 627fd4e5da5Sopenharmony_ci std::to_string(kMaxSigned48Bit) + "\n", 628fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 48 1\n%2 = OpSpecConstant %1 ") + 629fd4e5da5Sopenharmony_ci std::to_string(kMinSigned48Bit) + "\n", 630fd4e5da5Sopenharmony_ci // 64 bit 631fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 64 0\n%2 = OpSpecConstant %1 0\n"), 632fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 64 0\n%2 = OpSpecConstant %1 ") + 633fd4e5da5Sopenharmony_ci std::to_string(std::numeric_limits<uint64_t>::max()) + "\n", 634fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 64 1\n%2 = OpSpecConstant %1 ") + 635fd4e5da5Sopenharmony_ci std::to_string(std::numeric_limits<int64_t>::max()) + "\n", 636fd4e5da5Sopenharmony_ci std::string("%1 = OpTypeInt 64 1\n%2 = OpSpecConstant %1 ") + 637fd4e5da5Sopenharmony_ci std::to_string(std::numeric_limits<int64_t>::min()) + "\n", 638fd4e5da5Sopenharmony_ci // 32-bit float 639fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpSpecConstant %1 0\n", 640fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpSpecConstant %1 13.5\n", 641fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 32\n%2 = OpSpecConstant %1 -12.5\n", 642fd4e5da5Sopenharmony_ci // 64-bit float 643fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpSpecConstant %1 0\n", 644fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpSpecConstant %1 1.79767e+308\n", 645fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpSpecConstant %1 -1.79767e+308\n", 646fd4e5da5Sopenharmony_ci })); 647fd4e5da5Sopenharmony_ci 648fd4e5da5Sopenharmony_ci// Test OpSpecConstantOp 649fd4e5da5Sopenharmony_ci 650fd4e5da5Sopenharmony_ciusing OpSpecConstantOpTestWithIds = 651fd4e5da5Sopenharmony_ci spvtest::TextToBinaryTestBase<::testing::TestWithParam<EnumCase<spv::Op>>>; 652fd4e5da5Sopenharmony_ci 653fd4e5da5Sopenharmony_ci// The operands to the OpSpecConstantOp opcode are all Ids. 654fd4e5da5Sopenharmony_ciTEST_P(OpSpecConstantOpTestWithIds, Assembly) { 655fd4e5da5Sopenharmony_ci std::stringstream input; 656fd4e5da5Sopenharmony_ci input << "%2 = OpSpecConstantOp %1 " << GetParam().name(); 657fd4e5da5Sopenharmony_ci for (auto id : GetParam().operands()) input << " %" << id; 658fd4e5da5Sopenharmony_ci input << "\n"; 659fd4e5da5Sopenharmony_ci 660fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(input.str()), 661fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpSpecConstantOp, 662fd4e5da5Sopenharmony_ci {1, 2, uint32_t(GetParam().value())}, 663fd4e5da5Sopenharmony_ci GetParam().operands()))); 664fd4e5da5Sopenharmony_ci 665fd4e5da5Sopenharmony_ci // Check the disassembler as well. 666fd4e5da5Sopenharmony_ci EXPECT_THAT(EncodeAndDecodeSuccessfully(input.str()), input.str()); 667fd4e5da5Sopenharmony_ci} 668fd4e5da5Sopenharmony_ci 669fd4e5da5Sopenharmony_ci// clang-format off 670fd4e5da5Sopenharmony_ci#define CASE1(NAME) { spv::Op::Op##NAME, #NAME, {3} } 671fd4e5da5Sopenharmony_ci#define CASE2(NAME) { spv::Op::Op##NAME, #NAME, {3, 4} } 672fd4e5da5Sopenharmony_ci#define CASE3(NAME) { spv::Op::Op##NAME, #NAME, {3, 4, 5} } 673fd4e5da5Sopenharmony_ci#define CASE4(NAME) { spv::Op::Op##NAME, #NAME, {3, 4, 5, 6} } 674fd4e5da5Sopenharmony_ci#define CASE5(NAME) { spv::Op::Op##NAME, #NAME, {3, 4, 5, 6, 7} } 675fd4e5da5Sopenharmony_ci#define CASE6(NAME) { spv::Op::Op##NAME, #NAME, {3, 4, 5, 6, 7, 8} } 676fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 677fd4e5da5Sopenharmony_ci TextToBinaryOpSpecConstantOp, OpSpecConstantOpTestWithIds, 678fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<EnumCase<spv::Op>>{ 679fd4e5da5Sopenharmony_ci // Conversion 680fd4e5da5Sopenharmony_ci CASE1(SConvert), 681fd4e5da5Sopenharmony_ci CASE1(FConvert), 682fd4e5da5Sopenharmony_ci CASE1(ConvertFToS), 683fd4e5da5Sopenharmony_ci CASE1(ConvertSToF), 684fd4e5da5Sopenharmony_ci CASE1(ConvertFToU), 685fd4e5da5Sopenharmony_ci CASE1(ConvertUToF), 686fd4e5da5Sopenharmony_ci CASE1(UConvert), 687fd4e5da5Sopenharmony_ci CASE1(ConvertPtrToU), 688fd4e5da5Sopenharmony_ci CASE1(ConvertUToPtr), 689fd4e5da5Sopenharmony_ci CASE1(GenericCastToPtr), 690fd4e5da5Sopenharmony_ci CASE1(PtrCastToGeneric), 691fd4e5da5Sopenharmony_ci CASE1(Bitcast), 692fd4e5da5Sopenharmony_ci CASE1(QuantizeToF16), 693fd4e5da5Sopenharmony_ci // Arithmetic 694fd4e5da5Sopenharmony_ci CASE1(SNegate), 695fd4e5da5Sopenharmony_ci CASE1(Not), 696fd4e5da5Sopenharmony_ci CASE2(IAdd), 697fd4e5da5Sopenharmony_ci CASE2(ISub), 698fd4e5da5Sopenharmony_ci CASE2(IMul), 699fd4e5da5Sopenharmony_ci CASE2(UDiv), 700fd4e5da5Sopenharmony_ci CASE2(SDiv), 701fd4e5da5Sopenharmony_ci CASE2(UMod), 702fd4e5da5Sopenharmony_ci CASE2(SRem), 703fd4e5da5Sopenharmony_ci CASE2(SMod), 704fd4e5da5Sopenharmony_ci CASE2(ShiftRightLogical), 705fd4e5da5Sopenharmony_ci CASE2(ShiftRightArithmetic), 706fd4e5da5Sopenharmony_ci CASE2(ShiftLeftLogical), 707fd4e5da5Sopenharmony_ci CASE2(BitwiseOr), 708fd4e5da5Sopenharmony_ci CASE2(BitwiseAnd), 709fd4e5da5Sopenharmony_ci CASE2(BitwiseXor), 710fd4e5da5Sopenharmony_ci CASE1(FNegate), 711fd4e5da5Sopenharmony_ci CASE2(FAdd), 712fd4e5da5Sopenharmony_ci CASE2(FSub), 713fd4e5da5Sopenharmony_ci CASE2(FMul), 714fd4e5da5Sopenharmony_ci CASE2(FDiv), 715fd4e5da5Sopenharmony_ci CASE2(FRem), 716fd4e5da5Sopenharmony_ci CASE2(FMod), 717fd4e5da5Sopenharmony_ci // Composite operations use literal numbers. So they're in another test. 718fd4e5da5Sopenharmony_ci // Logical 719fd4e5da5Sopenharmony_ci CASE2(LogicalOr), 720fd4e5da5Sopenharmony_ci CASE2(LogicalAnd), 721fd4e5da5Sopenharmony_ci CASE1(LogicalNot), 722fd4e5da5Sopenharmony_ci CASE2(LogicalEqual), 723fd4e5da5Sopenharmony_ci CASE2(LogicalNotEqual), 724fd4e5da5Sopenharmony_ci CASE3(Select), 725fd4e5da5Sopenharmony_ci // Comparison 726fd4e5da5Sopenharmony_ci CASE2(IEqual), 727fd4e5da5Sopenharmony_ci CASE2(INotEqual), // Allowed in 1.0 Rev 7 728fd4e5da5Sopenharmony_ci CASE2(ULessThan), 729fd4e5da5Sopenharmony_ci CASE2(SLessThan), 730fd4e5da5Sopenharmony_ci CASE2(UGreaterThan), 731fd4e5da5Sopenharmony_ci CASE2(SGreaterThan), 732fd4e5da5Sopenharmony_ci CASE2(ULessThanEqual), 733fd4e5da5Sopenharmony_ci CASE2(SLessThanEqual), 734fd4e5da5Sopenharmony_ci CASE2(UGreaterThanEqual), 735fd4e5da5Sopenharmony_ci CASE2(SGreaterThanEqual), 736fd4e5da5Sopenharmony_ci // Memory 737fd4e5da5Sopenharmony_ci // For AccessChain, there is a base Id, then a sequence of index Ids. 738fd4e5da5Sopenharmony_ci // Having no index Ids is a corner case. 739fd4e5da5Sopenharmony_ci CASE1(AccessChain), 740fd4e5da5Sopenharmony_ci CASE2(AccessChain), 741fd4e5da5Sopenharmony_ci CASE6(AccessChain), 742fd4e5da5Sopenharmony_ci CASE1(InBoundsAccessChain), 743fd4e5da5Sopenharmony_ci CASE2(InBoundsAccessChain), 744fd4e5da5Sopenharmony_ci CASE6(InBoundsAccessChain), 745fd4e5da5Sopenharmony_ci // PtrAccessChain also has an element Id. 746fd4e5da5Sopenharmony_ci CASE2(PtrAccessChain), 747fd4e5da5Sopenharmony_ci CASE3(PtrAccessChain), 748fd4e5da5Sopenharmony_ci CASE6(PtrAccessChain), 749fd4e5da5Sopenharmony_ci CASE2(InBoundsPtrAccessChain), 750fd4e5da5Sopenharmony_ci CASE3(InBoundsPtrAccessChain), 751fd4e5da5Sopenharmony_ci CASE6(InBoundsPtrAccessChain), 752fd4e5da5Sopenharmony_ci })); 753fd4e5da5Sopenharmony_ci#undef CASE1 754fd4e5da5Sopenharmony_ci#undef CASE2 755fd4e5da5Sopenharmony_ci#undef CASE3 756fd4e5da5Sopenharmony_ci#undef CASE4 757fd4e5da5Sopenharmony_ci#undef CASE5 758fd4e5da5Sopenharmony_ci#undef CASE6 759fd4e5da5Sopenharmony_ci// clang-format on 760fd4e5da5Sopenharmony_ci 761fd4e5da5Sopenharmony_ciusing OpSpecConstantOpTestWithTwoIdsThenLiteralNumbers = 762fd4e5da5Sopenharmony_ci spvtest::TextToBinaryTestBase<::testing::TestWithParam<EnumCase<spv::Op>>>; 763fd4e5da5Sopenharmony_ci 764fd4e5da5Sopenharmony_ci// The operands to the OpSpecConstantOp opcode are two Ids followed by a 765fd4e5da5Sopenharmony_ci// sequence of literal numbers. 766fd4e5da5Sopenharmony_ciTEST_P(OpSpecConstantOpTestWithTwoIdsThenLiteralNumbers, Assembly) { 767fd4e5da5Sopenharmony_ci std::stringstream input; 768fd4e5da5Sopenharmony_ci input << "%2 = OpSpecConstantOp %1 " << GetParam().name() << " %3 %4"; 769fd4e5da5Sopenharmony_ci for (auto number : GetParam().operands()) input << " " << number; 770fd4e5da5Sopenharmony_ci input << "\n"; 771fd4e5da5Sopenharmony_ci 772fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(input.str()), 773fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpSpecConstantOp, 774fd4e5da5Sopenharmony_ci {1, 2, uint32_t(GetParam().value()), 3, 4}, 775fd4e5da5Sopenharmony_ci GetParam().operands()))); 776fd4e5da5Sopenharmony_ci 777fd4e5da5Sopenharmony_ci // Check the disassembler as well. 778fd4e5da5Sopenharmony_ci EXPECT_THAT(EncodeAndDecodeSuccessfully(input.str()), input.str()); 779fd4e5da5Sopenharmony_ci} 780fd4e5da5Sopenharmony_ci 781fd4e5da5Sopenharmony_ci#define CASE(NAME) spv::Op::Op##NAME, #NAME 782fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 783fd4e5da5Sopenharmony_ci TextToBinaryOpSpecConstantOp, 784fd4e5da5Sopenharmony_ci OpSpecConstantOpTestWithTwoIdsThenLiteralNumbers, 785fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<EnumCase<spv::Op>>{ 786fd4e5da5Sopenharmony_ci // For VectorShuffle, there are two vector operands, and at least 787fd4e5da5Sopenharmony_ci // two selector Ids. OpenCL can have up to 16-element vectors. 788fd4e5da5Sopenharmony_ci {CASE(VectorShuffle), {0, 0}}, 789fd4e5da5Sopenharmony_ci {CASE(VectorShuffle), {4, 3, 2, 1}}, 790fd4e5da5Sopenharmony_ci {CASE(VectorShuffle), {0, 2, 4, 6, 1, 3, 5, 7}}, 791fd4e5da5Sopenharmony_ci {CASE(VectorShuffle), 792fd4e5da5Sopenharmony_ci {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}}, 793fd4e5da5Sopenharmony_ci // For CompositeInsert, there is an object to insert, the target 794fd4e5da5Sopenharmony_ci // composite, and then literal indices. 795fd4e5da5Sopenharmony_ci {CASE(CompositeInsert), {0}}, 796fd4e5da5Sopenharmony_ci {CASE(CompositeInsert), {4, 3, 99, 1}}, 797fd4e5da5Sopenharmony_ci })); 798fd4e5da5Sopenharmony_ci 799fd4e5da5Sopenharmony_ciusing OpSpecConstantOpTestWithOneIdThenLiteralNumbers = 800fd4e5da5Sopenharmony_ci spvtest::TextToBinaryTestBase<::testing::TestWithParam<EnumCase<spv::Op>>>; 801fd4e5da5Sopenharmony_ci 802fd4e5da5Sopenharmony_ci// The operands to the OpSpecConstantOp opcode are one Id followed by a 803fd4e5da5Sopenharmony_ci// sequence of literal numbers. 804fd4e5da5Sopenharmony_ciTEST_P(OpSpecConstantOpTestWithOneIdThenLiteralNumbers, Assembly) { 805fd4e5da5Sopenharmony_ci std::stringstream input; 806fd4e5da5Sopenharmony_ci input << "%2 = OpSpecConstantOp %1 " << GetParam().name() << " %3"; 807fd4e5da5Sopenharmony_ci for (auto number : GetParam().operands()) input << " " << number; 808fd4e5da5Sopenharmony_ci input << "\n"; 809fd4e5da5Sopenharmony_ci 810fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(input.str()), 811fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpSpecConstantOp, 812fd4e5da5Sopenharmony_ci {1, 2, uint32_t(GetParam().value()), 3}, 813fd4e5da5Sopenharmony_ci GetParam().operands()))); 814fd4e5da5Sopenharmony_ci 815fd4e5da5Sopenharmony_ci // Check the disassembler as well. 816fd4e5da5Sopenharmony_ci EXPECT_THAT(EncodeAndDecodeSuccessfully(input.str()), input.str()); 817fd4e5da5Sopenharmony_ci} 818fd4e5da5Sopenharmony_ci 819fd4e5da5Sopenharmony_ci#define CASE(NAME) spv::Op::Op##NAME, #NAME 820fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 821fd4e5da5Sopenharmony_ci TextToBinaryOpSpecConstantOp, 822fd4e5da5Sopenharmony_ci OpSpecConstantOpTestWithOneIdThenLiteralNumbers, 823fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<EnumCase<spv::Op>>{ 824fd4e5da5Sopenharmony_ci // For CompositeExtract, the universal limit permits up to 255 literal 825fd4e5da5Sopenharmony_ci // indices. Let's only test a few. 826fd4e5da5Sopenharmony_ci {CASE(CompositeExtract), {0}}, 827fd4e5da5Sopenharmony_ci {CASE(CompositeExtract), {0, 99, 42, 16, 17, 12, 19}}, 828fd4e5da5Sopenharmony_ci })); 829fd4e5da5Sopenharmony_ci 830fd4e5da5Sopenharmony_ci// TODO(dneto): OpConstantTrue 831fd4e5da5Sopenharmony_ci// TODO(dneto): OpConstantFalse 832fd4e5da5Sopenharmony_ci// TODO(dneto): OpConstantComposite 833fd4e5da5Sopenharmony_ci// TODO(dneto): OpConstantSampler: other variations Param is 0 or 1 834fd4e5da5Sopenharmony_ci// TODO(dneto): OpConstantNull 835fd4e5da5Sopenharmony_ci// TODO(dneto): OpSpecConstantTrue 836fd4e5da5Sopenharmony_ci// TODO(dneto): OpSpecConstantFalse 837fd4e5da5Sopenharmony_ci// TODO(dneto): OpSpecConstantComposite 838fd4e5da5Sopenharmony_ci// TODO(dneto): Negative tests for OpSpecConstantOp 839fd4e5da5Sopenharmony_ci 840fd4e5da5Sopenharmony_ci} // namespace 841fd4e5da5Sopenharmony_ci} // namespace spvtools 842