builtins: Add insertBits
CTS tests: https://github.com/gpuweb/cts/pull/1012
Bug: tint:1371
Change-Id: Idd55c0bc9dad1dffb558d0bc57d744f65e9041b5
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/81701
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/tint/transform/builtin_polyfill_test.cc b/src/tint/transform/builtin_polyfill_test.cc
index 4ac51fd..49e0471 100644
--- a/src/tint/transform/builtin_polyfill_test.cc
+++ b/src/tint/transform/builtin_polyfill_test.cc
@@ -889,6 +889,233 @@
EXPECT_EQ(expect, str(got));
}
+////////////////////////////////////////////////////////////////////////////////
+// insertBits
+////////////////////////////////////////////////////////////////////////////////
+DataMap polyfillInsertBits(Level level) {
+ BuiltinPolyfill::Builtins builtins;
+ builtins.insert_bits = level;
+ DataMap data;
+ data.Add<BuiltinPolyfill::Config>(builtins);
+ return data;
+}
+
+TEST_F(BuiltinPolyfillTest, ShouldRunInsertBits) {
+ auto* src = R"(
+fn f() {
+ insertBits(1234, 5678, 5u, 6u);
+}
+)";
+
+ EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
+ EXPECT_FALSE(
+ ShouldRun<BuiltinPolyfill>(src, polyfillInsertBits(Level::kNone)));
+ EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(
+ src, polyfillInsertBits(Level::kClampParameters)));
+ EXPECT_TRUE(
+ ShouldRun<BuiltinPolyfill>(src, polyfillInsertBits(Level::kFull)));
+}
+
+TEST_F(BuiltinPolyfillTest, InsertBits_Full_i32) {
+ auto* src = R"(
+fn f() {
+ let r : i32 = insertBits(1234, 5678, 5u, 6u);
+}
+)";
+
+ auto* expect = R"(
+fn tint_insert_bits(v : i32, n : i32, offset : u32, count : u32) -> i32 {
+ let s = min(offset, 32u);
+ let e = min(32u, (s + count));
+ let mask = (((1u << s) - 1u) ^ ((1u << e) - 1u));
+ return (((n << s) & i32(mask)) | (v & i32(~(mask))));
+}
+
+fn f() {
+ let r : i32 = tint_insert_bits(1234, 5678, 5u, 6u);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kFull));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, InsertBits_Full_u32) {
+ auto* src = R"(
+fn f() {
+ let r : u32 = insertBits(1234u, 5678u, 5u, 6u);
+}
+)";
+
+ auto* expect = R"(
+fn tint_insert_bits(v : u32, n : u32, offset : u32, count : u32) -> u32 {
+ let s = min(offset, 32u);
+ let e = min(32u, (s + count));
+ let mask = (((1u << s) - 1u) ^ ((1u << e) - 1u));
+ return (((n << s) & mask) | (v & ~(mask)));
+}
+
+fn f() {
+ let r : u32 = tint_insert_bits(1234u, 5678u, 5u, 6u);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kFull));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, InsertBits_Full_vec3_i32) {
+ auto* src = R"(
+fn f() {
+ let r : vec3<i32> = insertBits(vec3<i32>(1234), vec3<i32>(5678), 5u, 6u);
+}
+)";
+
+ auto* expect = R"(
+fn tint_insert_bits(v : vec3<i32>, n : vec3<i32>, offset : u32, count : u32) -> vec3<i32> {
+ let s = min(offset, 32u);
+ let e = min(32u, (s + count));
+ let mask = (((1u << s) - 1u) ^ ((1u << e) - 1u));
+ return (((n << vec3<u32>(s)) & vec3<i32>(i32(mask))) | (v & vec3<i32>(i32(~(mask)))));
+}
+
+fn f() {
+ let r : vec3<i32> = tint_insert_bits(vec3<i32>(1234), vec3<i32>(5678), 5u, 6u);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kFull));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, InsertBits_Full_vec3_u32) {
+ auto* src = R"(
+fn f() {
+ let r : vec3<u32> = insertBits(vec3<u32>(1234u), vec3<u32>(5678u), 5u, 6u);
+}
+)";
+
+ auto* expect = R"(
+fn tint_insert_bits(v : vec3<u32>, n : vec3<u32>, offset : u32, count : u32) -> vec3<u32> {
+ let s = min(offset, 32u);
+ let e = min(32u, (s + count));
+ let mask = (((1u << s) - 1u) ^ ((1u << e) - 1u));
+ return (((n << vec3<u32>(s)) & vec3<u32>(mask)) | (v & vec3<u32>(~(mask))));
+}
+
+fn f() {
+ let r : vec3<u32> = tint_insert_bits(vec3<u32>(1234u), vec3<u32>(5678u), 5u, 6u);
+}
+)";
+
+ auto got = Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kFull));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, InsertBits_Clamp_i32) {
+ auto* src = R"(
+fn f() {
+ let r : i32 = insertBits(1234, 5678, 5u, 6u);
+}
+)";
+
+ auto* expect = R"(
+fn tint_insert_bits(v : i32, n : i32, offset : u32, count : u32) -> i32 {
+ let s = min(offset, 32u);
+ let e = min(32u, (s + count));
+ return insertBits(v, n, s, (e - s));
+}
+
+fn f() {
+ let r : i32 = tint_insert_bits(1234, 5678, 5u, 6u);
+}
+)";
+
+ auto got =
+ Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kClampParameters));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, InsertBits_Clamp_u32) {
+ auto* src = R"(
+fn f() {
+ let r : u32 = insertBits(1234u, 5678u, 5u, 6u);
+}
+)";
+
+ auto* expect = R"(
+fn tint_insert_bits(v : u32, n : u32, offset : u32, count : u32) -> u32 {
+ let s = min(offset, 32u);
+ let e = min(32u, (s + count));
+ return insertBits(v, n, s, (e - s));
+}
+
+fn f() {
+ let r : u32 = tint_insert_bits(1234u, 5678u, 5u, 6u);
+}
+)";
+
+ auto got =
+ Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kClampParameters));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, InsertBits_Clamp_vec3_i32) {
+ auto* src = R"(
+fn f() {
+ let r : vec3<i32> = insertBits(vec3<i32>(1234), vec3<i32>(5678), 5u, 6u);
+}
+)";
+
+ auto* expect = R"(
+fn tint_insert_bits(v : vec3<i32>, n : vec3<i32>, offset : u32, count : u32) -> vec3<i32> {
+ let s = min(offset, 32u);
+ let e = min(32u, (s + count));
+ return insertBits(v, n, s, (e - s));
+}
+
+fn f() {
+ let r : vec3<i32> = tint_insert_bits(vec3<i32>(1234), vec3<i32>(5678), 5u, 6u);
+}
+)";
+
+ auto got =
+ Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kClampParameters));
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, InsertBits_Clamp_vec3_u32) {
+ auto* src = R"(
+fn f() {
+ let r : vec3<u32> = insertBits(vec3<u32>(1234u), vec3<u32>(5678u), 5u, 6u);
+}
+)";
+
+ auto* expect = R"(
+fn tint_insert_bits(v : vec3<u32>, n : vec3<u32>, offset : u32, count : u32) -> vec3<u32> {
+ let s = min(offset, 32u);
+ let e = min(32u, (s + count));
+ return insertBits(v, n, s, (e - s));
+}
+
+fn f() {
+ let r : vec3<u32> = tint_insert_bits(vec3<u32>(1234u), vec3<u32>(5678u), 5u, 6u);
+}
+)";
+
+ auto got =
+ Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kClampParameters));
+
+ EXPECT_EQ(expect, str(got));
+}
+
} // namespace
} // namespace transform
} // namespace tint