Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/src/common-tests/bitutils_tests.cpp
4212 views
1
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <[email protected]>
2
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
3
4
#include "common/align.h"
5
#include "common/bitfield.h"
6
#include "common/bitutils.h"
7
8
#include "gtest/gtest.h"
9
10
#include <type_traits>
11
12
// Test fixture for BitField tests
13
namespace {
14
// Simple test structs using different backing types and field configurations
15
union TestUnion8
16
{
17
u8 bits;
18
BitField<u8, bool, 0, 1> flag;
19
BitField<u8, u8, 1, 3> value3bit;
20
BitField<u8, u8, 4, 4> value4bit;
21
BitField<u8, s8, 4, 4> signed4bit;
22
};
23
24
union TestUnion16
25
{
26
u16 bits;
27
BitField<u16, bool, 0, 1> flag;
28
BitField<u16, u8, 1, 8> value8bit;
29
BitField<u16, u8, 9, 7> value7bit;
30
BitField<u16, s8, 8, 8> signed8bit;
31
};
32
33
union TestUnion32
34
{
35
u32 bits;
36
BitField<u32, bool, 0, 1> flag;
37
BitField<u32, u16, 1, 16> value16bit;
38
BitField<u32, u32, 17, 15> value15bit;
39
BitField<u32, s16, 16, 16> signed16bit;
40
};
41
42
union TestUnion64
43
{
44
u64 bits;
45
BitField<u64, bool, 0, 1> flag;
46
BitField<u64, u32, 1, 32> value32bit;
47
BitField<u64, u64, 33, 31> value31bit;
48
BitField<u64, s32, 32, 32> signed32bit;
49
};
50
} // namespace
51
52
// Tests for GetMask method
53
TEST(BitField, GetMask)
54
{
55
TestUnion8 test8{};
56
EXPECT_EQ(test8.flag.GetMask(), 0x01u);
57
EXPECT_EQ(test8.value3bit.GetMask(), 0x0Eu);
58
EXPECT_EQ(test8.value4bit.GetMask(), 0xF0u);
59
60
TestUnion16 test16{};
61
EXPECT_EQ(test16.flag.GetMask(), 0x0001u);
62
EXPECT_EQ(test16.value8bit.GetMask(), 0x01FEu);
63
EXPECT_EQ(test16.value7bit.GetMask(), 0xFE00u);
64
65
TestUnion32 test32{};
66
EXPECT_EQ(test32.flag.GetMask(), 0x00000001u);
67
EXPECT_EQ(test32.value16bit.GetMask(), 0x0001FFFEu);
68
EXPECT_EQ(test32.value15bit.GetMask(), 0xFFFE0000u);
69
70
TestUnion64 test64{};
71
EXPECT_EQ(test64.flag.GetMask(), 0x0000000000000001ULL);
72
EXPECT_EQ(test64.value32bit.GetMask(), 0x00000001FFFFFFFEULL);
73
EXPECT_EQ(test64.value31bit.GetMask(), 0xFFFFFFFE00000000ULL);
74
}
75
76
// Tests for implicit conversion operator (operator DataType())
77
TEST(BitField, ImplicitConversion)
78
{
79
TestUnion8 test8{};
80
test8.bits = 0xFF;
81
82
bool flag_value = test8.flag;
83
EXPECT_TRUE(flag_value);
84
85
u8 value3bit_value = test8.value3bit;
86
EXPECT_EQ(value3bit_value, 7);
87
88
u8 value4bit_value = test8.value4bit;
89
EXPECT_EQ(value4bit_value, 15);
90
91
// Test with zeros
92
test8.bits = 0x00;
93
flag_value = test8.flag;
94
EXPECT_FALSE(flag_value);
95
96
value3bit_value = test8.value3bit;
97
EXPECT_EQ(value3bit_value, 0);
98
}
99
100
// Tests for assignment operator (operator=)
101
TEST(BitField, Assignment)
102
{
103
TestUnion8 test8{};
104
test8.bits = 0x00;
105
106
test8.flag = true;
107
EXPECT_EQ(test8.bits, 0x01);
108
109
test8.value3bit = 5;
110
EXPECT_EQ(test8.bits, 0x0B); // 0001 (flag) + 1010 (5 << 1)
111
112
test8.value4bit = 12;
113
EXPECT_EQ(test8.bits, 0xCB); // Previous + 1100 (12 << 4)
114
115
// Test overwriting
116
test8.flag = false;
117
EXPECT_EQ(test8.bits, 0xCA);
118
}
119
120
// Tests for prefix increment operator (operator++())
121
TEST(BitField, PrefixIncrement)
122
{
123
TestUnion8 test8{};
124
test8.bits = 0x00;
125
test8.value3bit = 3;
126
127
u8 result = ++test8.value3bit;
128
EXPECT_EQ(result, 4);
129
EXPECT_EQ(static_cast<u8>(test8.value3bit), 4);
130
131
// Test overflow handling
132
test8.value3bit = 7; // Maximum for 3 bits
133
result = ++test8.value3bit;
134
EXPECT_EQ(result, 0); // Should wrap around
135
EXPECT_EQ(static_cast<u8>(test8.value3bit), 0);
136
}
137
138
// Tests for postfix increment operator (operator++(int))
139
TEST(BitField, PostfixIncrement)
140
{
141
TestUnion8 test8{};
142
test8.bits = 0x00;
143
test8.value3bit = 3;
144
145
u8 result = test8.value3bit++;
146
EXPECT_EQ(result, 3); // Should return old value
147
EXPECT_EQ(static_cast<u8>(test8.value3bit), 4); // Should increment
148
149
// Test overflow handling
150
test8.value3bit = 7; // Maximum for 3 bits
151
result = test8.value3bit++;
152
EXPECT_EQ(result, 7); // Should return old value
153
EXPECT_EQ(static_cast<u8>(test8.value3bit), 0); // Should wrap around
154
}
155
156
// Tests for prefix decrement operator (operator--())
157
TEST(BitField, PrefixDecrement)
158
{
159
TestUnion8 test8{};
160
test8.bits = 0x00;
161
test8.value3bit = 4;
162
163
u8 result = --test8.value3bit;
164
EXPECT_EQ(result, 3);
165
EXPECT_EQ(static_cast<u8>(test8.value3bit), 3);
166
167
// Test underflow handling
168
test8.value3bit = 0;
169
result = --test8.value3bit;
170
EXPECT_EQ(result, 7); // Should wrap around
171
EXPECT_EQ(static_cast<u8>(test8.value3bit), 7);
172
}
173
174
// Tests for postfix decrement operator (operator--(int))
175
TEST(BitField, PostfixDecrement)
176
{
177
TestUnion8 test8{};
178
test8.bits = 0x00;
179
test8.value3bit = 4;
180
181
u8 result = test8.value3bit--;
182
EXPECT_EQ(result, 4); // Should return old value
183
EXPECT_EQ(static_cast<u8>(test8.value3bit), 3); // Should decrement
184
185
// Test underflow handling
186
test8.value3bit = 0;
187
result = test8.value3bit--;
188
EXPECT_EQ(result, 0); // Should return old value
189
EXPECT_EQ(static_cast<u8>(test8.value3bit), 7); // Should wrap around
190
}
191
192
// Tests for compound assignment operators (+=, -=, *=, /=)
193
TEST(BitField, CompoundArithmeticOperators)
194
{
195
TestUnion8 test8{};
196
test8.bits = 0x00;
197
test8.value4bit = 5;
198
199
// Test +=
200
test8.value4bit += 3;
201
EXPECT_EQ(static_cast<u8>(test8.value4bit), 8);
202
203
// Test -=
204
test8.value4bit -= 2;
205
EXPECT_EQ(static_cast<u8>(test8.value4bit), 6);
206
207
// Test *=
208
test8.value4bit *= 2;
209
EXPECT_EQ(static_cast<u8>(test8.value4bit), 12);
210
211
// Test / =
212
test8.value4bit /= 3;
213
EXPECT_EQ(static_cast<u8>(test8.value4bit), 4);
214
215
// Test overflow with +=
216
test8.value4bit = 14;
217
test8.value4bit += 5; // Should overflow and wrap
218
EXPECT_EQ(static_cast<u8>(test8.value4bit), 3); // (14 + 5) & 0xF = 19 & 0xF = 3
219
}
220
221
// Tests for compound bitwise operators (&=, |=, ^=, <<=, >>=)
222
TEST(BitField, CompoundBitwiseOperators)
223
{
224
TestUnion8 test8{};
225
test8.bits = 0x00;
226
test8.value4bit = 12; // 1100
227
228
// Test & =
229
test8.value4bit &= 10; // 1100 & 1010 = 1000
230
EXPECT_EQ(static_cast<u8>(test8.value4bit), 8);
231
232
// Test |=
233
test8.value4bit |= 3; // 1000 | 0011 = 1011
234
EXPECT_EQ(static_cast<u8>(test8.value4bit), 11);
235
236
// Test ^ =
237
test8.value4bit ^= 5; // 1011 ^ 0101 = 1110
238
EXPECT_EQ(static_cast<u8>(test8.value4bit), 14);
239
240
// Test << =
241
test8.value4bit = 3; // 0011
242
test8.value4bit <<= 2; // 0011 << 2 = 1100
243
EXPECT_EQ(static_cast<u8>(test8.value4bit), 12);
244
245
// Test >> =
246
test8.value4bit >>= 1; // 1100 >> 1 = 0110
247
EXPECT_EQ(static_cast<u8>(test8.value4bit), 6);
248
}
249
250
// Tests for GetValue method with different data types
251
TEST(BitField, GetValue)
252
{
253
// Test unsigned values
254
TestUnion16 test16{};
255
test16.bits = 0xFFFF;
256
EXPECT_EQ(test16.flag.GetValue(), true);
257
EXPECT_EQ(test16.value8bit.GetValue(), 0xFF);
258
EXPECT_EQ(test16.value7bit.GetValue(), 0x7F);
259
260
// Test signed values
261
test16.bits = 0xFF00; // Set upper 8 bits
262
EXPECT_EQ(test16.signed8bit.GetValue(), -1); // Should be sign-extended
263
264
test16.bits = 0x7F00; // Set bit pattern for +127
265
EXPECT_EQ(test16.signed8bit.GetValue(), 127);
266
267
test16.bits = 0x8000; // Set bit pattern for -128
268
EXPECT_EQ(test16.signed8bit.GetValue(), -128);
269
}
270
271
// Tests for SetValue method
272
TEST(BitField, SetValue)
273
{
274
TestUnion16 test16{};
275
test16.bits = 0x0000;
276
277
test16.flag.SetValue(true);
278
EXPECT_EQ(test16.bits, 0x0001);
279
280
test16.value8bit.SetValue(0xAB);
281
EXPECT_EQ(test16.bits, 0x0157); // 0xAB << 1 | 0x0001
282
283
test16.value7bit.SetValue(0x55);
284
EXPECT_EQ(test16.bits, 0xAB57); // 0x55 << 9 | previous
285
286
// Test that setting doesn't affect other fields
287
test16.bits = 0xFFFF;
288
test16.flag.SetValue(false);
289
EXPECT_EQ(test16.bits, 0xFFFE); // Only bit 0 should be cleared
290
}
291
292
// Tests for boolean BitFields (1-bit fields)
293
TEST(BitField, BooleanBitFields)
294
{
295
TestUnion8 test8{};
296
test8.bits = 0x00;
297
298
// Test setting and getting boolean values
299
test8.flag.SetValue(true);
300
EXPECT_TRUE(test8.flag.GetValue());
301
EXPECT_TRUE(static_cast<bool>(test8.flag));
302
303
test8.flag.SetValue(false);
304
EXPECT_FALSE(test8.flag.GetValue());
305
EXPECT_FALSE(static_cast<bool>(test8.flag));
306
307
// Test that any non-zero value in the bit position is treated as true
308
test8.bits = 0x01;
309
EXPECT_TRUE(test8.flag.GetValue());
310
}
311
312
// Tests for signed BitFields with sign extension
313
TEST(BitField, SignedBitFields)
314
{
315
TestUnion32 test32{};
316
test32.bits = 0x00000000;
317
318
// Test positive signed values
319
test32.signed16bit.SetValue(12345);
320
EXPECT_EQ(test32.signed16bit.GetValue(), 12345);
321
322
// Test negative signed values
323
test32.signed16bit.SetValue(-12345);
324
EXPECT_EQ(test32.signed16bit.GetValue(), -12345);
325
326
// Test maximum positive value for 16-bit signed
327
test32.signed16bit.SetValue(32767);
328
EXPECT_EQ(test32.signed16bit.GetValue(), 32767);
329
330
// Test minimum negative value for 16-bit signed
331
test32.signed16bit.SetValue(-32768);
332
EXPECT_EQ(test32.signed16bit.GetValue(), -32768);
333
334
// Test sign extension with manual bit manipulation
335
test32.bits = 0xFFFF0000; // Set all bits in the signed field to 1
336
EXPECT_EQ(test32.signed16bit.GetValue(), -1);
337
}
338
339
// Tests for edge cases and boundary conditions
340
TEST(BitField, EdgeCases)
341
{
342
TestUnion64 test64{};
343
test64.bits = 0x0000000000000000ULL;
344
345
// Test maximum values
346
test64.value32bit.SetValue(0xFFFFFFFF);
347
EXPECT_EQ(test64.value32bit.GetValue(), 0xFFFFFFFFu);
348
349
test64.value31bit.SetValue(0x7FFFFFFF);
350
EXPECT_EQ(test64.value31bit.GetValue(), 0x7FFFFFFFu);
351
352
// Test that fields don't interfere with each other
353
test64.bits = 0x0000000000000000ULL;
354
test64.flag.SetValue(true);
355
test64.value32bit.SetValue(0x12345678);
356
test64.value31bit.SetValue(0x55555555);
357
358
EXPECT_TRUE(test64.flag.GetValue());
359
EXPECT_EQ(test64.value32bit.GetValue(), 0x12345678u);
360
EXPECT_EQ(test64.value31bit.GetValue(), 0x55555555u);
361
}
362
363
// Tests for arithmetic operations that may cause overflow
364
TEST(BitField, OverflowBehavior)
365
{
366
TestUnion8 test8{};
367
test8.bits = 0x00;
368
369
// Test 3-bit field (max value 7)
370
test8.value3bit.SetValue(7);
371
test8.value3bit += 1; // Should overflow
372
EXPECT_EQ(static_cast<u8>(test8.value3bit), 0);
373
374
test8.value3bit.SetValue(7);
375
test8.value3bit *= 2; // 7 * 2 = 14, should wrap to 6 (14 & 0x7)
376
EXPECT_EQ(static_cast<u8>(test8.value3bit), 6);
377
378
// Test underflow
379
test8.value3bit.SetValue(0);
380
test8.value3bit -= 1; // Should underflow
381
EXPECT_EQ(static_cast<u8>(test8.value3bit), 7);
382
}
383
384
// Tests for chaining operations
385
TEST(BitField, OperatorChaining)
386
{
387
TestUnion8 test8{};
388
test8.bits = 0x00;
389
390
// Test chaining assignment operators
391
auto& result = test8.value3bit = 5;
392
EXPECT_EQ(&result, &test8.value3bit);
393
EXPECT_EQ(static_cast<u8>(test8.value3bit), 5);
394
395
// Test chaining compound operators
396
auto& result2 = (test8.value3bit += 2);
397
EXPECT_EQ(&result2, &test8.value3bit);
398
EXPECT_EQ(static_cast<u8>(test8.value3bit), 7);
399
}
400
401
// Tests for static_assert conditions
402
TEST(BitField, StaticAssertions)
403
{
404
// These should compile without issues due to the static_assert in BitField
405
406
// Boolean fields should only be 1 bit
407
union TestBoolField
408
{
409
u8 bits;
410
BitField<u8, bool, 0, 1> valid_bool; // This should compile
411
};
412
413
// This would fail to compile:
414
// BitField<u8, bool, 0, 2> invalid_bool; // static_assert should trigger
415
416
TestBoolField test{};
417
test.bits = 0;
418
test.valid_bool = true;
419
EXPECT_TRUE(test.valid_bool);
420
}
421
422
template<typename T>
423
static inline constexpr unsigned ManualCountLeadingZeros(T value)
424
{
425
constexpr unsigned BITS = sizeof(T) * 8u;
426
constexpr T MASK = T(1) << (BITS - 1);
427
428
unsigned count = 0;
429
for (unsigned i = 0; i < BITS && (value & MASK) == 0; i++)
430
{
431
count++;
432
value <<= 1;
433
}
434
435
return count;
436
}
437
438
template<typename T>
439
static inline constexpr unsigned ManualCountTrailingZeros(T value)
440
{
441
constexpr unsigned BITS = sizeof(T) * 8u;
442
constexpr auto MASK = static_cast<std::make_unsigned_t<T>>(1);
443
444
auto u_value = static_cast<std::make_unsigned_t<T>>(value);
445
446
unsigned count = 0;
447
for (unsigned i = 0; i < BITS && (u_value & MASK) != MASK; i++)
448
{
449
count++;
450
u_value >>= 1;
451
}
452
453
return count;
454
}
455
456
TEST(BitUtils, Test8Bit)
457
{
458
ASSERT_EQ(CountLeadingZeros(u8(1)), ManualCountLeadingZeros(u8(1)));
459
ASSERT_EQ(CountLeadingZeros(u8(2)), ManualCountLeadingZeros(u8(2)));
460
ASSERT_EQ(CountLeadingZeros(u8(4)), ManualCountLeadingZeros(u8(4)));
461
ASSERT_EQ(CountLeadingZeros(u8(8)), ManualCountLeadingZeros(u8(8)));
462
ASSERT_EQ(CountLeadingZeros(u8(16)), ManualCountLeadingZeros(u8(16)));
463
ASSERT_EQ(CountLeadingZeros(u8(32)), ManualCountLeadingZeros(u8(32)));
464
ASSERT_EQ(CountLeadingZeros(u8(64)), ManualCountLeadingZeros(u8(64)));
465
ASSERT_EQ(CountLeadingZeros(u8(128)), ManualCountLeadingZeros(u8(128)));
466
467
ASSERT_EQ(CountTrailingZeros(u8(1)), ManualCountTrailingZeros(u8(1)));
468
ASSERT_EQ(CountTrailingZeros(u8(2)), ManualCountTrailingZeros(u8(2)));
469
ASSERT_EQ(CountTrailingZeros(u8(4)), ManualCountTrailingZeros(u8(4)));
470
ASSERT_EQ(CountTrailingZeros(u8(8)), ManualCountTrailingZeros(u8(8)));
471
ASSERT_EQ(CountTrailingZeros(u8(16)), ManualCountTrailingZeros(u8(16)));
472
ASSERT_EQ(CountTrailingZeros(u8(32)), ManualCountTrailingZeros(u8(32)));
473
ASSERT_EQ(CountTrailingZeros(u8(64)), ManualCountTrailingZeros(u8(64)));
474
ASSERT_EQ(CountTrailingZeros(u8(128)), ManualCountTrailingZeros(u8(128)));
475
}
476
477
TEST(BitUtils, Test16Bit)
478
{
479
for (u32 i = 1; i < 0x10000; i++)
480
{
481
u16 value = Truncate16(i);
482
ASSERT_EQ(CountLeadingZeros(value), ManualCountLeadingZeros(value));
483
ASSERT_EQ(CountTrailingZeros(value), ManualCountTrailingZeros(value));
484
}
485
}
486
487
TEST(BitUtils, ZeroExtendHelpers)
488
{
489
EXPECT_EQ(ZeroExtend16(u8(0xFF)), 0x00FFu);
490
EXPECT_EQ(ZeroExtend32(u16(0xFFFF)), 0x0000FFFFu);
491
EXPECT_EQ(ZeroExtend64(u32(0xFFFFFFFF)), 0x00000000FFFFFFFFull);
492
}
493
494
TEST(BitUtils, SignExtendHelpers)
495
{
496
EXPECT_EQ(SignExtend16(s8(-1)), 0xFFFFu);
497
EXPECT_EQ(SignExtend32(s16(-1)), 0xFFFFFFFFu);
498
EXPECT_EQ(SignExtend64(s32(-1)), 0xFFFFFFFFFFFFFFFFull);
499
}
500
501
TEST(BitUtils, TruncateHelpers)
502
{
503
EXPECT_EQ(Truncate8(u16(0x1234)), 0x34u);
504
EXPECT_EQ(Truncate16(u32(0x12345678)), 0x5678u);
505
EXPECT_EQ(Truncate32(u64(0x123456789ABCDEF0)), 0x9ABCDEF0u);
506
}
507
508
TEST(BitUtils, BinaryToBCD)
509
{
510
EXPECT_EQ(BinaryToBCD(0), 0x00u);
511
EXPECT_EQ(BinaryToBCD(9), 0x09u);
512
EXPECT_EQ(BinaryToBCD(12), 0x12u);
513
EXPECT_EQ(BinaryToBCD(99), 0x99u);
514
}
515
516
TEST(BitUtils, PackedBCDToBinary)
517
{
518
EXPECT_EQ(PackedBCDToBinary(0x00), 0);
519
EXPECT_EQ(PackedBCDToBinary(0x09), 9);
520
EXPECT_EQ(PackedBCDToBinary(0x12), 12);
521
EXPECT_EQ(PackedBCDToBinary(0x99), 99);
522
}
523
524
TEST(BitUtils, IsValidBCDDigit)
525
{
526
for (u8 i = 0; i < 10; ++i)
527
EXPECT_TRUE(IsValidBCDDigit(i));
528
for (u8 i = 10; i < 16; ++i)
529
EXPECT_FALSE(IsValidBCDDigit(i));
530
}
531
532
TEST(BitUtils, IsValidPackedBCD)
533
{
534
EXPECT_TRUE(IsValidPackedBCD(0x12));
535
EXPECT_TRUE(IsValidPackedBCD(0x99));
536
EXPECT_FALSE(IsValidPackedBCD(0x1A));
537
EXPECT_FALSE(IsValidPackedBCD(0xA1));
538
}
539
540
TEST(BitUtils, BoolToUInt)
541
{
542
EXPECT_EQ(BoolToUInt8(true), 1u);
543
EXPECT_EQ(BoolToUInt8(false), 0u);
544
EXPECT_EQ(BoolToUInt16(true), 1u);
545
EXPECT_EQ(BoolToUInt32(false), 0u);
546
EXPECT_EQ(BoolToUInt64(true), 1ull);
547
EXPECT_FLOAT_EQ(BoolToFloat(true), 1.0f);
548
EXPECT_FLOAT_EQ(BoolToFloat(false), 0.0f);
549
}
550
551
TEST(BitUtils, ConvertToBool)
552
{
553
EXPECT_TRUE(ConvertToBool(1));
554
EXPECT_FALSE(ConvertToBool(0));
555
EXPECT_TRUE(ConvertToBool(-1));
556
EXPECT_TRUE(ConvertToBool(123));
557
}
558
559
TEST(BitUtils, ConvertToBoolUnchecked)
560
{
561
u8 one = 1, zero = 0;
562
EXPECT_TRUE(ConvertToBoolUnchecked(one));
563
EXPECT_FALSE(ConvertToBoolUnchecked(zero));
564
}
565
566
TEST(BitUtils, SignExtendN)
567
{
568
EXPECT_EQ(SignExtendN<4>(0b0111), 7);
569
EXPECT_EQ(SignExtendN<4>(0b1000), -8);
570
EXPECT_EQ(SignExtendN<8>(0xFF), -1);
571
EXPECT_EQ(SignExtendN<12>(0x800), -2048);
572
}
573
574
TEST(BitUtils, CountLeadingZeros)
575
{
576
EXPECT_EQ(CountLeadingZeros<u8>(0b00010000), 3u);
577
EXPECT_EQ(CountLeadingZeros<u16>(0x0001), 15u);
578
EXPECT_EQ(CountLeadingZeros<u32>(0x80000000), 0u);
579
EXPECT_EQ(CountLeadingZeros<u64>(0x0000000100000000ull), 31u);
580
}
581
582
TEST(BitUtils, CountTrailingZeros)
583
{
584
EXPECT_EQ(CountTrailingZeros<u8>(0b10000000), 7u);
585
EXPECT_EQ(CountTrailingZeros<u16>(0x8000), 15u);
586
EXPECT_EQ(CountTrailingZeros<u32>(0x00010000), 16u);
587
EXPECT_EQ(CountTrailingZeros<u64>(0x0000000100000000ull), 32u);
588
}
589
590
TEST(BitUtils, ByteSwap)
591
{
592
EXPECT_EQ(ByteSwap<u16>(0x1234), 0x3412u);
593
EXPECT_EQ(ByteSwap<u32>(0x12345678), 0x78563412u);
594
EXPECT_EQ(ByteSwap<u64>(0x0123456789ABCDEFull), 0xEFCDAB8967452301ull);
595
EXPECT_EQ(ByteSwap<s16>(s16(0x1234)), s16(0x3412));
596
EXPECT_EQ(ByteSwap<s32>(s32(0x12345678)), s32(0x78563412));
597
EXPECT_EQ(ByteSwap<s64>(s64(0x0123456789ABCDEFll)), s64(0xEFCDAB8967452301ll));
598
}
599
600
// Alignment function tests
601
TEST(Align, IsAligned)
602
{
603
// Test with various integer types and alignments
604
EXPECT_TRUE(Common::IsAligned(0u, 4u));
605
EXPECT_TRUE(Common::IsAligned(4u, 4u));
606
EXPECT_TRUE(Common::IsAligned(8u, 4u));
607
EXPECT_TRUE(Common::IsAligned(16u, 4u));
608
EXPECT_FALSE(Common::IsAligned(1u, 4u));
609
EXPECT_FALSE(Common::IsAligned(3u, 4u));
610
EXPECT_FALSE(Common::IsAligned(5u, 4u));
611
612
// Test with pointer types
613
EXPECT_TRUE(Common::IsAligned(reinterpret_cast<uintptr_t>(nullptr), 8u));
614
EXPECT_TRUE(Common::IsAligned(0x1000ull, 16u));
615
EXPECT_FALSE(Common::IsAligned(0x1001ull, 16u));
616
617
// Test with different alignments
618
EXPECT_TRUE(Common::IsAligned(15u, 1u));
619
EXPECT_TRUE(Common::IsAligned(16u, 8u));
620
EXPECT_FALSE(Common::IsAligned(15u, 8u));
621
}
622
623
TEST(Align, AlignUp)
624
{
625
// Test basic alignment up
626
EXPECT_EQ(Common::AlignUp(0u, 4u), 0u);
627
EXPECT_EQ(Common::AlignUp(1u, 4u), 4u);
628
EXPECT_EQ(Common::AlignUp(3u, 4u), 4u);
629
EXPECT_EQ(Common::AlignUp(4u, 4u), 4u);
630
EXPECT_EQ(Common::AlignUp(5u, 4u), 8u);
631
EXPECT_EQ(Common::AlignUp(7u, 4u), 8u);
632
EXPECT_EQ(Common::AlignUp(8u, 4u), 8u);
633
634
// Test with larger values
635
EXPECT_EQ(Common::AlignUp(1000u, 64u), 1024u);
636
EXPECT_EQ(Common::AlignUp(1024u, 64u), 1024u);
637
EXPECT_EQ(Common::AlignUp(1025u, 64u), 1088u);
638
639
// Test with different types
640
EXPECT_EQ(Common::AlignUp(13ull, 8u), 16ull);
641
EXPECT_EQ(Common::AlignUp(size_t(100), 16u), size_t(112));
642
}
643
644
TEST(Align, AlignDown)
645
{
646
// Test basic alignment down
647
EXPECT_EQ(Common::AlignDown(0u, 4u), 0u);
648
EXPECT_EQ(Common::AlignDown(1u, 4u), 0u);
649
EXPECT_EQ(Common::AlignDown(3u, 4u), 0u);
650
EXPECT_EQ(Common::AlignDown(4u, 4u), 4u);
651
EXPECT_EQ(Common::AlignDown(5u, 4u), 4u);
652
EXPECT_EQ(Common::AlignDown(7u, 4u), 4u);
653
EXPECT_EQ(Common::AlignDown(8u, 4u), 8u);
654
655
// Test with larger values
656
EXPECT_EQ(Common::AlignDown(1000u, 64u), 960u);
657
EXPECT_EQ(Common::AlignDown(1024u, 64u), 1024u);
658
EXPECT_EQ(Common::AlignDown(1087u, 64u), 1024u);
659
660
// Test with different types
661
EXPECT_EQ(Common::AlignDown(13ull, 8u), 8ull);
662
EXPECT_EQ(Common::AlignDown(size_t(100), 16u), size_t(96));
663
}
664
665
TEST(Align, IsAlignedPow2)
666
{
667
// Test power-of-2 alignment checks
668
EXPECT_TRUE(Common::IsAlignedPow2(0u, 4u));
669
EXPECT_TRUE(Common::IsAlignedPow2(4u, 4u));
670
EXPECT_TRUE(Common::IsAlignedPow2(8u, 4u));
671
EXPECT_TRUE(Common::IsAlignedPow2(16u, 4u));
672
EXPECT_FALSE(Common::IsAlignedPow2(1u, 4u));
673
EXPECT_FALSE(Common::IsAlignedPow2(3u, 4u));
674
EXPECT_FALSE(Common::IsAlignedPow2(5u, 4u));
675
676
// Test with different power-of-2 alignments
677
EXPECT_TRUE(Common::IsAlignedPow2(32u, 16u));
678
EXPECT_TRUE(Common::IsAlignedPow2(64u, 16u));
679
EXPECT_TRUE(Common::IsAlignedPow2(48u, 16u));
680
EXPECT_FALSE(Common::IsAlignedPow2(56u, 16u));
681
EXPECT_FALSE(Common::IsAlignedPow2(63u, 16u));
682
683
// Test with larger values
684
EXPECT_TRUE(Common::IsAlignedPow2(1024u, 256u));
685
EXPECT_TRUE(Common::IsAlignedPow2(1280u, 256u));
686
EXPECT_FALSE(Common::IsAlignedPow2(1100u, 256u));
687
}
688
689
TEST(Align, AlignUpPow2)
690
{
691
// Test power-of-2 alignment up
692
EXPECT_EQ(Common::AlignUpPow2(0u, 4u), 0u);
693
EXPECT_EQ(Common::AlignUpPow2(1u, 4u), 4u);
694
EXPECT_EQ(Common::AlignUpPow2(3u, 4u), 4u);
695
EXPECT_EQ(Common::AlignUpPow2(4u, 4u), 4u);
696
EXPECT_EQ(Common::AlignUpPow2(5u, 4u), 8u);
697
EXPECT_EQ(Common::AlignUpPow2(7u, 4u), 8u);
698
EXPECT_EQ(Common::AlignUpPow2(8u, 4u), 8u);
699
700
// Test with larger power-of-2 alignments
701
EXPECT_EQ(Common::AlignUpPow2(1000u, 64u), 1024u);
702
EXPECT_EQ(Common::AlignUpPow2(1024u, 64u), 1024u);
703
EXPECT_EQ(Common::AlignUpPow2(1025u, 64u), 1088u);
704
705
// Test with different types
706
EXPECT_EQ(Common::AlignUpPow2(13ull, 8u), 16ull);
707
EXPECT_EQ(Common::AlignUpPow2(size_t(100), 16u), size_t(112));
708
}
709
710
TEST(Align, AlignDownPow2)
711
{
712
// Test power-of-2 alignment down
713
EXPECT_EQ(Common::AlignDownPow2(0u, 4u), 0u);
714
EXPECT_EQ(Common::AlignDownPow2(1u, 4u), 0u);
715
EXPECT_EQ(Common::AlignDownPow2(3u, 4u), 0u);
716
EXPECT_EQ(Common::AlignDownPow2(4u, 4u), 4u);
717
EXPECT_EQ(Common::AlignDownPow2(5u, 4u), 4u);
718
EXPECT_EQ(Common::AlignDownPow2(7u, 4u), 4u);
719
EXPECT_EQ(Common::AlignDownPow2(8u, 4u), 8u);
720
721
// Test with larger power-of-2 alignments
722
EXPECT_EQ(Common::AlignDownPow2(1000u, 64u), 960u);
723
EXPECT_EQ(Common::AlignDownPow2(1024u, 64u), 1024u);
724
EXPECT_EQ(Common::AlignDownPow2(1087u, 64u), 1024u);
725
726
// Test with different types
727
EXPECT_EQ(Common::AlignDownPow2(13ull, 8u), 8ull);
728
EXPECT_EQ(Common::AlignDownPow2(size_t(100), 16u), size_t(96));
729
}
730
731
TEST(Align, IsPow2)
732
{
733
// Test power-of-2 detection
734
EXPECT_TRUE(Common::IsPow2(0u));
735
EXPECT_TRUE(Common::IsPow2(1u));
736
EXPECT_TRUE(Common::IsPow2(2u));
737
EXPECT_TRUE(Common::IsPow2(4u));
738
EXPECT_TRUE(Common::IsPow2(8u));
739
EXPECT_TRUE(Common::IsPow2(16u));
740
EXPECT_TRUE(Common::IsPow2(32u));
741
EXPECT_TRUE(Common::IsPow2(64u));
742
EXPECT_TRUE(Common::IsPow2(128u));
743
EXPECT_TRUE(Common::IsPow2(256u));
744
EXPECT_TRUE(Common::IsPow2(1024u));
745
746
// Test non-power-of-2 values
747
EXPECT_FALSE(Common::IsPow2(3u));
748
EXPECT_FALSE(Common::IsPow2(5u));
749
EXPECT_FALSE(Common::IsPow2(6u));
750
EXPECT_FALSE(Common::IsPow2(7u));
751
EXPECT_FALSE(Common::IsPow2(9u));
752
EXPECT_FALSE(Common::IsPow2(15u));
753
EXPECT_FALSE(Common::IsPow2(31u));
754
EXPECT_FALSE(Common::IsPow2(1000u));
755
756
// Test with different types
757
EXPECT_TRUE(Common::IsPow2(512ull));
758
EXPECT_FALSE(Common::IsPow2(513ull));
759
}
760
761
TEST(Align, PreviousPow2)
762
{
763
// Test finding previous power-of-2
764
EXPECT_EQ(Common::PreviousPow2(1u), 1u);
765
EXPECT_EQ(Common::PreviousPow2(2u), 2u);
766
EXPECT_EQ(Common::PreviousPow2(3u), 2u);
767
EXPECT_EQ(Common::PreviousPow2(4u), 4u);
768
EXPECT_EQ(Common::PreviousPow2(5u), 4u);
769
EXPECT_EQ(Common::PreviousPow2(6u), 4u);
770
EXPECT_EQ(Common::PreviousPow2(7u), 4u);
771
EXPECT_EQ(Common::PreviousPow2(8u), 8u);
772
EXPECT_EQ(Common::PreviousPow2(15u), 8u);
773
EXPECT_EQ(Common::PreviousPow2(16u), 16u);
774
EXPECT_EQ(Common::PreviousPow2(31u), 16u);
775
EXPECT_EQ(Common::PreviousPow2(32u), 32u);
776
EXPECT_EQ(Common::PreviousPow2(1000u), 512u);
777
EXPECT_EQ(Common::PreviousPow2(1024u), 1024u);
778
779
// Test with different types
780
EXPECT_EQ(Common::PreviousPow2(100ull), 64ull);
781
EXPECT_EQ(Common::PreviousPow2(static_cast<size_t>(2047)), static_cast<size_t>(1024));
782
EXPECT_EQ(Common::PreviousPow2(static_cast<size_t>(2048)), static_cast<size_t>(2048));
783
}
784
785
TEST(Align, NextPow2)
786
{
787
// Test finding next power-of-2
788
EXPECT_EQ(Common::NextPow2(0u), 0u);
789
EXPECT_EQ(Common::NextPow2(1u), 1u);
790
EXPECT_EQ(Common::NextPow2(2u), 2u);
791
EXPECT_EQ(Common::NextPow2(3u), 4u);
792
EXPECT_EQ(Common::NextPow2(4u), 4u);
793
EXPECT_EQ(Common::NextPow2(5u), 8u);
794
EXPECT_EQ(Common::NextPow2(7u), 8u);
795
EXPECT_EQ(Common::NextPow2(8u), 8u);
796
EXPECT_EQ(Common::NextPow2(9u), 16u);
797
EXPECT_EQ(Common::NextPow2(15u), 16u);
798
EXPECT_EQ(Common::NextPow2(16u), 16u);
799
EXPECT_EQ(Common::NextPow2(17u), 32u);
800
EXPECT_EQ(Common::NextPow2(1000u), 1024u);
801
EXPECT_EQ(Common::NextPow2(1024u), 1024u);
802
803
// Test with different types
804
EXPECT_EQ(Common::NextPow2(100ull), 128ull);
805
EXPECT_EQ(Common::NextPow2(size_t(1025)), size_t(2048));
806
}
807
808
TEST(Align, AlignedMallocAndFree)
809
{
810
// Test aligned memory allocation and deallocation
811
void* ptr1 = Common::AlignedMalloc(128, 16);
812
ASSERT_NE(ptr1, nullptr);
813
EXPECT_TRUE(Common::IsAlignedPow2(reinterpret_cast<uintptr_t>(ptr1), 16u));
814
Common::AlignedFree(ptr1);
815
816
void* ptr2 = Common::AlignedMalloc(256, 32);
817
ASSERT_NE(ptr2, nullptr);
818
EXPECT_TRUE(Common::IsAlignedPow2(reinterpret_cast<uintptr_t>(ptr2), 32u));
819
Common::AlignedFree(ptr2);
820
821
void* ptr3 = Common::AlignedMalloc(1024, 64);
822
ASSERT_NE(ptr3, nullptr);
823
EXPECT_TRUE(Common::IsAlignedPow2(reinterpret_cast<uintptr_t>(ptr3), 64u));
824
Common::AlignedFree(ptr3);
825
826
// Test with zero size (implementation-defined behavior)
827
void* ptr4 = Common::AlignedMalloc(0, 16);
828
Common::AlignedFree(ptr4); // Should not crash even if ptr4 is nullptr
829
830
// Test AlignedFree with nullptr (should not crash)
831
Common::AlignedFree(nullptr);
832
}
833
834
TEST(Align, UniqueAlignedPtr)
835
{
836
// Test make_unique_aligned for arrays
837
auto ptr1 = Common::make_unique_aligned<int[]>(16, 10);
838
ASSERT_NE(ptr1.get(), nullptr);
839
EXPECT_TRUE(Common::IsAlignedPow2(reinterpret_cast<uintptr_t>(ptr1.get()), 16u));
840
841
// Test that we can write to the memory
842
for (int i = 0; i < 10; ++i)
843
{
844
ptr1[i] = i * 2;
845
}
846
for (int i = 0; i < 10; ++i)
847
{
848
EXPECT_EQ(ptr1[i], i * 2);
849
}
850
851
auto ptr2 = Common::make_unique_aligned<u8[]>(32, 100);
852
ASSERT_NE(ptr2.get(), nullptr);
853
EXPECT_TRUE(Common::IsAlignedPow2(reinterpret_cast<uintptr_t>(ptr2.get()), 32u));
854
855
// Test make_unique_aligned_for_overwrite
856
auto ptr3 = Common::make_unique_aligned_for_overwrite<u32[]>(64, 50);
857
ASSERT_NE(ptr3.get(), nullptr);
858
EXPECT_TRUE(Common::IsAlignedPow2(reinterpret_cast<uintptr_t>(ptr3.get()), 64u));
859
860
// Test that we can write to the memory
861
for (u32 i = 0; i < 50; ++i)
862
{
863
ptr3[i] = i + 1000;
864
}
865
for (u32 i = 0; i < 50; ++i)
866
{
867
EXPECT_EQ(ptr3[i], i + 1000);
868
}
869
}
870