]>
Commit | Line | Data |
---|---|---|
9b0a0ba9 OZ |
1 | /* |
2 | * BIRD Library -- Generic Bit Operations Tests | |
3 | * | |
4 | * (c) 2015 CZ.NIC z.s.p.o. | |
5 | * | |
6 | * Can be freely distributed and used under the terms of the GNU GPL. | |
7 | */ | |
8 | ||
9 | #include "test/birdtest.h" | |
10 | #include "test/bt-utils.h" /* naive_pow() */ | |
11 | ||
12 | #include "lib/bitops.h" | |
13 | ||
14 | #define MAX_NUM 1000 | |
15 | #define CHECK_BIT(var,pos) ((var) & (u32)(1<<(pos))) | |
16 | ||
17 | static int | |
18 | t_mkmask(void) | |
19 | { | |
20 | int i; | |
21 | u32 compute, expect; | |
22 | ||
23 | bt_assert(u32_mkmask(0) == 0x00000000); | |
24 | for (i = 1; i <= 32; i++) | |
25 | { | |
26 | compute = u32_mkmask(i); | |
27 | expect = (u32) (0xffffffff << (32-i)); | |
28 | bt_assert_msg(compute == expect, "u32_mkmask(%d) = 0x%08X, expected 0x%08X", i, compute, expect); | |
29 | } | |
30 | ||
5e3cd0e5 | 31 | return 1; |
9b0a0ba9 OZ |
32 | } |
33 | ||
34 | static int | |
35 | u32_masklen_expected(u32 mask) | |
36 | { | |
37 | int j, expect = 0; | |
38 | ||
39 | int valid = 0; | |
40 | for (j = 0; j <= 32; j++) | |
41 | if (mask == (j ? (0xffffffff << (32-j)) : 0)) /* Shifting 32-bit value by 32 bits is undefined behavior */ | |
42 | valid = 1; | |
43 | ||
44 | if (!valid && mask != 0) | |
45 | expect = 255; | |
46 | else | |
47 | for (j = 0; j <= 31; j++) | |
48 | if (CHECK_BIT(mask, (31-j))) | |
49 | expect = j+1; | |
50 | else | |
51 | break; | |
52 | return expect; | |
53 | } | |
54 | ||
55 | static void | |
56 | check_mask(u32 mask) | |
57 | { | |
58 | int expected, masklen; | |
59 | ||
60 | expected = u32_masklen_expected(mask); | |
61 | masklen = u32_masklen(mask); | |
62 | int ok = (expected == masklen); | |
63 | bt_debug("u32_masklen(Ox%08x) = %d, expected %d %s\n", mask, masklen, expected, ok ? "OK" : "FAIL!"); | |
64 | bt_assert(ok); | |
65 | } | |
66 | ||
67 | static int | |
68 | t_masklen(void) | |
69 | { | |
70 | u32 i; | |
71 | ||
72 | check_mask(0x82828282); | |
73 | check_mask(0x00000000); | |
74 | ||
75 | for (i = 0; i <= 32; i++) | |
76 | check_mask(((u32) (i ? (0xffffffff << (32-i)) : 0)) & 0xffffffff); /* Shifting 32-bit value by 32 bits is undefined behavior */ | |
77 | ||
78 | for (i = 0; i <= MAX_NUM; i++) | |
79 | check_mask(bt_random()); | |
80 | ||
5e3cd0e5 | 81 | return 1; |
9b0a0ba9 OZ |
82 | } |
83 | ||
84 | static void | |
85 | check_log2(u32 n) | |
86 | { | |
87 | u32 log = u32_log2(n); | |
88 | u32 low = bt_naive_pow(2, log); | |
89 | u32 high = bt_naive_pow(2, log+1); | |
90 | ||
91 | bt_assert_msg(n >= low && n < high, | |
92 | "u32_log2(%u) = %u, %u should be in the range <%u, %u)", | |
93 | n, log, n, low, high); | |
94 | } | |
95 | ||
96 | static int | |
97 | t_log2(void) | |
98 | { | |
99 | u32 i; | |
100 | ||
101 | for (i = 0; i < 31; i++) | |
102 | bt_assert(u32_log2(bt_naive_pow(2, i+1)) == i+1); | |
103 | ||
104 | for (i = 1; i < MAX_NUM; i++) | |
105 | check_log2(i); | |
106 | ||
107 | for (i = 1; i < MAX_NUM; i++) | |
108 | check_log2(((u32) bt_random()) % 0x0fffffff); | |
109 | ||
5e3cd0e5 | 110 | return 1; |
9b0a0ba9 OZ |
111 | } |
112 | ||
113 | int | |
114 | main(int argc, char *argv[]) | |
115 | { | |
116 | bt_init(argc, argv); | |
117 | ||
118 | bt_test_suite(t_mkmask, "u32_mkmask()"); | |
119 | bt_test_suite(t_masklen, "u32_masklen()"); | |
120 | bt_test_suite(t_log2, "u32_log2()"); | |
121 | ||
122 | return bt_exit_value(); | |
123 | } |