From: Dave Airlie <[email protected]> There are two copies of these libraries, like the upstream should just not do this, but in the kernel we definitely don't want this.
I haven't taken the next step of ripping out the spl_ changes, but maybe if I get in a bad mood. This drops 5K from the amdgpu binary: text data bss dec hex filename 12284141 705053 292544 13281738 caa9ca ../../drm-next-build/drivers/gpu/drm/amd/amdgpu/amdgpu.ko text data bss dec hex filename 12279057 704445 292544 13276046 ca938e ../../drm-next-build/drivers/gpu/drm/amd/amdgpu/amdgpu.ko Signed-off-by: Dave Airlie <[email protected]> --- drivers/gpu/drm/amd/display/dc/sspl/Makefile | 2 +- .../amd/display/dc/sspl/spl_custom_float.c | 152 ----- .../amd/display/dc/sspl/spl_custom_float.h | 15 +- .../drm/amd/display/dc/sspl/spl_fixpt31_32.c | 495 ---------------- .../drm/amd/display/dc/sspl/spl_fixpt31_32.h | 544 +----------------- 5 files changed, 31 insertions(+), 1177 deletions(-) delete mode 100644 drivers/gpu/drm/amd/display/dc/sspl/spl_custom_float.c delete mode 100644 drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c diff --git a/drivers/gpu/drm/amd/display/dc/sspl/Makefile b/drivers/gpu/drm/amd/display/dc/sspl/Makefile index 5e3e4aa13820..17f3e2c801cf 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/Makefile +++ b/drivers/gpu/drm/amd/display/dc/sspl/Makefile @@ -23,7 +23,7 @@ # Makefile for the 'spl' sub-component of DAL. # It provides the scaling library interface. -SPL = dc_spl.o dc_spl_scl_filters.o dc_spl_scl_easf_filters.o dc_spl_isharp_filters.o dc_spl_filters.o spl_fixpt31_32.o spl_custom_float.o +SPL = dc_spl.o dc_spl_scl_filters.o dc_spl_scl_easf_filters.o dc_spl_isharp_filters.o dc_spl_filters.o AMD_DAL_SPL = $(addprefix $(AMDDALPATH)/dc/sspl/,$(SPL)) diff --git a/drivers/gpu/drm/amd/display/dc/sspl/spl_custom_float.c b/drivers/gpu/drm/amd/display/dc/sspl/spl_custom_float.c deleted file mode 100644 index 0700b3dbbda7..000000000000 --- a/drivers/gpu/drm/amd/display/dc/sspl/spl_custom_float.c +++ /dev/null @@ -1,152 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// Copyright 2024 Advanced Micro Devices, Inc. - -#include "spl_debug.h" -#include "spl_custom_float.h" - -static bool spl_build_custom_float(struct spl_fixed31_32 value, - const struct spl_custom_float_format *format, - bool *negative, - uint32_t *mantissa, - uint32_t *exponenta) -{ - uint32_t exp_offset = (1 << (format->exponenta_bits - 1)) - 1; - - const struct spl_fixed31_32 mantissa_constant_plus_max_fraction = - SPL_NAMESPACE(spl_fixpt_from_fraction((1LL << (format->mantissa_bits + 1)) - 1, - 1LL << format->mantissa_bits)); - - struct spl_fixed31_32 mantiss; - - if (spl_fixpt_eq(value, spl_fixpt_zero)) { - *negative = false; - *mantissa = 0; - *exponenta = 0; - return true; - } - - if (spl_fixpt_lt(value, spl_fixpt_zero)) { - *negative = format->sign; - value = spl_fixpt_neg(value); - } else { - *negative = false; - } - - if (spl_fixpt_lt(value, spl_fixpt_one)) { - uint32_t i = 1; - - do { - value = spl_fixpt_shl(value, 1); - ++i; - } while (spl_fixpt_lt(value, spl_fixpt_one)); - - --i; - - if (exp_offset <= i) { - *mantissa = 0; - *exponenta = 0; - return true; - } - - *exponenta = exp_offset - i; - } else if (spl_fixpt_le(mantissa_constant_plus_max_fraction, value)) { - uint32_t i = 1; - - do { - value = spl_fixpt_shr(value, 1); - ++i; - } while (spl_fixpt_lt(mantissa_constant_plus_max_fraction, value)); - - *exponenta = exp_offset + i - 1; - } else { - *exponenta = exp_offset; - } - - mantiss = spl_fixpt_sub(value, spl_fixpt_one); - - if (spl_fixpt_lt(mantiss, spl_fixpt_zero) || - spl_fixpt_lt(spl_fixpt_one, mantiss)) - mantiss = spl_fixpt_zero; - else - mantiss = spl_fixpt_shl(mantiss, format->mantissa_bits); - - *mantissa = spl_fixpt_floor(mantiss); - - return true; -} - -static bool spl_setup_custom_float(const struct spl_custom_float_format *format, - bool negative, - uint32_t mantissa, - uint32_t exponenta, - uint32_t *result) -{ - uint32_t i = 0; - uint32_t j = 0; - uint32_t value = 0; - - /* verification code: - * once calculation is ok we can remove it - */ - - const uint32_t mantissa_mask = - (1 << (format->mantissa_bits + 1)) - 1; - - const uint32_t exponenta_mask = - (1 << (format->exponenta_bits + 1)) - 1; - - if (mantissa & ~mantissa_mask) { - SPL_BREAK_TO_DEBUGGER(); - mantissa = mantissa_mask; - } - - if (exponenta & ~exponenta_mask) { - SPL_BREAK_TO_DEBUGGER(); - exponenta = exponenta_mask; - } - - /* end of verification code */ - - while (i < format->mantissa_bits) { - uint32_t mask = 1 << i; - - if (mantissa & mask) - value |= mask; - - ++i; - } - - while (j < format->exponenta_bits) { - uint32_t mask = 1 << j; - - if (exponenta & mask) - value |= mask << i; - - ++j; - } - - if (negative && format->sign) - value |= 1 << (i + j); - - *result = value; - - return true; -} - -bool SPL_NAMESPACE(spl_convert_to_custom_float_format( - struct spl_fixed31_32 value, - const struct spl_custom_float_format *format, - uint32_t *result)) -{ - uint32_t mantissa; - uint32_t exponenta; - bool negative; - - return spl_build_custom_float(value, format, &negative, &mantissa, &exponenta) && - spl_setup_custom_float(format, - negative, - mantissa, - exponenta, - result); -} diff --git a/drivers/gpu/drm/amd/display/dc/sspl/spl_custom_float.h b/drivers/gpu/drm/amd/display/dc/sspl/spl_custom_float.h index 60620537ae3e..7aaa2c5db1a5 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/spl_custom_float.h +++ b/drivers/gpu/drm/amd/display/dc/sspl/spl_custom_float.h @@ -5,18 +5,9 @@ #ifndef SPL_CUSTOM_FLOAT_H_ #define SPL_CUSTOM_FLOAT_H_ -#include "spl_os_types.h" -#include "spl_fixpt31_32.h" +#include "dc/inc/custom_float.h" -struct spl_custom_float_format { - uint32_t mantissa_bits; - uint32_t exponenta_bits; - bool sign; -}; - -bool SPL_NAMESPACE(spl_convert_to_custom_float_format( - struct spl_fixed31_32 value, - const struct spl_custom_float_format *format, - uint32_t *result)); +#define spl_custom_float_format custom_float_format +#define spl_convert_to_custom_float_format convert_to_custom_float_format #endif //SPL_CUSTOM_FLOAT_H_ diff --git a/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c b/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c deleted file mode 100644 index ff0bdc3c33c8..000000000000 --- a/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c +++ /dev/null @@ -1,495 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// Copyright 2024 Advanced Micro Devices, Inc. - -#include "spl_fixpt31_32.h" - -static const struct spl_fixed31_32 spl_fixpt_two_pi = { 26986075409LL }; -static const struct spl_fixed31_32 spl_fixpt_ln2 = { 2977044471LL }; -static const struct spl_fixed31_32 spl_fixpt_ln2_div_2 = { 1488522236LL }; - -static inline unsigned long long abs_i64( - long long arg) -{ - if (arg > 0) - return (unsigned long long)arg; - else - return (unsigned long long)(-arg); -} - -/* - * @brief - * result = dividend / divisor - * *remainder = dividend % divisor - */ -static inline unsigned long long spl_complete_integer_division_u64( - unsigned long long dividend, - unsigned long long divisor, - unsigned long long *remainder) -{ - unsigned long long result; - - result = spl_div64_u64_rem(dividend, divisor, remainder); - - return result; -} - - -#define FRACTIONAL_PART_MASK \ - ((1ULL << FIXED31_32_BITS_PER_FRACTIONAL_PART) - 1) - -#define GET_INTEGER_PART(x) \ - ((x) >> FIXED31_32_BITS_PER_FRACTIONAL_PART) - -#define GET_FRACTIONAL_PART(x) \ - (FRACTIONAL_PART_MASK & (x)) - -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_from_fraction( - long long numerator, long long denominator)) -{ - struct spl_fixed31_32 res; - - bool arg1_negative = numerator < 0; - bool arg2_negative = denominator < 0; - - unsigned long long arg1_value = arg1_negative ? -numerator : numerator; - unsigned long long arg2_value = arg2_negative ? -denominator : denominator; - - unsigned long long remainder; - - /* determine integer part */ - - unsigned long long res_value = spl_complete_integer_division_u64( - arg1_value, arg2_value, &remainder); - - SPL_ASSERT(res_value <= (unsigned long long)LONG_MAX); - - /* determine fractional part */ - { - unsigned int i = FIXED31_32_BITS_PER_FRACTIONAL_PART; - - do { - remainder <<= 1; - - res_value <<= 1; - - if (remainder >= arg2_value) { - res_value |= 1; - remainder -= arg2_value; - } - } while (--i != 0); - } - - /* round up LSB */ - { - unsigned long long summand = (remainder << 1) >= arg2_value; - - SPL_ASSERT(res_value <= (unsigned long long)LLONG_MAX - summand); - - res_value += summand; - } - - res.value = (long long)res_value; - - if (arg1_negative ^ arg2_negative) - res.value = -res.value; - - return res; -} - -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_mul( - struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)) -{ - struct spl_fixed31_32 res; - - bool arg1_negative = arg1.value < 0; - bool arg2_negative = arg2.value < 0; - - unsigned long long arg1_value = arg1_negative ? -arg1.value : arg1.value; - unsigned long long arg2_value = arg2_negative ? -arg2.value : arg2.value; - - unsigned long long arg1_int = GET_INTEGER_PART(arg1_value); - unsigned long long arg2_int = GET_INTEGER_PART(arg2_value); - - unsigned long long arg1_fra = GET_FRACTIONAL_PART(arg1_value); - unsigned long long arg2_fra = GET_FRACTIONAL_PART(arg2_value); - - unsigned long long tmp; - - res.value = arg1_int * arg2_int; - - SPL_ASSERT(res.value <= (long long)LONG_MAX); - - res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART; - - tmp = arg1_int * arg2_fra; - - SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); - - res.value += tmp; - - tmp = arg2_int * arg1_fra; - - SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); - - res.value += tmp; - - tmp = arg1_fra * arg2_fra; - - tmp = (tmp >> FIXED31_32_BITS_PER_FRACTIONAL_PART) + - (tmp >= (unsigned long long)spl_fixpt_half.value); - - SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); - - res.value += tmp; - - if (arg1_negative ^ arg2_negative) - res.value = -res.value; - - return res; -} - -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_sqr(struct spl_fixed31_32 arg)) -{ - struct spl_fixed31_32 res; - - unsigned long long arg_value = abs_i64(arg.value); - - unsigned long long arg_int = GET_INTEGER_PART(arg_value); - - unsigned long long arg_fra = GET_FRACTIONAL_PART(arg_value); - - unsigned long long tmp; - - res.value = arg_int * arg_int; - - SPL_ASSERT(res.value <= (long long)LONG_MAX); - - res.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART; - - tmp = arg_int * arg_fra; - - SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); - - res.value += tmp; - - SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); - - res.value += tmp; - - tmp = arg_fra * arg_fra; - - tmp = (tmp >> FIXED31_32_BITS_PER_FRACTIONAL_PART) + - (tmp >= (unsigned long long)spl_fixpt_half.value); - - SPL_ASSERT(tmp <= (unsigned long long)(LLONG_MAX - res.value)); - - res.value += tmp; - - return res; -} - -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_recip(struct spl_fixed31_32 arg)) -{ - /* - * @note - * Good idea to use Newton's method - */ - - return SPL_NAMESPACE(spl_fixpt_from_fraction( - spl_fixpt_one.value, - arg.value)); -} - -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_sinc(struct spl_fixed31_32 arg)) -{ - struct spl_fixed31_32 square; - - struct spl_fixed31_32 res = spl_fixpt_one; - - int n = 27; - - struct spl_fixed31_32 arg_norm = arg; - - if (spl_fixpt_le( - spl_fixpt_two_pi, - spl_fixpt_abs(arg))) { - arg_norm = spl_fixpt_sub( - arg_norm, - spl_fixpt_mul_int( - spl_fixpt_two_pi, - (int)spl_div64_s64( - arg_norm.value, - spl_fixpt_two_pi.value))); - } - - square = SPL_NAMESPACE(spl_fixpt_sqr(arg_norm)); - - do { - res = spl_fixpt_sub( - spl_fixpt_one, - spl_fixpt_div_int( - SPL_NAMESPACE(spl_fixpt_mul( - square, - res)), - n * (n - 1))); - - n -= 2; - } while (n > 2); - - if (arg.value != arg_norm.value) - res = spl_fixpt_div( - SPL_NAMESPACE(spl_fixpt_mul(res, arg_norm)), - arg); - - return res; -} - -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_sin(struct spl_fixed31_32 arg)) -{ - return SPL_NAMESPACE(spl_fixpt_mul( - arg, - SPL_NAMESPACE(spl_fixpt_sinc(arg)))); -} - -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_cos(struct spl_fixed31_32 arg)) -{ - /* TODO implement argument normalization */ - - const struct spl_fixed31_32 square = SPL_NAMESPACE(spl_fixpt_sqr(arg)); - - struct spl_fixed31_32 res = spl_fixpt_one; - - int n = 26; - - do { - res = spl_fixpt_sub( - spl_fixpt_one, - spl_fixpt_div_int( - SPL_NAMESPACE(spl_fixpt_mul( - square, - res)), - n * (n - 1))); - - n -= 2; - } while (n != 0); - - return res; -} - -/* - * @brief - * result = exp(arg), - * where abs(arg) < 1 - * - * Calculated as Taylor series. - */ -static struct spl_fixed31_32 spl_fixed31_32_exp_from_taylor_series(struct spl_fixed31_32 arg) -{ - unsigned int n = 9; - - struct spl_fixed31_32 res = SPL_NAMESPACE(spl_fixpt_from_fraction( - n + 2, - n + 1)); - /* TODO find correct res */ - - SPL_ASSERT(spl_fixpt_lt(arg, spl_fixpt_one)); - - do - res = spl_fixpt_add( - spl_fixpt_one, - spl_fixpt_div_int( - SPL_NAMESPACE(spl_fixpt_mul( - arg, - res)), - n)); - while (--n != 1); - - return spl_fixpt_add( - spl_fixpt_one, - SPL_NAMESPACE(spl_fixpt_mul( - arg, - res))); -} - -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_exp(struct spl_fixed31_32 arg)) -{ - /* - * @brief - * Main equation is: - * exp(x) = exp(r + m * ln(2)) = (1 << m) * exp(r), - * where m = round(x / ln(2)), r = x - m * ln(2) - */ - - if (spl_fixpt_le( - spl_fixpt_ln2_div_2, - spl_fixpt_abs(arg))) { - int m = spl_fixpt_round( - spl_fixpt_div( - arg, - spl_fixpt_ln2)); - - struct spl_fixed31_32 r = spl_fixpt_sub( - arg, - spl_fixpt_mul_int( - spl_fixpt_ln2, - m)); - - SPL_ASSERT(m != 0); - - SPL_ASSERT(spl_fixpt_lt( - spl_fixpt_abs(r), - spl_fixpt_one)); - - if (m > 0) - return spl_fixpt_shl( - spl_fixed31_32_exp_from_taylor_series(r), - (unsigned int)m); - else - return spl_fixpt_div_int( - spl_fixed31_32_exp_from_taylor_series(r), - 1LL << -m); - } else if (arg.value != 0) - return spl_fixed31_32_exp_from_taylor_series(arg); - else - return spl_fixpt_one; -} - -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_log(struct spl_fixed31_32 arg)) -{ - struct spl_fixed31_32 res = spl_fixpt_neg(spl_fixpt_one); - /* TODO improve 1st estimation */ - - struct spl_fixed31_32 error; - - SPL_ASSERT(arg.value > 0); - /* TODO if arg is negative, return NaN */ - /* TODO if arg is zero, return -INF */ - - do { - struct spl_fixed31_32 res1 = spl_fixpt_add( - spl_fixpt_sub( - res, - spl_fixpt_one), - spl_fixpt_div( - arg, - SPL_NAMESPACE(spl_fixpt_exp(res)))); - - error = spl_fixpt_sub( - res, - res1); - - res = res1; - /* TODO determine max_allowed_error based on quality of exp() */ - } while (abs_i64(error.value) > 100ULL); - - return res; -} - - -/* this function is a generic helper to translate fixed point value to - * specified integer format that will consist of integer_bits integer part and - * fractional_bits fractional part. For example it is used in - * spl_fixpt_u2d19 to receive 2 bits integer part and 19 bits fractional - * part in 32 bits. It is used in hw programming (scaler) - */ - -static inline unsigned int spl_ux_dy( - long long value, - unsigned int integer_bits, - unsigned int fractional_bits) -{ - /* 1. create mask of integer part */ - unsigned int result = (1 << integer_bits) - 1; - /* 2. mask out fractional part */ - unsigned int fractional_part = FRACTIONAL_PART_MASK & value; - /* 3. shrink fixed point integer part to be of integer_bits width*/ - result &= GET_INTEGER_PART(value); - /* 4. make space for fractional part to be filled in after integer */ - result <<= fractional_bits; - /* 5. shrink fixed point fractional part to of fractional_bits width*/ - fractional_part >>= FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits; - /* 6. merge the result */ - return result | fractional_part; -} - -static inline unsigned int spl_clamp_ux_dy( - long long value, - unsigned int integer_bits, - unsigned int fractional_bits, - unsigned int min_clamp) -{ - unsigned int truncated_val = spl_ux_dy(value, integer_bits, fractional_bits); - - if (value >= (1LL << (integer_bits + FIXED31_32_BITS_PER_FRACTIONAL_PART))) - return (1 << (integer_bits + fractional_bits)) - 1; - else if (truncated_val > min_clamp) - return truncated_val; - else - return min_clamp; -} - -unsigned int SPL_NAMESPACE(spl_fixpt_u4d19(struct spl_fixed31_32 arg)) -{ - return spl_ux_dy(arg.value, 4, 19); -} - -unsigned int SPL_NAMESPACE(spl_fixpt_u3d19(struct spl_fixed31_32 arg)) -{ - return spl_ux_dy(arg.value, 3, 19); -} - -unsigned int SPL_NAMESPACE(spl_fixpt_u2d19(struct spl_fixed31_32 arg)) -{ - return spl_ux_dy(arg.value, 2, 19); -} - -unsigned int SPL_NAMESPACE(spl_fixpt_u0d19(struct spl_fixed31_32 arg)) -{ - return spl_ux_dy(arg.value, 0, 19); -} - -unsigned int SPL_NAMESPACE(spl_fixpt_clamp_u0d14(struct spl_fixed31_32 arg)) -{ - return spl_clamp_ux_dy(arg.value, 0, 14, 1); -} - -unsigned int SPL_NAMESPACE(spl_fixpt_clamp_u0d10(struct spl_fixed31_32 arg)) -{ - return spl_clamp_ux_dy(arg.value, 0, 10, 1); -} - -int SPL_NAMESPACE(spl_fixpt_s4d19(struct spl_fixed31_32 arg)) -{ - if (arg.value < 0) - return -(int)spl_ux_dy(spl_fixpt_abs(arg).value, 4, 19); - else - return spl_ux_dy(arg.value, 4, 19); -} - -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_from_ux_dy(unsigned int value, - unsigned int integer_bits, - unsigned int fractional_bits)) -{ - struct spl_fixed31_32 fixpt_value = spl_fixpt_zero; - struct spl_fixed31_32 fixpt_int_value = spl_fixpt_zero; - long long frac_mask = ((long long)1 << (long long)integer_bits) - 1; - - fixpt_value.value = (long long)value << (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits); - frac_mask = frac_mask << fractional_bits; - fixpt_int_value.value = value & frac_mask; - fixpt_int_value.value <<= (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits); - fixpt_value.value |= fixpt_int_value.value; - return fixpt_value; -} - -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_from_int_dy(unsigned int int_value, - unsigned int frac_value, - unsigned int integer_bits, - unsigned int fractional_bits)) -{ - struct spl_fixed31_32 fixpt_value = spl_fixpt_from_int(int_value); - - fixpt_value.value |= (long long)frac_value << (FIXED31_32_BITS_PER_FRACTIONAL_PART - fractional_bits); - return fixpt_value; -} diff --git a/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.h b/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.h index b0e639d6e97d..b5b15d6070ab 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.h +++ b/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.h @@ -5,522 +5,32 @@ #ifndef __SPL_FIXED31_32_H__ #define __SPL_FIXED31_32_H__ -#include "spl_debug.h" -#include "spl_os_types.h" // swap - -#ifndef LLONG_MAX -#define LLONG_MAX 9223372036854775807ll -#endif -#ifndef LLONG_MIN -#define LLONG_MIN (-LLONG_MAX - 1ll) -#endif - -#define FIXED31_32_BITS_PER_FRACTIONAL_PART 32 -#ifndef LLONG_MIN -#define LLONG_MIN (1LL<<63) -#endif -#ifndef LLONG_MAX -#define LLONG_MAX (-1LL>>1) -#endif - -/* - * @brief - * Arithmetic operations on real numbers - * represented as fixed-point numbers. - * There are: 1 bit for sign, - * 31 bit for integer part, - * 32 bits for fractional part. - * - * @note - * Currently, overflows and underflows are asserted; - * no special result returned. - */ - -struct spl_fixed31_32 { - long long value; -}; - - -/* - * @brief - * Useful constants - */ - -static const struct spl_fixed31_32 spl_fixpt_zero = { 0 }; -static const struct spl_fixed31_32 spl_fixpt_epsilon = { 1LL }; -static const struct spl_fixed31_32 spl_fixpt_half = { 0x80000000LL }; -static const struct spl_fixed31_32 spl_fixpt_one = { 0x100000000LL }; - -/* - * @brief - * Initialization routines - */ - -/* - * @brief - * result = numerator / denominator - */ -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_from_fraction( - long long numerator, long long denominator)); - -/* - * @brief - * result = arg - */ -static inline struct spl_fixed31_32 spl_fixpt_from_int(int arg) -{ - struct spl_fixed31_32 res; - - res.value = (long long) arg << FIXED31_32_BITS_PER_FRACTIONAL_PART; - - return res; -} - -/* - * @brief - * Unary operators - */ - -/* - * @brief - * result = -arg - */ -static inline struct spl_fixed31_32 spl_fixpt_neg(struct spl_fixed31_32 arg) -{ - struct spl_fixed31_32 res; - - res.value = -arg.value; - - return res; -} - -/* - * @brief - * result = abs(arg) := (arg >= 0) ? arg : -arg - */ -static inline struct spl_fixed31_32 spl_fixpt_abs(struct spl_fixed31_32 arg) -{ - if (arg.value < 0) - return spl_fixpt_neg(arg); - else - return arg; -} - -/* - * @brief - * Binary relational operators - */ - -/* - * @brief - * result = arg1 < arg2 - */ -static inline bool spl_fixpt_lt(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2) -{ - return arg1.value < arg2.value; -} - -/* - * @brief - * result = arg1 <= arg2 - */ -static inline bool spl_fixpt_le(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2) -{ - return arg1.value <= arg2.value; -} - -/* - * @brief - * result = arg1 == arg2 - */ -static inline bool spl_fixpt_eq(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2) -{ - return arg1.value == arg2.value; -} - -/* - * @brief - * result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2 - */ -static inline struct spl_fixed31_32 spl_fixpt_min(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2) -{ - if (arg1.value <= arg2.value) - return arg1; - else - return arg2; -} - -/* - * @brief - * result = max(arg1, arg2) := (arg1 <= arg2) ? arg2 : arg1 - */ -static inline struct spl_fixed31_32 spl_fixpt_max(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2) -{ - if (arg1.value <= arg2.value) - return arg2; - else - return arg1; -} - -/* - * @brief - * | min_value, when arg <= min_value - * result = | arg, when min_value < arg < max_value - * | max_value, when arg >= max_value - */ -static inline struct spl_fixed31_32 spl_fixpt_clamp( - struct spl_fixed31_32 arg, - struct spl_fixed31_32 min_value, - struct spl_fixed31_32 max_value) -{ - if (spl_fixpt_le(arg, min_value)) - return min_value; - else if (spl_fixpt_le(max_value, arg)) - return max_value; - else - return arg; -} - -/* - * @brief - * Binary shift operators - */ - -/* - * @brief - * result = arg << shift - */ -static inline struct spl_fixed31_32 spl_fixpt_shl(struct spl_fixed31_32 arg, unsigned int shift) -{ - SPL_ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) || - ((arg.value < 0) && (arg.value >= ~(LLONG_MAX >> shift)))); - - arg.value = arg.value << shift; - - return arg; -} - -/* - * @brief - * result = arg >> shift - */ -static inline struct spl_fixed31_32 spl_fixpt_shr(struct spl_fixed31_32 arg, unsigned int shift) -{ - bool negative = arg.value < 0; - - if (negative) - arg.value = -arg.value; - arg.value = arg.value >> shift; - if (negative) - arg.value = -arg.value; - return arg; -} - -/* - * @brief - * Binary additive operators - */ - -/* - * @brief - * result = arg1 + arg2 - */ -static inline struct spl_fixed31_32 spl_fixpt_add(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2) -{ - struct spl_fixed31_32 res; - - SPL_ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) || - ((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value))); - - res.value = arg1.value + arg2.value; - - return res; -} - -/* - * @brief - * result = arg1 + arg2 - */ -static inline struct spl_fixed31_32 spl_fixpt_add_int(struct spl_fixed31_32 arg1, int arg2) -{ - return spl_fixpt_add(arg1, spl_fixpt_from_int(arg2)); -} - -/* - * @brief - * result = arg1 - arg2 - */ -static inline struct spl_fixed31_32 spl_fixpt_sub(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2) -{ - struct spl_fixed31_32 res; - - SPL_ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) || - ((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value))); - - res.value = arg1.value - arg2.value; - - return res; -} - -/* - * @brief - * result = arg1 - arg2 - */ -static inline struct spl_fixed31_32 spl_fixpt_sub_int(struct spl_fixed31_32 arg1, int arg2) -{ - return spl_fixpt_sub(arg1, spl_fixpt_from_int(arg2)); -} - - -/* - * @brief - * Binary multiplicative operators - */ - -/* - * @brief - * result = arg1 * arg2 - */ -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_mul( - struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2)); - - -/* - * @brief - * result = arg1 * arg2 - */ -static inline struct spl_fixed31_32 spl_fixpt_mul_int(struct spl_fixed31_32 arg1, int arg2) -{ - return SPL_NAMESPACE(spl_fixpt_mul(arg1, spl_fixpt_from_int(arg2))); -} - -/* - * @brief - * result = square(arg) := arg * arg - */ -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_sqr(struct spl_fixed31_32 arg)); - -/* - * @brief - * result = arg1 / arg2 - */ -static inline struct spl_fixed31_32 spl_fixpt_div_int(struct spl_fixed31_32 arg1, long long arg2) -{ - return SPL_NAMESPACE(spl_fixpt_from_fraction(arg1.value, - spl_fixpt_from_int((int)arg2).value)); -} - -/* - * @brief - * result = arg1 / arg2 - */ -static inline struct spl_fixed31_32 spl_fixpt_div(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2) -{ - return SPL_NAMESPACE(spl_fixpt_from_fraction(arg1.value, arg2.value)); -} - -/* - * @brief - * Reciprocal function - */ - -/* - * @brief - * result = reciprocal(arg) := 1 / arg - * - * @note - * No special actions taken in case argument is zero. - */ -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_recip(struct spl_fixed31_32 arg)); - -/* - * @brief - * Trigonometric functions - */ - -/* - * @brief - * result = sinc(arg) := sin(arg) / arg - * - * @note - * Argument specified in radians, - * internally it's normalized to [-2pi...2pi] range. - */ -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_sinc(struct spl_fixed31_32 arg)); - -/* - * @brief - * result = sin(arg) - * - * @note - * Argument specified in radians, - * internally it's normalized to [-2pi...2pi] range. - */ -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_sin(struct spl_fixed31_32 arg)); - -/* - * @brief - * result = cos(arg) - * - * @note - * Argument specified in radians - * and should be in [-2pi...2pi] range - - * passing arguments outside that range - * will cause incorrect result! - */ -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_cos(struct spl_fixed31_32 arg)); - -/* - * @brief - * Transcendent functions - */ - -/* - * @brief - * result = exp(arg) - * - * @note - * Currently, function is verified for abs(arg) <= 1. - */ -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_exp(struct spl_fixed31_32 arg)); - -/* - * @brief - * result = log(arg) - * - * @note - * Currently, abs(arg) should be less than 1. - * No normalization is done. - * Currently, no special actions taken - * in case of invalid argument(s). Take care! - */ -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_log(struct spl_fixed31_32 arg)); - -/* - * @brief - * Power function - */ - -/* - * @brief - * result = pow(arg1, arg2) - * - * @note - * Currently, abs(arg1) should be less than 1. Take care! - */ -static inline struct spl_fixed31_32 spl_fixpt_pow(struct spl_fixed31_32 arg1, struct spl_fixed31_32 arg2) -{ - if (arg1.value == 0) - return arg2.value == 0 ? spl_fixpt_one : spl_fixpt_zero; - - return SPL_NAMESPACE(spl_fixpt_exp( - SPL_NAMESPACE(spl_fixpt_mul( - SPL_NAMESPACE(spl_fixpt_log(arg1)), - arg2)))); -} - -/* - * @brief - * Rounding functions - */ - -/* - * @brief - * result = floor(arg) := greatest integer lower than or equal to arg - */ -static inline int spl_fixpt_floor(struct spl_fixed31_32 arg) -{ - unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value; - - if (arg.value >= 0) - return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART); - else - return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART); -} - -/* - * @brief - * result = round(arg) := integer nearest to arg - */ -static inline int spl_fixpt_round(struct spl_fixed31_32 arg) -{ - unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value; - - const long long summand = spl_fixpt_half.value; - - SPL_ASSERT(LLONG_MAX - (long long)arg_value >= summand); - - arg_value += summand; - - if (arg.value >= 0) - return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART); - else - return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART); -} - -/* - * @brief - * result = ceil(arg) := lowest integer greater than or equal to arg - */ -static inline int spl_fixpt_ceil(struct spl_fixed31_32 arg) -{ - unsigned long long arg_value = arg.value > 0 ? arg.value : -arg.value; - - const long long summand = spl_fixpt_one.value - - spl_fixpt_epsilon.value; - - SPL_ASSERT(LLONG_MAX - (long long)arg_value >= summand); - - arg_value += summand; - - if (arg.value >= 0) - return (int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART); - else - return -(int)(arg_value >> FIXED31_32_BITS_PER_FRACTIONAL_PART); -} - -/* the following two function are used in scaler hw programming to convert fixed - * point value to format 2 bits from integer part and 19 bits from fractional - * part. The same applies for u0d19, 0 bits from integer part and 19 bits from - * fractional - */ - -unsigned int SPL_NAMESPACE(spl_fixpt_u4d19(struct spl_fixed31_32 arg)); - -unsigned int SPL_NAMESPACE(spl_fixpt_u3d19(struct spl_fixed31_32 arg)); - -unsigned int SPL_NAMESPACE(spl_fixpt_u2d19(struct spl_fixed31_32 arg)); - -unsigned int SPL_NAMESPACE(spl_fixpt_u0d19(struct spl_fixed31_32 arg)); - -unsigned int SPL_NAMESPACE(spl_fixpt_clamp_u0d14(struct spl_fixed31_32 arg)); - -unsigned int SPL_NAMESPACE(spl_fixpt_clamp_u0d10(struct spl_fixed31_32 arg)); - -int SPL_NAMESPACE(spl_fixpt_s4d19(struct spl_fixed31_32 arg)); - -static inline struct spl_fixed31_32 spl_fixpt_truncate(struct spl_fixed31_32 arg, unsigned int frac_bits) -{ - bool negative = arg.value < 0; - - if (frac_bits >= FIXED31_32_BITS_PER_FRACTIONAL_PART) { - SPL_ASSERT(frac_bits == FIXED31_32_BITS_PER_FRACTIONAL_PART); - return arg; - } - - if (negative) - arg.value = -arg.value; - arg.value &= (~0ULL) << (FIXED31_32_BITS_PER_FRACTIONAL_PART - frac_bits); - if (negative) - arg.value = -arg.value; - return arg; -} - -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_from_ux_dy(unsigned int value, - unsigned int integer_bits, unsigned int fractional_bits)); -struct spl_fixed31_32 SPL_NAMESPACE(spl_fixpt_from_int_dy(unsigned int int_value, - unsigned int frac_value, - unsigned int integer_bits, - unsigned int fractional_bits)); +#include "dc/os_types.h" +#include "include/fixed31_32.h" + +#define spl_fixed31_32 fixed31_32 +#define spl_fixpt_mul dc_fixpt_mul +#define spl_fixpt_from_fraction dc_fixpt_from_fraction +#define spl_fixpt_u0d19 dc_fixpt_u0d19 +#define spl_fixpt_u3d19 dc_fixpt_u3d19 +#define spl_fixpt_le dc_fixpt_le + +#define spl_fixpt_add dc_fixpt_add +#define spl_fixpt_mul dc_fixpt_mul +#define spl_fixpt_div dc_fixpt_div + +#define spl_fixpt_from_int dc_fixpt_from_int +#define spl_fixpt_add_int dc_fixpt_add_int +#define spl_fixpt_mul_int dc_fixpt_mul_int +#define spl_fixpt_div_int dc_fixpt_div_int + +#define spl_fixpt_min dc_fixpt_min +#define spl_fixpt_one dc_fixpt_one +#define spl_fixpt_zero dc_fixpt_zero +#define spl_fixpt_ceil dc_fixpt_ceil +#define spl_fixpt_floor dc_fixpt_floor +#define spl_fixpt_recip dc_fixpt_recip +#define spl_fixpt_truncate dc_fixpt_truncate +#define spl_fixpt_round dc_fixpt_round #endif -- 2.54.0
