| /* |
| * 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); |
| } |