| /* | 
 |  * Copyright (c) 2015 Wind River Systems, Inc. | 
 |  * Copyright (c) 2018 Intel Corporation | 
 |  * | 
 |  * SPDX-License-Identifier: Apache-2.0 | 
 |  */ | 
 |  | 
 | #include <ztest.h> | 
 |  | 
 | /* Built-time math test.  Zephyr code depends on a standard C ABI with | 
 |  * 2's complement signed math.  As this isn't technically guaranteed | 
 |  * by the compiler or language standard, validate it explicitly here. | 
 |  */ | 
 |  | 
 | /* Recent GCC's can detect integer overflow in static expressions and | 
 |  * will warn about it heplfully.  But obviously integer overflow is | 
 |  * the whole point here, so turn that warning off. | 
 |  */ | 
 | #ifdef __GNUC__ | 
 | #pragma GCC diagnostic ignored "-Woverflow" | 
 | #endif | 
 |  | 
 | /* Two's complement negation check: "-N" must equal "(~N)+1" */ | 
 | #define NEG_CHECK(T, N) BUILD_ASSERT((-((T)N)) == (~((T)N)) + 1) | 
 |  | 
 | /* Checks that MAX+1==MIN in the given type */ | 
 | #define ROLLOVER_CHECK(T, MAX, MIN) BUILD_ASSERT((T)((T)1 + (T)MAX) == (T)MIN) | 
 |  | 
 | #ifdef __clang__ | 
 | #pragma clang diagnostic push | 
 | #pragma clang diagnostic ignored "-Winteger-overflow" | 
 | #endif | 
 |  | 
 | ROLLOVER_CHECK(unsigned int, 0xffffffff, 0); | 
 | ROLLOVER_CHECK(unsigned short, 0xffff, 0); | 
 | ROLLOVER_CHECK(unsigned char, 0xff, 0); | 
 |  | 
 | NEG_CHECK(signed char, 1); | 
 | NEG_CHECK(signed char, 0); | 
 | NEG_CHECK(signed char, -1); | 
 | NEG_CHECK(signed char, 0x80); | 
 | NEG_CHECK(signed char, 0x7f); | 
 | ROLLOVER_CHECK(signed char, 127, -128); | 
 |  | 
 | NEG_CHECK(short, 1); | 
 | NEG_CHECK(short, 0); | 
 | NEG_CHECK(short, -1); | 
 | NEG_CHECK(short, 0x8000); | 
 | NEG_CHECK(short, 0x7fff); | 
 | ROLLOVER_CHECK(short, 32767, -32768); | 
 |  | 
 | NEG_CHECK(int, 1); | 
 | NEG_CHECK(int, 0); | 
 | NEG_CHECK(int, -1); | 
 | NEG_CHECK(int, 0x80000000); | 
 | NEG_CHECK(int, 0x7fffffff); | 
 | ROLLOVER_CHECK(int, 2147483647, -2147483648); | 
 |  | 
 | #ifdef __clang__ | 
 | #pragma clang diagnostic pop | 
 | #endif | 
 |  | 
 | /** | 
 |  * @addtogroup kernel_common_tests | 
 |  * @{ | 
 |  */ | 
 |  | 
 | /** | 
 |  * @brief Test integer arithmetic operations | 
 |  * | 
 |  * @details Test multiplication and division of two | 
 |  * integers | 
 |  */ | 
 | void test_intmath(void) | 
 | { | 
 | 	/* | 
 | 	 * Declaring volatile so the compiler doesn't try to optimize any | 
 | 	 * of the math away at build time | 
 | 	 */ | 
 | 	volatile uint64_t bignum, ba, bb; | 
 | 	volatile uint32_t num, a, b; | 
 |  | 
 | 	ba = 0x00000012ABCDEF12ULL; | 
 | 	bb = 0x0000001000000111ULL; | 
 | 	bignum = ba * bb; | 
 | 	zassert_true((bignum == 0xbcdf0509369bf232ULL), "64-bit multiplication failed"); | 
 |  | 
 | 	a = 30000U; | 
 | 	b = 5872U; | 
 | 	num = a * b; | 
 | 	zassert_true((num == 176160000U), "32-bit multiplication failed"); | 
 |  | 
 | 	a = 234424432U; | 
 | 	b = 98982U; | 
 | 	num = a / b; | 
 | 	zassert_true((num == 2368U), "32-bit division failed"); | 
 | } | 
 | /** | 
 |  * @} | 
 |  */ | 
 |  | 
 |  | 
 |  | 
 | void test_main(void) | 
 | { | 
 | 	ztest_test_suite(intmath, | 
 | 			 ztest_unit_test(test_intmath) | 
 | 			 ); | 
 |  | 
 | 	ztest_run_test_suite(intmath); | 
 | } |