1 // Copyright (c) 2019 Google 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 #include "source/util/bitutils.h"
16
17 #include "gmock/gmock.h"
18
19 namespace spvtools {
20 namespace utils {
21 namespace {
22
23 using BitUtilsTest = ::testing::Test;
24
TEST(BitUtilsTest,MutateBitsWholeWord)25 TEST(BitUtilsTest, MutateBitsWholeWord) {
26 const uint32_t zero_u32 = 0;
27 const uint32_t max_u32 = ~0;
28
29 EXPECT_EQ(MutateBits(zero_u32, 0, 0, false), zero_u32);
30 EXPECT_EQ(MutateBits(max_u32, 0, 0, false), max_u32);
31 EXPECT_EQ(MutateBits(zero_u32, 0, 32, false), zero_u32);
32 EXPECT_EQ(MutateBits(zero_u32, 0, 32, true), max_u32);
33 EXPECT_EQ(MutateBits(max_u32, 0, 32, true), max_u32);
34 EXPECT_EQ(MutateBits(max_u32, 0, 32, false), zero_u32);
35 }
36
TEST(BitUtilsTest,MutateBitsLow)37 TEST(BitUtilsTest, MutateBitsLow) {
38 const uint32_t zero_u32 = 0;
39 const uint32_t one_u32 = 1;
40 const uint32_t max_u32 = ~0;
41
42 EXPECT_EQ(MutateBits(zero_u32, 0, 1, false), zero_u32);
43 EXPECT_EQ(MutateBits(zero_u32, 0, 1, true), one_u32);
44 EXPECT_EQ(MutateBits(max_u32, 0, 1, true), max_u32);
45 EXPECT_EQ(MutateBits(one_u32, 0, 32, false), zero_u32);
46 EXPECT_EQ(MutateBits(one_u32, 0, 1, true), one_u32);
47 EXPECT_EQ(MutateBits(one_u32, 0, 1, false), zero_u32);
48 EXPECT_EQ(MutateBits(zero_u32, 0, 3, true), uint32_t(7));
49 EXPECT_EQ(MutateBits(uint32_t(7), 0, 2, false), uint32_t(4));
50 }
51
TEST(BitUtilsTest,MutateBitsHigh)52 TEST(BitUtilsTest, MutateBitsHigh) {
53 const uint8_t zero_u8 = 0;
54 const uint8_t one_u8 = 1;
55 const uint8_t max_u8 = 255;
56
57 EXPECT_EQ(MutateBits(zero_u8, 7, 0, true), zero_u8);
58 EXPECT_EQ(MutateBits(zero_u8, 7, 1, true), uint8_t(128));
59 EXPECT_EQ(MutateBits(one_u8, 7, 1, true), uint8_t(129));
60 EXPECT_EQ(MutateBits(max_u8, 7, 1, true), max_u8);
61 EXPECT_EQ(MutateBits(max_u8, 7, 1, false), uint8_t(127));
62 EXPECT_EQ(MutateBits(max_u8, 6, 2, true), max_u8);
63 EXPECT_EQ(MutateBits(max_u8, 6, 2, false), uint8_t(63));
64 }
65
TEST(BitUtilsTest,MutateBitsUint8Mid)66 TEST(BitUtilsTest, MutateBitsUint8Mid) {
67 const uint8_t zero_u8 = 0;
68 const uint8_t max_u8 = 255;
69
70 EXPECT_EQ(MutateBits(zero_u8, 1, 2, true), uint8_t(6));
71 EXPECT_EQ(MutateBits(max_u8, 1, 2, true), max_u8);
72 EXPECT_EQ(MutateBits(max_u8, 1, 2, false), uint8_t(0xF9));
73 EXPECT_EQ(MutateBits(zero_u8, 2, 3, true), uint8_t(0x1C));
74 }
75
TEST(BitUtilsTest,MutateBitsUint64Mid)76 TEST(BitUtilsTest, MutateBitsUint64Mid) {
77 const uint64_t zero_u64 = 0;
78 const uint64_t max_u64 = ~zero_u64;
79
80 EXPECT_EQ(MutateBits(zero_u64, 1, 2, true), uint64_t(6));
81 EXPECT_EQ(MutateBits(max_u64, 1, 2, true), max_u64);
82 EXPECT_EQ(MutateBits(max_u64, 1, 2, false), uint64_t(0xFFFFFFFFFFFFFFF9));
83 EXPECT_EQ(MutateBits(zero_u64, 2, 3, true), uint64_t(0x000000000000001C));
84 EXPECT_EQ(MutateBits(zero_u64, 2, 35, true), uint64_t(0x0000001FFFFFFFFC));
85 EXPECT_EQ(MutateBits(zero_u64, 36, 4, true), uint64_t(0x000000F000000000));
86 EXPECT_EQ(MutateBits(max_u64, 36, 4, false), uint64_t(0xFFFFFF0FFFFFFFFF));
87 }
88
TEST(BitUtilsTest,SetHighBitsUint32)89 TEST(BitUtilsTest, SetHighBitsUint32) {
90 const uint32_t zero_u32 = 0;
91 const uint32_t one_u32 = 1;
92 const uint32_t max_u32 = ~zero_u32;
93
94 EXPECT_EQ(SetHighBits(zero_u32, 0), zero_u32);
95 EXPECT_EQ(SetHighBits(zero_u32, 1), 0x80000000);
96 EXPECT_EQ(SetHighBits(one_u32, 1), 0x80000001);
97 EXPECT_EQ(SetHighBits(one_u32, 2), 0xC0000001);
98 EXPECT_EQ(SetHighBits(zero_u32, 31), 0xFFFFFFFE);
99 EXPECT_EQ(SetHighBits(zero_u32, 32), max_u32);
100 EXPECT_EQ(SetHighBits(max_u32, 32), max_u32);
101 }
102
TEST(BitUtilsTest,ClearHighBitsUint32)103 TEST(BitUtilsTest, ClearHighBitsUint32) {
104 const uint32_t zero_u32 = 0;
105 const uint32_t one_u32 = 1;
106 const uint32_t max_u32 = ~zero_u32;
107
108 EXPECT_EQ(ClearHighBits(zero_u32, 0), zero_u32);
109 EXPECT_EQ(ClearHighBits(zero_u32, 1), zero_u32);
110 EXPECT_EQ(ClearHighBits(one_u32, 1), one_u32);
111 EXPECT_EQ(ClearHighBits(one_u32, 31), one_u32);
112 EXPECT_EQ(ClearHighBits(one_u32, 32), zero_u32);
113 EXPECT_EQ(ClearHighBits(max_u32, 0), max_u32);
114 EXPECT_EQ(ClearHighBits(max_u32, 1), 0x7FFFFFFF);
115 EXPECT_EQ(ClearHighBits(max_u32, 2), 0x3FFFFFFF);
116 EXPECT_EQ(ClearHighBits(max_u32, 31), one_u32);
117 EXPECT_EQ(ClearHighBits(max_u32, 32), zero_u32);
118 }
119
TEST(BitUtilsTest,IsBitSetAtPositionZero)120 TEST(BitUtilsTest, IsBitSetAtPositionZero) {
121 const uint32_t zero_u32 = 0;
122 for (size_t i = 0; i != 32; ++i) {
123 EXPECT_FALSE(IsBitAtPositionSet(zero_u32, i));
124 }
125
126 const uint8_t zero_u8 = 0;
127 for (size_t i = 0; i != 8; ++i) {
128 EXPECT_FALSE(IsBitAtPositionSet(zero_u8, i));
129 }
130
131 const uint64_t zero_u64 = 0;
132 for (size_t i = 0; i != 64; ++i) {
133 EXPECT_FALSE(IsBitAtPositionSet(zero_u64, i));
134 }
135 }
136
TEST(BitUtilsTest,IsBitSetAtPositionOne)137 TEST(BitUtilsTest, IsBitSetAtPositionOne) {
138 const uint32_t one_u32 = 1;
139 for (size_t i = 0; i != 32; ++i) {
140 if (i == 0) {
141 EXPECT_TRUE(IsBitAtPositionSet(one_u32, i));
142 } else {
143 EXPECT_FALSE(IsBitAtPositionSet(one_u32, i));
144 }
145 }
146
147 const uint32_t two_to_17_u32 = 1 << 17;
148 for (size_t i = 0; i != 32; ++i) {
149 if (i == 17) {
150 EXPECT_TRUE(IsBitAtPositionSet(two_to_17_u32, i));
151 } else {
152 EXPECT_FALSE(IsBitAtPositionSet(two_to_17_u32, i));
153 }
154 }
155
156 const uint8_t two_to_4_u8 = 1 << 4;
157 for (size_t i = 0; i != 8; ++i) {
158 if (i == 4) {
159 EXPECT_TRUE(IsBitAtPositionSet(two_to_4_u8, i));
160 } else {
161 EXPECT_FALSE(IsBitAtPositionSet(two_to_4_u8, i));
162 }
163 }
164
165 const uint64_t two_to_55_u64 = uint64_t(1) << 55;
166 for (size_t i = 0; i != 64; ++i) {
167 if (i == 55) {
168 EXPECT_TRUE(IsBitAtPositionSet(two_to_55_u64, i));
169 } else {
170 EXPECT_FALSE(IsBitAtPositionSet(two_to_55_u64, i));
171 }
172 }
173 }
174
TEST(BitUtilsTest,IsBitSetAtPositionAll)175 TEST(BitUtilsTest, IsBitSetAtPositionAll) {
176 const uint32_t max_u32 = ~0;
177 for (size_t i = 0; i != 32; ++i) {
178 EXPECT_TRUE(IsBitAtPositionSet(max_u32, i));
179 }
180
181 const uint32_t max_u8 = ~uint8_t(0);
182 for (size_t i = 0; i != 8; ++i) {
183 EXPECT_TRUE(IsBitAtPositionSet(max_u8, i));
184 }
185
186 const uint64_t max_u64 = ~uint64_t(0);
187 for (size_t i = 0; i != 64; ++i) {
188 EXPECT_TRUE(IsBitAtPositionSet(max_u64, i));
189 }
190 }
191 } // namespace
192 } // namespace utils
193 } // namespace spvtools
194