blob: ddec586f33b88ba08660537e81c38c675f807c62 [file] [log] [blame]
/**
****************************************************************************************
*
* @file co_math.h
*
* @brief Common optimized math functions
*
* Copyright (C) RivieraWaves 2009-2015
* Copyright (C) Atmosic 2023
*
****************************************************************************************
*/
#ifndef _CO_MATH_H_
#define _CO_MATH_H_
/**
*****************************************************************************************
* @defgroup CO_MATH Math functions
* @ingroup COMMON
* @brief Optimized math functions and other computations.
*
* @{
*****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include <stdint.h> // standard integer definitions
#include <stdbool.h> // boolean definitions
#include <stdlib.h> // standard library
#include "compiler.h" // for __INLINE
#include "arch.h" // for ASSERT_ERR
extern void srand (unsigned int seed);
extern int rand (void);
/*
* MACROS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Return value with one bit set.
*
* @param[in] pos Position of the bit to set.
*
* @return Value with one bit set. There is no return type since this is a macro and this
* will be resolved by the compiler upon assignment to an l-value.
****************************************************************************************
*/
#define CO_BIT(pos) (1UL<<(pos))
/**
****************************************************************************************
* @brief Align val on the multiple of 4 equal or nearest higher.
* @param[in] val Value to align.
* @return Value aligned.
****************************************************************************************
*/
#define CO_ALIGN4_HI(val) (((val)+3)&~3)
/**
****************************************************************************************
* @brief Align val on the multiple of 4 equal or nearest lower.
* @param[in] val Value to align.
* @return Value aligned.
****************************************************************************************
*/
#define CO_ALIGN4_LO(val) ((val)&~3)
/**
****************************************************************************************
* @brief Align val on the multiple of 2 equal or nearest higher.
* @param[in] val Value to align.
* @return Value aligned.
****************************************************************************************
*/
#define CO_ALIGN2_HI(val) (((val)+1)&~1)
/**
****************************************************************************************
* @brief Align val on the multiple of 2 equal or nearest lower.
* @param[in] val Value to align.
* @return Value aligned.
****************************************************************************************
*/
#define CO_ALIGN2_LO(val) ((val)&~1)
/**
****************************************************************************************
* Perform a division and ceil up the result
*
* @param[in] val Value to divide
* @param[in] div Divide value
* @return ceil(val/div)
****************************************************************************************
*/
#define CO_DIVIDE_CEIL(val, div) (((val) + ((div) - 1))/ (div))
/**
****************************************************************************************
* Perform a division and round the result
*
* @param[in] val Value to divide
* @param[in] div Divide value
* @return round(val/div)
****************************************************************************************
*/
#define CO_DIVIDE_ROUND(val, div) (((val) + ((div) >> 1))/ (div))
/**
****************************************************************************************
* Perform a modulo operation
*
* @param[in] val Dividend
* @param[in] div Divisor
* @return val/div)
****************************************************************************************
*/
//#define CO_MOD(val, div) ((val) % (div))
__INLINE uint32_t co_mod(uint32_t val, uint32_t div)
{
ASSERT_ERR(div);
return ((val) % (div));
}
#define CO_MOD(val, div) co_mod(val, div)
/*
* FUNCTION DEFINITIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Count leading zeros.
* @param[in] val Value to count the number of leading zeros on.
* @return Number of leading zeros when value is written as 32 bits.
****************************************************************************************
*/
__INLINE uint32_t co_clz(uint32_t val)
{
#if defined(__ICCARM__)
return __CLZ(val);
#elif defined(__arm__)
return __builtin_clz(val);
#elif defined(__GNUC__)
if (val == 0)
{
return 32;
}
return __builtin_clz(val);
#else
uint32_t i;
for (i = 0; i < 32; i++)
{
if (val & CO_BIT(31 - i))
break;
}
return i;
#endif // defined(__arm__)
}
/**
****************************************************************************************
* @brief Count trailing zeros.
* @param[in] val Value to count the number of trailing zeros on.
* @return Number of trailing zeros when value is written as 32 bits.
****************************************************************************************
*/
__INLINE uint32_t co_ctz(uint32_t val)
{
#if defined(__arm__) && defined(CFG_ROM)
return __builtin_ctz(val);
#elif defined(__GNUC__)
if (val == 0)
{
return 32;
}
return __builtin_ctz(val);
#else
uint32_t i;
for (i = 0; i < 32; i++)
{
if (val & CO_BIT(i))
break;
}
return i;
#endif // defined(__arm__)
}
/**
****************************************************************************************
* @brief Function to initialize the random seed.
* @param[in] seed The seed number to use to generate the random sequence.
****************************************************************************************
*/
extern void co_random_init(uint32_t seed);
/**
****************************************************************************************
* @brief Function to get an 8 bit random number.
* @return Random byte value.
****************************************************************************************
*/
__INLINE uint8_t co_rand_byte(void)
{
return (uint8_t)(rand() & 0xFF);
}
/**
****************************************************************************************
* @brief Function to get an 16 bit random number.
* @return Random half word value.
****************************************************************************************
*/
__INLINE uint16_t co_rand_hword(void)
{
return (uint16_t)(rand() & 0xFFFF);
}
/**
****************************************************************************************
* @brief Function to get an 32 bit random number.
* @return Random word value.
****************************************************************************************
*/
__INLINE uint32_t co_rand_word(void)
{
return (uint32_t)rand();
}
extern uint32_t co_secure_rand_word(void);
/**
****************************************************************************************
* @brief Function to return the smallest of 2 unsigned 32 bits words.
* @return The smallest value.
****************************************************************************************
*/
__INLINE uint32_t co_min(uint32_t a, uint32_t b)
{
return a < b ? a : b;
}
/**
****************************************************************************************
* @brief Function to return the smallest of 2 signed 32 bits words.
* @return The smallest value.
****************************************************************************************
*/
__INLINE int32_t co_min_s(int32_t a, int32_t b)
{
return a < b ? a : b;
}
/**
****************************************************************************************
* @brief Function to return the greatest of 2 unsigned 32 bits words.
* @return The greatest value.
****************************************************************************************
*/
__INLINE uint32_t co_max(uint32_t a, uint32_t b)
{
return a > b ? a : b;
}
/**
****************************************************************************************
* @brief Function to return the absolute value of a signed integer.
* @return The absolute value.
****************************************************************************************
*/
__INLINE int co_abs(int val)
{
return val < 0 ? val*(-1) : val;
}
/// @} CO_MATH
#endif // _CO_MATH_H_