Linux Audio

Check our new training course

Loading...
/*
 * 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 u64_t bignum, ba, bb;
	volatile u32_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);
}