]>
Commit | Line | Data |
---|---|---|
0e2dc70e JB |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * Test cases for bitfield helpers. | |
4 | */ | |
5 | ||
6 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
7 | ||
d2585f51 | 8 | #include <kunit/test.h> |
0e2dc70e JB |
9 | #include <linux/bitfield.h> |
10 | ||
11 | #define CHECK_ENC_GET_U(tp, v, field, res) do { \ | |
12 | { \ | |
13 | u##tp _res; \ | |
14 | \ | |
15 | _res = u##tp##_encode_bits(v, field); \ | |
d2585f51 VMI |
16 | KUNIT_ASSERT_FALSE_MSG(context, _res != res, \ |
17 | "u" #tp "_encode_bits(" #v ", " #field ") is 0x%llx != " #res "\n", \ | |
18 | (u64)_res); \ | |
19 | KUNIT_ASSERT_FALSE(context, \ | |
20 | u##tp##_get_bits(_res, field) != v); \ | |
0e2dc70e JB |
21 | } \ |
22 | } while (0) | |
23 | ||
24 | #define CHECK_ENC_GET_LE(tp, v, field, res) do { \ | |
25 | { \ | |
26 | __le##tp _res; \ | |
27 | \ | |
28 | _res = le##tp##_encode_bits(v, field); \ | |
d2585f51 VMI |
29 | KUNIT_ASSERT_FALSE_MSG(context, \ |
30 | _res != cpu_to_le##tp(res), \ | |
31 | "le" #tp "_encode_bits(" #v ", " #field ") is 0x%llx != 0x%llx",\ | |
32 | (u64)le##tp##_to_cpu(_res), \ | |
33 | (u64)(res)); \ | |
34 | KUNIT_ASSERT_FALSE(context, \ | |
35 | le##tp##_get_bits(_res, field) != v);\ | |
0e2dc70e JB |
36 | } \ |
37 | } while (0) | |
38 | ||
39 | #define CHECK_ENC_GET_BE(tp, v, field, res) do { \ | |
40 | { \ | |
41 | __be##tp _res; \ | |
42 | \ | |
43 | _res = be##tp##_encode_bits(v, field); \ | |
d2585f51 VMI |
44 | KUNIT_ASSERT_FALSE_MSG(context, \ |
45 | _res != cpu_to_be##tp(res), \ | |
46 | "be" #tp "_encode_bits(" #v ", " #field ") is 0x%llx != 0x%llx", \ | |
47 | (u64)be##tp##_to_cpu(_res), \ | |
48 | (u64)(res)); \ | |
49 | KUNIT_ASSERT_FALSE(context, \ | |
50 | be##tp##_get_bits(_res, field) != v);\ | |
0e2dc70e JB |
51 | } \ |
52 | } while (0) | |
53 | ||
54 | #define CHECK_ENC_GET(tp, v, field, res) do { \ | |
55 | CHECK_ENC_GET_U(tp, v, field, res); \ | |
56 | CHECK_ENC_GET_LE(tp, v, field, res); \ | |
57 | CHECK_ENC_GET_BE(tp, v, field, res); \ | |
58 | } while (0) | |
59 | ||
d2585f51 | 60 | static void __init test_bitfields_constants(struct kunit *context) |
0e2dc70e JB |
61 | { |
62 | /* | |
63 | * NOTE | |
64 | * This whole function compiles (or at least should, if everything | |
65 | * is going according to plan) to nothing after optimisation. | |
66 | */ | |
67 | ||
68 | CHECK_ENC_GET(16, 1, 0x000f, 0x0001); | |
69 | CHECK_ENC_GET(16, 3, 0x00f0, 0x0030); | |
70 | CHECK_ENC_GET(16, 5, 0x0f00, 0x0500); | |
71 | CHECK_ENC_GET(16, 7, 0xf000, 0x7000); | |
72 | CHECK_ENC_GET(16, 14, 0x000f, 0x000e); | |
73 | CHECK_ENC_GET(16, 15, 0x00f0, 0x00f0); | |
74 | ||
75 | CHECK_ENC_GET_U(8, 1, 0x0f, 0x01); | |
76 | CHECK_ENC_GET_U(8, 3, 0xf0, 0x30); | |
77 | CHECK_ENC_GET_U(8, 14, 0x0f, 0x0e); | |
78 | CHECK_ENC_GET_U(8, 15, 0xf0, 0xf0); | |
79 | ||
80 | CHECK_ENC_GET(32, 1, 0x00000f00, 0x00000100); | |
81 | CHECK_ENC_GET(32, 3, 0x0000f000, 0x00003000); | |
82 | CHECK_ENC_GET(32, 5, 0x000f0000, 0x00050000); | |
83 | CHECK_ENC_GET(32, 7, 0x00f00000, 0x00700000); | |
84 | CHECK_ENC_GET(32, 14, 0x0f000000, 0x0e000000); | |
85 | CHECK_ENC_GET(32, 15, 0xf0000000, 0xf0000000); | |
86 | ||
87 | CHECK_ENC_GET(64, 1, 0x00000f0000000000ull, 0x0000010000000000ull); | |
88 | CHECK_ENC_GET(64, 3, 0x0000f00000000000ull, 0x0000300000000000ull); | |
89 | CHECK_ENC_GET(64, 5, 0x000f000000000000ull, 0x0005000000000000ull); | |
90 | CHECK_ENC_GET(64, 7, 0x00f0000000000000ull, 0x0070000000000000ull); | |
91 | CHECK_ENC_GET(64, 14, 0x0f00000000000000ull, 0x0e00000000000000ull); | |
92 | CHECK_ENC_GET(64, 15, 0xf000000000000000ull, 0xf000000000000000ull); | |
0e2dc70e JB |
93 | } |
94 | ||
95 | #define CHECK(tp, mask) do { \ | |
96 | u64 v; \ | |
97 | \ | |
98 | for (v = 0; v < 1 << hweight32(mask); v++) \ | |
d2585f51 VMI |
99 | KUNIT_ASSERT_FALSE(context, \ |
100 | tp##_encode_bits(v, mask) != v << __ffs64(mask));\ | |
0e2dc70e JB |
101 | } while (0) |
102 | ||
d2585f51 | 103 | static void __init test_bitfields_variables(struct kunit *context) |
0e2dc70e JB |
104 | { |
105 | CHECK(u8, 0x0f); | |
106 | CHECK(u8, 0xf0); | |
107 | CHECK(u8, 0x38); | |
108 | ||
109 | CHECK(u16, 0x0038); | |
110 | CHECK(u16, 0x0380); | |
111 | CHECK(u16, 0x3800); | |
112 | CHECK(u16, 0x8000); | |
113 | ||
114 | CHECK(u32, 0x80000000); | |
115 | CHECK(u32, 0x7f000000); | |
116 | CHECK(u32, 0x07e00000); | |
117 | CHECK(u32, 0x00018000); | |
118 | ||
119 | CHECK(u64, 0x8000000000000000ull); | |
120 | CHECK(u64, 0x7f00000000000000ull); | |
121 | CHECK(u64, 0x0001800000000000ull); | |
122 | CHECK(u64, 0x0000000080000000ull); | |
123 | CHECK(u64, 0x000000007f000000ull); | |
124 | CHECK(u64, 0x0000000018000000ull); | |
125 | CHECK(u64, 0x0000001f8000000ull); | |
0e2dc70e JB |
126 | } |
127 | ||
294a7f16 | 128 | #ifdef TEST_BITFIELD_COMPILE |
d2585f51 VMI |
129 | static void __init test_bitfields_compile(struct kunit *context) |
130 | { | |
0e2dc70e JB |
131 | /* these should fail compilation */ |
132 | CHECK_ENC_GET(16, 16, 0x0f00, 0x1000); | |
133 | u32_encode_bits(7, 0x06000000); | |
134 | ||
135 | /* this should at least give a warning */ | |
136 | u16_encode_bits(0, 0x60000); | |
d2585f51 | 137 | } |
294a7f16 | 138 | #endif |
d2585f51 VMI |
139 | |
140 | static struct kunit_case __refdata bitfields_test_cases[] = { | |
141 | KUNIT_CASE(test_bitfields_constants), | |
142 | KUNIT_CASE(test_bitfields_variables), | |
d2585f51 VMI |
143 | {} |
144 | }; | |
0e2dc70e | 145 | |
d2585f51 VMI |
146 | static struct kunit_suite bitfields_test_suite = { |
147 | .name = "bitfields", | |
148 | .test_cases = bitfields_test_cases, | |
149 | }; | |
0e2dc70e | 150 | |
d2585f51 | 151 | kunit_test_suites(&bitfields_test_suite); |
0e2dc70e JB |
152 | |
153 | MODULE_AUTHOR("Johannes Berg <[email protected]>"); | |
154 | MODULE_LICENSE("GPL"); |