112 lines
2.5 KiB
C
112 lines
2.5 KiB
C
/*
|
|
* 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 helpfully. 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);
|
|
}
|