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