1 /*
2 * Copyright (c) 2015 Wind River Systems, Inc.
3 * Copyright (c) 2018 Intel Corporation
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <ztest.h>
9
10 /* Built-time math test. Zephyr code depends on a standard C ABI with
11 * 2's complement signed math. As this isn't technically guaranteed
12 * by the compiler or language standard, validate it explicitly here.
13 */
14
15 /* Recent GCC's can detect integer overflow in static expressions and
16 * will warn about it heplfully. But obviously integer overflow is
17 * the whole point here, so turn that warning off.
18 */
19 #ifdef __GNUC__
20 #pragma GCC diagnostic ignored "-Woverflow"
21 #endif
22
23 /* Two's complement negation check: "-N" must equal "(~N)+1" */
24 #define NEG_CHECK(T, N) BUILD_ASSERT((-((T)N)) == (~((T)N)) + 1)
25
26 /* Checks that MAX+1==MIN in the given type */
27 #define ROLLOVER_CHECK(T, MAX, MIN) BUILD_ASSERT((T)((T)1 + (T)MAX) == (T)MIN)
28
29 #ifdef __clang__
30 #pragma clang diagnostic push
31 #pragma clang diagnostic ignored "-Winteger-overflow"
32 #endif
33
34 ROLLOVER_CHECK(unsigned int, 0xffffffff, 0);
35 ROLLOVER_CHECK(unsigned short, 0xffff, 0);
36 ROLLOVER_CHECK(unsigned char, 0xff, 0);
37
38 NEG_CHECK(signed char, 1);
39 NEG_CHECK(signed char, 0);
40 NEG_CHECK(signed char, -1);
41 NEG_CHECK(signed char, 0x80);
42 NEG_CHECK(signed char, 0x7f);
43 ROLLOVER_CHECK(signed char, 127, -128);
44
45 NEG_CHECK(short, 1);
46 NEG_CHECK(short, 0);
47 NEG_CHECK(short, -1);
48 NEG_CHECK(short, 0x8000);
49 NEG_CHECK(short, 0x7fff);
50 ROLLOVER_CHECK(short, 32767, -32768);
51
52 NEG_CHECK(int, 1);
53 NEG_CHECK(int, 0);
54 NEG_CHECK(int, -1);
55 NEG_CHECK(int, 0x80000000);
56 NEG_CHECK(int, 0x7fffffff);
57 ROLLOVER_CHECK(int, 2147483647, -2147483648);
58
59 #ifdef __clang__
60 #pragma clang diagnostic pop
61 #endif
62
63 /**
64 * @addtogroup kernel_common_tests
65 * @{
66 */
67
68 /**
69 * @brief Test integer arithmetic operations
70 *
71 * @details Test multiplication and division of two
72 * integers
73 */
test_intmath(void)74 void test_intmath(void)
75 {
76 /*
77 * Declaring volatile so the compiler doesn't try to optimize any
78 * of the math away at build time
79 */
80 volatile uint64_t bignum, ba, bb;
81 volatile uint32_t num, a, b;
82
83 ba = 0x00000012ABCDEF12ULL;
84 bb = 0x0000001000000111ULL;
85 bignum = ba * bb;
86 zassert_true((bignum == 0xbcdf0509369bf232ULL), "64-bit multiplication failed");
87
88 a = 30000U;
89 b = 5872U;
90 num = a * b;
91 zassert_true((num == 176160000U), "32-bit multiplication failed");
92
93 a = 234424432U;
94 b = 98982U;
95 num = a / b;
96 zassert_true((num == 2368U), "32-bit division failed");
97 }
98 /**
99 * @}
100 */
101
102
103
test_main(void)104 void test_main(void)
105 {
106 ztest_test_suite(intmath,
107 ztest_unit_test(test_intmath)
108 );
109
110 ztest_run_test_suite(intmath);
111 }
112