gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
bitfield.test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2023 Arm Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2019 The Regents of the University of California
15 * All rights reserved
16 *
17 * The license below extends only to copyright in the software and shall
18 * not be construed as granting a license to any other intellectual
19 * property including but not limited to intellectual property relating
20 * to a hardware implementation of the functionality of the software
21 * licensed hereunder. You may use the software subject to the license
22 * terms below provided that you ensure that this notice is replicated
23 * unmodified and in its entirety in all distributions of the software,
24 * modified or unmodified, in source code or in binary form.
25 *
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions are
28 * met: redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer;
30 * redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in the
32 * documentation and/or other materials provided with the distribution;
33 * neither the name of the copyright holders nor the names of its
34 * contributors may be used to endorse or promote products derived from
35 * this software without specific prior written permission.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
38 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
40 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
41 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 */
49
50#include <gtest/gtest.h>
51
52#include "base/bitfield.hh"
53
54using namespace gem5;
55
56/*
57 * The following tests the "mask(N)" function. It is assumed that the mask
58 * returned is a 64 bit value with the N LSBs set to one.
59 */
60TEST(BitfieldTest, Mask0Bits)
61{
62 EXPECT_EQ(0x0, mask(0));
63}
64
65TEST(BitfieldTest, Mask1Bit)
66{
67 EXPECT_EQ(0x1, mask(1));
68}
69
70TEST(BitfieldTest, Mask8Bits)
71{
72 EXPECT_EQ(0xFF, mask(8));
73}
74
75TEST(BitfieldTest, Mask16Bits)
76{
77 EXPECT_EQ(0xFFFF, mask(16));
78}
79
80TEST(BitfieldTest, Mask32Bits)
81{
82 EXPECT_EQ(0xFFFFFFFF, mask(32));
83}
84
85TEST(BitfieldTest, MaskAllBits)
86{
87 EXPECT_EQ(0xFFFFFFFFFFFFFFFF, mask(64));
88}
89
90TEST(BitfieldTest, MaskAllBitsGreaterThan64)
91{
92 /* We cannot create a mask greater than 64 bits. It should default to 64
93 * bits if this occurs.
94 */
95 EXPECT_EQ(0xFFFFFFFFFFFFFFFF, mask(70));
96}
97
98/*
99 * The following tests "mask(X, Y)". mask will create a 64 bit value with bits
100 * X to Y (inclusive) set to one.
101 */
102TEST(BitfieldTest, MaskOneBit)
103{
104 EXPECT_EQ(1, mask(0, 0));
105}
106
107TEST(BitfieldTest, MaskTwoBits)
108{
109 EXPECT_EQ((1 << 1) + 1, mask(1, 0));
110}
111
112TEST(BitfieldTest, MaskThreeBits)
113{
114 EXPECT_EQ((1 << 5) + (1 << 4) + (1 << 3), mask(5, 3));
115}
116
117TEST(BitfieldTest, MaskEntireRange)
118{
119 EXPECT_EQ(0xFFFFFFFFFFFFFFFF, mask(63, 0));
120}
121
122TEST(BitfieldTest, MaskOutsideOfRange)
123{
124 // Masking >64 bits is not possible. The maximum is a 64 bit mask.
125 EXPECT_EQ(0xFFFFFFFFFFFFFFFF, mask(100, 0));
126}
127
128/*
129 * The following tests "bits". This function extracts bit/bits from the input
130 * value and return them as the LSBs. The remaining bits are set to zero.
131 */
132TEST(BitfieldTest, ExtractOneBit)
133{
134 int32_t x = 1 << 31;
135 EXPECT_EQ(1, bits(x, 31));
136}
137
138TEST(BitfieldTest, Extract63rdBit)
139{
140 int64_t x = 1ULL << 63;
141 EXPECT_EQ(1, bits(x, 63));
142}
143
144TEST(BitfieldTest, ExtractFirstBit)
145{
146 int64_t x = 1;
147 EXPECT_EQ(1, bits(x, 0));
148}
149
150TEST(BitfieldTest, ExtractFirstBitFirstBitZero)
151{
152 int64_t x = 1 << 1;
153 EXPECT_EQ(0, bits(x, 0));
154}
155
156TEST(BitfieldTest, ExtractThreeBits)
157{
158 uint64_t x = 1 << 31;
159 EXPECT_EQ((1 << 2), bits(x, 31, 29));
160}
161
162
163/*
164 * The following tests "mbits(X, Y, Z)". mbits returns a value with bits Y to
165 * Z from X (in position Y to Z).
166 */
167TEST(BitfieldTest, MbitsStandardCase)
168{
169 uint64_t x = (1 << 10) + (1 << 1);
170 EXPECT_EQ((1 << 10), mbits(x, 10, 8));
171}
172
173TEST(BitfieldTest, MbitsEntireRange)
174{
175 uint64_t x = (1ULL << 63) + 1;
176 EXPECT_EQ((1ULL << 63) + 1, mbits(x, 63, 0));
177}
178
179/*
180 * The following tests the "sext<N>(X)" function. sext carries out a sign
181 * extention from N bits to 64 bits on value X. It does not zero bits past the
182 * sign bit if it was zero.
183 */
184TEST(BitfieldTest, SignExtendPositiveInput)
185{
186 int8_t val = 14;
187 int64_t output = 14;
188 EXPECT_EQ(output, sext<8>(val));
189}
190
191TEST(BitfieldTest, SignExtendNegativeInput)
192{
193 int8_t val = -14;
194 uint64_t output = -14;
195 EXPECT_EQ(output, sext<8>(val));
196}
197
198TEST(BitfieldTest, SignExtendPositiveInputOutsideRange)
199{
200 EXPECT_EQ((1 << 10), sext<8>(1 << 10));
201}
202
203TEST(BitfieldTest, SignExtendNegativeInputOutsideRange)
204{
205 uint64_t val = 0x4800000010000008;
206 uint64_t output = 0xF800000010000008;
207 EXPECT_EQ(output, sext<60>(val));
208}
209/*
210 * The following tests the "szext<N>(X)" function. szext carries out a sign
211 * extention from N bits to 64 bits on value X. Will zero bits past the sign
212 * bit if it was zero.
213 */
214TEST(BitfieldTest, SignZeroExtendPositiveInput)
215{
216 int8_t val = 14;
217 int64_t output = 14;
218 EXPECT_EQ(output, szext<8>(val));
219}
220
221TEST(BitfieldTest, SignZeroExtendNegativeInput)
222{
223 int8_t val = -14;
224 uint64_t output = -14;
225 EXPECT_EQ(output, szext<8>(val));
226}
227
228TEST(BitfieldTest, SignZeroExtendPositiveInputOutsideRange)
229{
230 EXPECT_EQ(0, szext<8>(1 << 10));
231}
232
233TEST(BitfieldTest, SignZeroExtendNegativeInputOutsideRange)
234{
235 uint64_t val = 0x4800000010000008;
236 uint64_t output = 0xF800000010000008;
237 EXPECT_EQ(output, szext<60>(val));
238}
239
240/* The following tests "insertBits(A, B, C, D)". insertBits returns A
241 * with bits B to C set to D's (B - C) LSBs. "insertBits(A, B, D)" overrides
242 * the function to insert only B's LSB to position B.
243 */
244TEST(BitfieldTest, InsertOneBitTo3)
245{
246 int64_t val = 0;
247 int64_t bits = (1 << 3) + (1 << 2) + (1 << 1) + 1;
248 EXPECT_EQ((1 << 3), insertBits(val, 3, bits));
249}
250
251TEST(BitfieldTest, InsertOneBitTo18)
252{
253 int64_t val = 0;
254 int64_t bits = (1 << 3) + (1 << 2) + (1 << 1) + 1;
255 EXPECT_EQ((1 << 18), insertBits(val, 18, bits));
256}
257
258TEST(BitfieldTest, InsertOneBitTo3LsbZero)
259{
260 int64_t val = 0;
261 int64_t bits = (1 << 3) + (1 << 2) + (1 << 1);
262 EXPECT_EQ(0, insertBits(val, 3, bits));
263}
264
265TEST(BitfieldTest, InsertOneBitTo18LsbZero)
266{
267 int64_t val = 0;
268 int64_t bits = (1 << 3) + (1 << 2) + (1 << 1);
269 EXPECT_EQ(0, insertBits(val, 18, bits));
270}
271
272TEST(BitfieldTest, InsertOnBitTo8LsbZero)
273{
274 int64_t val = (1 << 8);
275 int64_t bits = (1 << 3) + (1 << 2) + (1 << 1);
276 EXPECT_EQ(0, insertBits(val, 8, bits));
277}
278
279TEST(BitfieldTest, InsertMultipleBits)
280{
281 int64_t val = (1ULL << 63);
282 int64_t bits = (1 << 2) + 1;
283 EXPECT_EQ(val + (1 << 5) + (1 << 3), insertBits(val, 5, 3, bits));
284}
285
286TEST(BitfieldTest, InsertMultipleBitsOverwrite)
287{
288 int64_t val = (1 << 29);
289 int64_t bits = (1 << 2) + 1;
290 EXPECT_EQ((1 << 30) + (1 << 28), insertBits(val, 30, 28, bits));
291}
292
293// The following tests the "reverseBits" function.
294TEST(BitfieldTest, ReverseBits8Bit)
295{
296 uint8_t value = (1 << 7);
297 EXPECT_EQ(1, reverseBits(value));
298}
299
300TEST(BitfieldTest, ReverseBits64Bit)
301{
302 uint64_t value = 0xF0F0F0F0F0F0F0F1;
303 EXPECT_EQ(0x8F0F0F0F0F0F0F0F, reverseBits(value));
304}
305
306/* The following tests "findMsb" and "findLsb". These return the most position
307 * of the MSBs/LSBs of the input value.
308 */
309TEST(BitfieldTest, FindMsb29)
310{
311 uint64_t val = (1 << 29) + (1 << 1);
312 EXPECT_EQ(29, findMsbSet(val));
313}
314
315TEST(BitfieldTest, FindMsb63)
316{
317 uint64_t val = (1ULL << 63) + (1ULL << 60) + (1 << 1);
318 EXPECT_EQ(63, findMsbSet(val));
319}
320
321
322TEST(BitfieldTest, FindMsbZero)
323{
324 EXPECT_EQ(0, findMsbSet(0));
325}
326
327TEST(BitfieldTest, FindLsb)
328{
329 uint64_t val = (1ULL << 63) + (1 << 1);
330 EXPECT_EQ(1, findLsbSet(val));
331 EXPECT_EQ(1, findLsbSetFallback(val));
332}
333
334TEST(BitfieldTest, FindLsbZero)
335{
336 EXPECT_EQ(64, findLsbSet(0));
337}
338
339TEST(BitfieldTest, FindLsbGeneralized)
340{
341 static constexpr size_t N{1000};
342 std::bitset<N> bs{0};
343 EXPECT_EQ(findLsbSet(bs), N);
344 for (size_t i{0}; i < N ; ++i) {
345 bs = std::bitset<N>{1} << i;
346 ASSERT_EQ(findLsbSet(bs), i);
347 }
348
349 const auto leadingOne = std::bitset<N>{1} << (N-1);
350 for (size_t i{0}; i < N ; ++i) {
351 bs = leadingOne | (std::bitset<N>{1} << i);
352 ASSERT_EQ(findLsbSet(bs), i);
353 }
354}
355
356/*
357 * The following tests "popCount(X)". popCount counts the number of bits set to
358 * one.
359 */
360TEST(BitfieldTest, PopCountNoBits)
361{
362 EXPECT_EQ(0, popCount(0));
363}
364
365TEST(BitfieldTest, PopCountOneBit)
366{
367 int64_t val = (1 << 9);
368 EXPECT_EQ(1, popCount(val));
369}
370
371TEST(BitfieldTest, PopCountManyBits)
372{
373 int64_t val = (1 << 22) + (1 << 21) + (1 << 15) + (1 << 9) + 1;
374 EXPECT_EQ(5, popCount(val));
375}
376
377TEST(BitfieldTest, PopCountAllOnes)
378{
379 int64_t val = 0xFFFFFFFFFFFFFFFF;
380 EXPECT_EQ(64, popCount(val));
381}
382
383/*
384 * The following tests the "alignToPowerOfTwo(x)" function which rounds
385 * uint64_t x up to the nearest power of two. If x is already a power
386 * of two, that power is returned.
387 */
388TEST(BitfieldTest, AlignToPowerOfTwo0)
389{
390 EXPECT_EQ(0, alignToPowerOfTwo(0));
391}
392
393TEST(BitfieldTest, AlignToPowerOfTwo3)
394{
395 EXPECT_EQ(4, alignToPowerOfTwo(3));
396}
397
398TEST(BitfieldTest, AlignToPowerOfTwo5)
399{
400 EXPECT_EQ(8, alignToPowerOfTwo(5));
401}
402
403TEST(BitfieldTest, AlignToPowerOfTwo10)
404{
405 EXPECT_EQ(16, alignToPowerOfTwo(10));
406}
407
408TEST(BitfieldTest, AlignToPowerOfTwo16)
409{
410 EXPECT_EQ(16, alignToPowerOfTwo(16));
411}
412
413TEST(BitfieldTest, AlignToPowerOfTwo31)
414{
415 EXPECT_EQ(32, alignToPowerOfTwo(31));
416}
417
418/*
419 * The following tests test ctz32/64. The value returned in all cases should
420 * be equal to the number of trailing zeros (i.e., the number before the first
421 * bit set to one).
422 */
423
424TEST(BitfieldTest, CountTrailingZeros32BitsNoTrailing)
425{
426 int32_t value = 1;
427 EXPECT_EQ(0, ctz32(value));
428}
429
430TEST(BitfieldTest, CountTrailingZeros32Bits)
431{
432 uint32_t value = (1 << 30) + (1 << 29);
433 EXPECT_EQ(29, ctz32(value));
434}
435
436TEST(BitfieldTest, CountTrailingZeros64BitsNoTrailing)
437{
438 uint64_t value = (1 << 29) + 1;
439 EXPECT_EQ(0, ctz64(value));
440}
441
442TEST(BitfieldTest, CountTrailingZeros64Bits)
443{
444 uint64_t value = 1ULL << 63;
445 EXPECT_EQ(63, ctz64(value));
446}
447
448TEST(BitfieldTest, CountTrailingZero64AllZeros)
449{
450 uint64_t value = 0;
451 EXPECT_EQ(64, ctz64(value));
452}
453
454/*
455 * The following tests test clz32/64. The value returned in all cases should
456 * be equal to the number of leading zeros (i.e., the number of zeroes before
457 * the first bit set to one counting from the MSB).
458 */
459
460TEST(BitfieldTest, CountLeadingZeros32BitsNoTrailing)
461{
462 int32_t value = 1;
463 EXPECT_EQ(31, clz32(value));
464}
465
466TEST(BitfieldTest, CountLeadingZeros32Bits)
467{
468 uint32_t value = (1 << 30) + (1 << 29);
469 EXPECT_EQ(1, clz32(value));
470}
471
472TEST(BitfieldTest, CountLeadingZeros64BitsNoTrailing)
473{
474 uint64_t value = (1 << 29) + 1;
475 EXPECT_EQ(34, clz64(value));
476}
477
478TEST(BitfieldTest, CountLeadingZeros64Bits)
479{
480 uint64_t value = 1ULL << 63;
481 EXPECT_EQ(0, clz64(value));
482}
483
484TEST(BitfieldTest, CountLeadingZero64AllZeros)
485{
486 uint64_t value = 0;
487 EXPECT_EQ(64, clz64(value));
488}
489
490/*
491 * This test simply check the the single bit decoding
492 * a) The 1 pattern returns true for 0b1 and false for 0b0
493 * b) The 0 pattern returns true for 0b0 and false for 0b1
494 * c) The X pattern returns true for both 0b0 and 0b1
495 */
496TEST(BitfieldTest, DecodeMaskOneBit)
497{
498 constexpr auto decode_1 = bitPatternMatcher<uint8_t, 0, 0, '1'>();
499 EXPECT_FALSE(decode_1(0b0));
500 EXPECT_TRUE(decode_1(0b1));
501
502 constexpr auto decode_0 = bitPatternMatcher<uint8_t, 0, 0, '0'>();
503 EXPECT_TRUE(decode_0(0b0));
504 EXPECT_FALSE(decode_0(0b1));
505
506 constexpr auto decode_x = bitPatternMatcher<uint8_t, 0, 0, 'X'>();
507 EXPECT_TRUE(decode_x(0b0));
508 EXPECT_TRUE(decode_x(0b1));
509}
510
511/*
512 * This test tries to match multiple bits (4)
513 * with the 101X pattern
514 */
515TEST(BitfieldTest, DecodeMaskMultipleBits)
516{
517 constexpr auto decode = bitPatternMatcher<
518 uint8_t, 3, 0, '1', '0', '1', 'X'>();
519
520 EXPECT_FALSE(decode(0b0000));
521 EXPECT_FALSE(decode(0b0010));
522
523 EXPECT_TRUE(decode(0b1010));
524 EXPECT_TRUE(decode(0b1011));
525}
TEST(BitfieldTest, Mask0Bits)
constexpr int findMsbSet(uint64_t val)
Returns the bit position of the MSB that is set in the input.
Definition bitfield.hh:279
constexpr int clz32(uint32_t value)
Count leading zeros in a 32-bit value.
Definition bitfield.hh:501
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
constexpr int popCount(uint64_t val)
Returns the number of set ones in the provided value.
Definition bitfield.hh:415
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
Definition bitfield.hh:106
constexpr int ctz32(uint32_t value)
Count trailing zeros in a 32-bit value.
Definition bitfield.hh:473
constexpr uint64_t szext(uint64_t val)
Sign-extend an N-bit value to 64 bits.
Definition bitfield.hh:161
constexpr T insertBits(T val, unsigned first, unsigned last, B bit_val)
Returns val with bits first to last set to the LSBs of bit_val.
Definition bitfield.hh:185
constexpr uint64_t alignToPowerOfTwo(uint64_t val)
Align to the next highest power of two.
Definition bitfield.hh:450
constexpr uint64_t sext(uint64_t val)
Sign-extend an N-bit value to 64 bits.
Definition bitfield.hh:129
constexpr int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input That function will either use a builtin ...
Definition bitfield.hh:369
constexpr int ctz64(uint64_t value)
Count trailing zeros in a 64-bit value.
Definition bitfield.hh:487
constexpr int clz64(uint64_t value)
Count leading zeros in a 64-bit value.
Definition bitfield.hh:515
std::enable_if_t< std::is_integral_v< T >, T > reverseBits(T val, size_t size=sizeof(T))
Takes a value and returns the bit reversed version.
Definition bitfield.hh:255
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 3 > x
Definition pagetable.hh:76
Bitfield< 63 > val
Definition misc.hh:804
Bitfield< 14 > bs
Definition misc.hh:686
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
constexpr auto bitPatternMatcher()
This helper implements a pattern matcher that can be used for instruction decoding.
Definition bitfield.hh:591
static void output(const char *filename)
Definition debug.cc:60

Generated on Mon May 26 2025 09:19:06 for gem5 by doxygen 1.13.2