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