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