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 <zephyr/ztest.h>
9 #include <zephyr/test_toolchain.h>
10
11 /* Built-time math test. Zephyr code depends on a standard C ABI with
12 * 2's complement signed math. As this isn't technically guaranteed
13 * by the compiler or language standard, validate it explicitly here.
14 */
15
16 /* Recent GCC's can detect integer overflow in static expressions and
17 * will warn about it helpfully. But obviously integer overflow is
18 * the whole point here, so turn that warning off.
19 */
20 TOOLCHAIN_DISABLE_WARNING(TOOLCHAIN_WARNING_OVERFLOW)
21
22 /* Two's complement negation check: "-N" must equal "(~N)+1" */
23 #define NEG_CHECK(T, N) BUILD_ASSERT((-((T)N)) == (~((T)N)) + 1)
24
25 /* Checks that MAX+1==MIN in the given type */
26 #define ROLLOVER_CHECK(T, MAX, MIN) BUILD_ASSERT((T)((T)1 + (T)MAX) == (T)MIN)
27
28 TOOLCHAIN_DISABLE_CLANG_WARNING(TOOLCHAIN_WARNING_INTEGER_OVERFLOW)
29
30 ROLLOVER_CHECK(unsigned int, 0xffffffff, 0);
31 ROLLOVER_CHECK(unsigned short, 0xffff, 0);
32 ROLLOVER_CHECK(unsigned char, 0xff, 0);
33
34 NEG_CHECK(signed char, 1);
35 NEG_CHECK(signed char, 0);
36 NEG_CHECK(signed char, -1);
37 NEG_CHECK(signed char, 0x80);
38 NEG_CHECK(signed char, 0x7f);
39 ROLLOVER_CHECK(signed char, 127, -128);
40
41 NEG_CHECK(short, 1);
42 NEG_CHECK(short, 0);
43 NEG_CHECK(short, -1);
44 NEG_CHECK(short, 0x8000);
45 NEG_CHECK(short, 0x7fff);
46 ROLLOVER_CHECK(short, 32767, -32768);
47
48 NEG_CHECK(int, 1);
49 NEG_CHECK(int, 0);
50 NEG_CHECK(int, -1);
51 NEG_CHECK(int, 0x80000000);
52 NEG_CHECK(int, 0x7fffffff);
53 ROLLOVER_CHECK(int, 2147483647, -2147483648);
54
55 TOOLCHAIN_ENABLE_CLANG_WARNING(TOOLCHAIN_WARNING_INTEGER_OVERFLOW)
56
57 /**
58 * @addtogroup kernel_common_tests
59 * @{
60 */
61
62 /**
63 * @brief Test integer arithmetic operations
64 *
65 * @details Test multiplication and division of two
66 * integers
67 */
ZTEST(intmath,test_intmath)68 ZTEST(intmath, test_intmath)
69 {
70 /*
71 * Declaring volatile so the compiler doesn't try to optimize any
72 * of the math away at build time
73 */
74 volatile uint64_t bignum, ba, bb;
75 volatile uint32_t num, a, b;
76
77 ba = 0x00000012ABCDEF12ULL;
78 bb = 0x0000001000000111ULL;
79 bignum = ba * bb;
80 zassert_true((bignum == 0xbcdf0509369bf232ULL), "64-bit multiplication failed");
81
82 a = 30000U;
83 b = 5872U;
84 num = a * b;
85 zassert_true((num == 176160000U), "32-bit multiplication failed");
86
87 a = 234424432U;
88 b = 98982U;
89 num = a / b;
90 zassert_true((num == 2368U), "32-bit division failed");
91 }
92 /**
93 * @}
94 */
95
96 ZTEST_SUITE(intmath, NULL, NULL, NULL, NULL, NULL);
97