1/*
2 * Copyright (c) 2019 Facebook
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#include <zephyr/ztest.h>
8#include <zephyr/sys/math_extras.h>
9#include <inttypes.h>
10
11static void VNAME(u32_add)(void)
12{
13	uint32_t result = 42;
14
15	zassert_false(u32_add_overflow(2, 3, &result));
16	zassert_equal(result, 5);
17
18	zassert_false(u32_add_overflow(2, 0, &result));
19	zassert_equal(result, 2);
20
21	zassert_false(u32_add_overflow(0, 3, &result));
22	zassert_equal(result, 3);
23
24	zassert_false(u32_add_overflow(0, UINT32_MAX, &result));
25	zassert_equal(result, UINT32_MAX);
26	zassert_true(u32_add_overflow(1, UINT32_MAX, &result));
27	zassert_equal(result, 0);
28
29	zassert_false(u32_add_overflow(UINT32_MAX, 0, &result));
30	zassert_equal(result, UINT32_MAX);
31	zassert_true(u32_add_overflow(UINT32_MAX, 2, &result));
32	zassert_equal(result, 1);
33}
34
35static void VNAME(u32_mul)(void)
36{
37	uint32_t result = 42;
38
39	zassert_false(u32_mul_overflow(2, 3, &result));
40	zassert_equal(result, 6);
41
42	zassert_false(u32_mul_overflow(UINT32_MAX, 1, &result));
43	zassert_equal(result, UINT32_MAX);
44	zassert_true(u32_mul_overflow(UINT32_MAX, 2, &result));
45	zassert_equal(result, UINT32_MAX * 2);
46
47	zassert_false(u32_mul_overflow(1, UINT32_MAX, &result));
48	zassert_equal(result, UINT32_MAX);
49	zassert_true(u32_mul_overflow(2, UINT32_MAX, &result));
50	zassert_equal(result, UINT32_MAX * 2);
51}
52
53static void VNAME(u64_add)(void)
54{
55	uint64_t result = 42;
56
57	zassert_false(u64_add_overflow(2, 3, &result));
58	zassert_equal(result, 5);
59
60	zassert_false(u64_add_overflow(2, 0, &result));
61	zassert_equal(result, 2);
62
63	zassert_false(u64_add_overflow(0, 3, &result));
64	zassert_equal(result, 3);
65
66	zassert_false(u64_add_overflow(0, UINT64_MAX, &result));
67	zassert_equal(result, UINT64_MAX);
68	zassert_true(u64_add_overflow(1, UINT64_MAX, &result));
69	zassert_equal(result, 0);
70
71	zassert_false(u64_add_overflow(UINT64_MAX, 0, &result));
72	zassert_equal(result, UINT64_MAX);
73	zassert_true(u64_add_overflow(UINT64_MAX, 2, &result));
74	zassert_equal(result, 1);
75}
76
77static void VNAME(u64_mul)(void)
78{
79	uint64_t result = 42;
80
81	zassert_false(u64_mul_overflow(2, 3, &result));
82	zassert_equal(result, 6);
83
84	zassert_false(u64_mul_overflow(UINT64_MAX, 1, &result));
85	zassert_equal(result, UINT64_MAX);
86	zassert_true(u64_mul_overflow(UINT64_MAX, 2, &result));
87	zassert_equal(result, UINT64_MAX * 2);
88
89	zassert_false(u64_mul_overflow(1, UINT64_MAX, &result));
90	zassert_equal(result, UINT64_MAX);
91	zassert_true(u64_mul_overflow(2, UINT64_MAX, &result));
92	zassert_equal(result, UINT64_MAX * 2);
93}
94
95static void VNAME(size_add)(void)
96{
97	size_t result = 42;
98
99	zassert_false(size_add_overflow(2, 3, &result));
100	zassert_equal(result, 5);
101
102	zassert_false(size_add_overflow(2, 0, &result));
103	zassert_equal(result, 2);
104
105	zassert_false(size_add_overflow(0, 3, &result));
106	zassert_equal(result, 3);
107
108	zassert_false(size_add_overflow(0, SIZE_MAX, &result));
109	zassert_equal(result, SIZE_MAX);
110	zassert_true(size_add_overflow(1, SIZE_MAX, &result));
111	zassert_equal(result, 0);
112
113	zassert_false(size_add_overflow(SIZE_MAX, 0, &result));
114	zassert_equal(result, SIZE_MAX);
115	zassert_true(size_add_overflow(SIZE_MAX, 2, &result));
116	zassert_equal(result, 1);
117}
118
119static void VNAME(size_mul)(void)
120{
121	size_t result = 42;
122
123	zassert_false(size_mul_overflow(2, 3, &result));
124	zassert_equal(result, 6);
125
126	zassert_false(size_mul_overflow(SIZE_MAX, 1, &result));
127	zassert_equal(result, SIZE_MAX);
128	zassert_true(size_mul_overflow(SIZE_MAX, 2, &result));
129	zassert_equal(result, SIZE_MAX * 2);
130
131	zassert_false(size_mul_overflow(1, SIZE_MAX, &result));
132	zassert_equal(result, SIZE_MAX);
133	zassert_true(size_mul_overflow(2, SIZE_MAX, &result));
134	zassert_equal(result, SIZE_MAX * 2);
135}
136
137static void VNAME(u32_clz)(void)
138{
139	zassert_equal(u32_count_leading_zeros(0), 32);
140	zassert_equal(u32_count_leading_zeros(1), 31);
141	zassert_equal(u32_count_leading_zeros(0xf00f), 16);
142	zassert_equal(u32_count_leading_zeros(0xf00ff00f), 0);
143	zassert_equal(u32_count_leading_zeros(0xffffffff), 0);
144}
145
146static void VNAME(u64_clz)(void)
147{
148	zassert_equal(u64_count_leading_zeros(0), 64);
149	zassert_equal(u64_count_leading_zeros(1), 63);
150	zassert_equal(u64_count_leading_zeros(0xf00f), 48);
151	zassert_equal(u64_count_leading_zeros(0xf00ff00f), 32);
152	zassert_equal(u64_count_leading_zeros(0xffffffff), 32);
153	zassert_equal(u64_count_leading_zeros(0xf00f00000000ull), 16);
154	zassert_equal(u64_count_leading_zeros(0xf00ff00f00000000ull), 0);
155	zassert_equal(u64_count_leading_zeros(0xffffffff00000000ull), 0);
156}
157
158static void VNAME(u32_ctz)(void)
159{
160	zassert_equal(u32_count_trailing_zeros(0), 32);
161	zassert_equal(u32_count_trailing_zeros(1), 0);
162	zassert_equal(u32_count_trailing_zeros(6), 1);
163	zassert_equal(u32_count_trailing_zeros(0x00f00f00), 8);
164	zassert_equal(u32_count_trailing_zeros(0xf00ffc00), 10);
165	zassert_equal(u32_count_trailing_zeros(0xffffffff), 0);
166	zassert_equal(u32_count_trailing_zeros(0x80000000), 31);
167}
168
169static void VNAME(u64_ctz)(void)
170{
171	zassert_equal(u64_count_trailing_zeros(0), 64);
172	zassert_equal(u64_count_trailing_zeros(1), 0);
173	zassert_equal(u64_count_trailing_zeros(6), 1);
174	zassert_equal(u64_count_trailing_zeros(0x00f00f00), 8);
175	zassert_equal(u64_count_trailing_zeros(0xf00ffc00), 10);
176	zassert_equal(u64_count_trailing_zeros(0xffffffffffffffffull), 0);
177	zassert_equal(u64_count_trailing_zeros(0x8000000080000000ull), 31,
178		      NULL);
179	zassert_equal(u64_count_trailing_zeros(0xc000000000000000ull), 62,
180		      NULL);
181}
182