From 7c24e9a9b02b04dcaf9507acb94091ea70a2c02d Mon Sep 17 00:00:00 2001 From: Xavi Del Campo Date: Fri, 31 Jan 2020 10:32:23 +0100 Subject: Imported pristine psxsdk-20190410 from official repo --- libfixmath/fixmath/fix16.h | 167 +++++++++++++++++++++++++++++++++++++++++++ libfixmath/fixmath/fract32.h | 38 ++++++++++ libfixmath/fixmath/int64.h | 162 +++++++++++++++++++++++++++++++++++++++++ libfixmath/fixmath/uint32.h | 19 +++++ 4 files changed, 386 insertions(+) create mode 100755 libfixmath/fixmath/fix16.h create mode 100755 libfixmath/fixmath/fract32.h create mode 100755 libfixmath/fixmath/int64.h create mode 100755 libfixmath/fixmath/uint32.h (limited to 'libfixmath/fixmath') diff --git a/libfixmath/fixmath/fix16.h b/libfixmath/fixmath/fix16.h new file mode 100755 index 0000000..a2a49b1 --- /dev/null +++ b/libfixmath/fixmath/fix16.h @@ -0,0 +1,167 @@ +#ifndef __libfixmath_fix16_h__ +#define __libfixmath_fix16_h__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* These options may let the optimizer to remove some calls to the functions. + * Refer to http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html + */ +#ifndef FIXMATH_FUNC_ATTRS +# ifdef __GNUC__ +# define FIXMATH_FUNC_ATTRS __attribute__((leaf, nothrow, pure)) +# else +# define FIXMATH_FUNC_ATTRS +# endif +#endif + +#include + +typedef int32_t fix16_t; + +static const fix16_t FOUR_DIV_PI = 0x145F3; /*!< Fix16 value of 4/PI */ +static const fix16_t _FOUR_DIV_PI2 = 0xFFFF9840; /*!< Fix16 value of -4/PI² */ +static const fix16_t X4_CORRECTION_COMPONENT = 0x399A; /*!< Fix16 value of 0.225 */ +static const fix16_t PI_DIV_4 = 0x0000C90F; /*!< Fix16 value of PI/4 */ +static const fix16_t THREE_PI_DIV_4 = 0x00025B2F; /*!< Fix16 value of 3PI/4 */ + +static const fix16_t fix16_max = 0x7FFFFFFF; /*!< the maximum value of fix16_t */ +static const fix16_t fix16_min = 0x80000000; /*!< the minimum value of fix16_t */ +static const fix16_t fix16_overflow = 0x80000000; /*!< the value used to indicate overflows when FIXMATH_NO_OVERFLOW is not specified */ + +static const fix16_t fix16_pi = 205887; /*!< fix16_t value of pi */ +static const fix16_t fix16_e = 178145; /*!< fix16_t value of e */ +static const fix16_t fix16_one = 0x00010000; /*!< fix16_t value of 1 */ + +/* Conversion functions between fix16_t and float/integer. + * These are inlined to allow compiler to optimize away constant numbers + */ +static inline fix16_t fix16_from_int(int a) { return a * fix16_one; } +static inline float fix16_to_float(fix16_t a) { return (float)a / fix16_one; } +static inline double fix16_to_dbl(fix16_t a) { return (double)a / fix16_one; } + +static inline int fix16_to_int(fix16_t a) +{ +#ifdef FIXMATH_NO_ROUNDING + return a >> 16; +#else + if (a >= 0) + return (a + fix16_one / 2) / fix16_one; + else + return (a - fix16_one / 2) / fix16_one; +#endif +} + +static inline fix16_t fix16_from_float(float a) +{ + float temp = a * fix16_one; +#ifndef FIXMATH_NO_ROUNDING + temp += (temp >= 0) ? 0.5f : -0.5f; +#endif + return (fix16_t)temp; +} + +static inline fix16_t fix16_from_dbl(double a) +{ + double temp = a * fix16_one; +#ifndef FIXMATH_NO_ROUNDING + temp += (temp >= 0) ? 0.5f : -0.5f; +#endif + return (fix16_t)temp; +} + +/* Subtraction and addition with (optional) overflow detection. */ +#ifdef FIXMATH_NO_OVERFLOW + +static inline fix16_t fix16_add(fix16_t inArg0, fix16_t inArg1) { return (inArg0 + inArg1); } +static inline fix16_t fix16_sub(fix16_t inArg0, fix16_t inArg1) { return (inArg0 - inArg1); } + +#else + +extern fix16_t fix16_add(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS; +extern fix16_t fix16_sub(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS; + +/* Saturating arithmetic */ +extern fix16_t fix16_sadd(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS; +extern fix16_t fix16_ssub(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS; + +#endif + +/*! Multiplies the two given fix16_t's and returns the result. +*/ +extern fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS; + +/*! Divides the first given fix16_t by the second and returns the result. +*/ +extern fix16_t fix16_div(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS; + +#ifndef FIXMATH_NO_OVERFLOW +/*! Performs a saturated multiplication (overflow-protected) of the two given fix16_t's and returns the result. +*/ +extern fix16_t fix16_smul(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS; + +/*! Performs a saturated division (overflow-protected) of the first fix16_t by the second and returns the result. +*/ +extern fix16_t fix16_sdiv(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS; +#endif + +/*! Returns the linear interpolation: (inArg0 * (1 - inFract)) + (inArg1 * inFract) +*/ +extern fix16_t fix16_lerp8(fix16_t inArg0, fix16_t inArg1, uint8_t inFract) FIXMATH_FUNC_ATTRS; +extern fix16_t fix16_lerp16(fix16_t inArg0, fix16_t inArg1, uint16_t inFract) FIXMATH_FUNC_ATTRS; +#ifndef FIXMATH_NO_64BIT +extern fix16_t fix16_lerp32(fix16_t inArg0, fix16_t inArg1, uint32_t inFract) FIXMATH_FUNC_ATTRS; +#endif + +/*! Returns the sine of the given fix16_t. +*/ +extern fix16_t fix16_sin_parabola(fix16_t inAngle) FIXMATH_FUNC_ATTRS; + +/*! Returns the sine of the given fix16_t. +*/ +extern fix16_t fix16_sin(fix16_t inAngle) FIXMATH_FUNC_ATTRS; + +/*! Returns the cosine of the given fix16_t. +*/ +extern fix16_t fix16_cos(fix16_t inAngle) FIXMATH_FUNC_ATTRS; + +/*! Returns the tangent of the given fix16_t. +*/ +extern fix16_t fix16_tan(fix16_t inAngle) FIXMATH_FUNC_ATTRS; + +/*! Returns the arcsine of the given fix16_t. +*/ +extern fix16_t fix16_asin(fix16_t inValue) FIXMATH_FUNC_ATTRS; + +/*! Returns the arccosine of the given fix16_t. +*/ +extern fix16_t fix16_acos(fix16_t inValue) FIXMATH_FUNC_ATTRS; + +/*! Returns the arctangent of the given fix16_t. +*/ +extern fix16_t fix16_atan(fix16_t inValue) FIXMATH_FUNC_ATTRS; + +/*! Returns the arctangent of inY/inX. +*/ +extern fix16_t fix16_atan2(fix16_t inY, fix16_t inX) FIXMATH_FUNC_ATTRS; + + + +/*! Returns the square root of the given fix16_t. +*/ +extern fix16_t fix16_sqrt(fix16_t inValue) FIXMATH_FUNC_ATTRS; + + + +/*! Returns the exponent (e^) of the given fix16_t. +*/ +extern fix16_t fix16_exp(fix16_t inValue) FIXMATH_FUNC_ATTRS; + +#ifdef __cplusplus +} +#include "fix16.hpp" +#endif + +#endif diff --git a/libfixmath/fixmath/fract32.h b/libfixmath/fixmath/fract32.h new file mode 100755 index 0000000..ee1f1c6 --- /dev/null +++ b/libfixmath/fixmath/fract32.h @@ -0,0 +1,38 @@ +#ifndef __libfixmath_fract32_h__ +#define __libfixmath_fract32_h__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +typedef uint32_t fract32_t; + +/*! Creates a fraction using unsigned integers. + \param inNumerator the unsigned integer numerator + \param inDenominator the unsigned integer denominator + \return a fraction using the given numerator and denominator +*/ +extern fract32_t fract32_create(uint32_t inNumerator, uint32_t inDenominator); + +/*! Inverts the given fraction, swapping the numerator and the denominator. +*/ +extern fract32_t fract32_invert(fract32_t inFract); + +#ifndef FIXMATH_NO_64BIT +/*! Performs unsigned saturated (overflow-protected) multiplication with the two given fractions and returns the result as an unsigned integer. +*/ +extern uint32_t fract32_usmul(uint32_t inVal, fract32_t inFract); + +/*! Performs saturated (overflow-protected) multiplication with the two given fractions and returns the result as a signed integer. +*/ +extern int32_t fract32_smul(int32_t inVal, fract32_t inFract); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libfixmath/fixmath/int64.h b/libfixmath/fixmath/int64.h new file mode 100755 index 0000000..4d716bf --- /dev/null +++ b/libfixmath/fixmath/int64.h @@ -0,0 +1,162 @@ +#ifndef __libfixmath_int64_h__ +#define __libfixmath_int64_h__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef FIXMATH_NO_64BIT +static inline int64_t int64_const(int32_t hi, uint32_t lo) { return (((int64_t)hi << 32) | lo); } +static inline int64_t int64_from_int32(int32_t x) { return (int64_t)x; } +static inline int32_t int64_hi(int64_t x) { return (x >> 32); } +static inline uint32_t int64_lo(int64_t x) { return (x & ((1ULL << 32) - 1)); } + +static inline int64_t int64_add(int64_t x, int64_t y) { return (x + y); } +static inline int64_t int64_neg(int64_t x) { return (-x); } +static inline int64_t int64_sub(int64_t x, int64_t y) { return (x - y); } +static inline int64_t int64_shift(int64_t x, int8_t y) { return (y < 0 ? (x >> -y) : (x << y)); } + +static inline int64_t int64_mul_i32_i32(int32_t x, int32_t y) { return (x * y); } +static inline int64_t int64_mul_i64_i32(int64_t x, int32_t y) { return (x * y); } + +static inline int64_t int64_div_i64_i32(int64_t x, int32_t y) { return (x / y); } + +static inline int int64_cmp_eq(int64_t x, int64_t y) { return (x == y); } +static inline int int64_cmp_ne(int64_t x, int64_t y) { return (x != y); } +static inline int int64_cmp_gt(int64_t x, int64_t y) { return (x > y); } +static inline int int64_cmp_ge(int64_t x, int64_t y) { return (x >= y); } +static inline int int64_cmp_lt(int64_t x, int64_t y) { return (x < y); } +static inline int int64_cmp_le(int64_t x, int64_t y) { return (x <= y); } +#else + +typedef struct { + int32_t hi; + uint32_t lo; +} __int64_t; + +static inline __int64_t int64_const(int32_t hi, uint32_t lo) { return (__int64_t){ hi, lo }; } +static inline __int64_t int64_from_int32(int32_t x) { return (__int64_t){ (x < 0 ? -1 : 0), x }; } +static inline int32_t int64_hi(__int64_t x) { return x.hi; } +static inline uint32_t int64_lo(__int64_t x) { return x.lo; } + +static inline int int64_cmp_eq(__int64_t x, __int64_t y) { return ((x.hi == y.hi) && (x.lo == y.lo)); } +static inline int int64_cmp_ne(__int64_t x, __int64_t y) { return ((x.hi != y.hi) || (x.lo != y.lo)); } +static inline int int64_cmp_gt(__int64_t x, __int64_t y) { return ((x.hi > y.hi) || ((x.hi == y.hi) && (x.lo > y.lo))); } +static inline int int64_cmp_ge(__int64_t x, __int64_t y) { return ((x.hi > y.hi) || ((x.hi == y.hi) && (x.lo >= y.lo))); } +static inline int int64_cmp_lt(__int64_t x, __int64_t y) { return ((x.hi < y.hi) || ((x.hi == y.hi) && (x.lo < y.lo))); } +static inline int int64_cmp_le(__int64_t x, __int64_t y) { return ((x.hi < y.hi) || ((x.hi == y.hi) && (x.lo <= y.lo))); } + +static inline __int64_t int64_add(__int64_t x, __int64_t y) { + __int64_t ret; + ret.hi = x.hi + y.hi; + ret.lo = x.lo + y.lo; + if((ret.lo < x.lo) || (ret.hi < y.hi)) + ret.hi++; + return ret; +} + +static inline __int64_t int64_neg(__int64_t x) { + __int64_t ret; + ret.hi = ~x.hi; + ret.lo = ~x.lo + 1; + if(ret.lo == 0) + ret.hi++; + return ret; +} + +static inline __int64_t int64_sub(__int64_t x, __int64_t y) { + return int64_add(x, int64_neg(y)); +} + +static inline __int64_t int64_shift(__int64_t x, int8_t y) { + __int64_t ret; + if(y > 0) { + if(y >= 32) + return (__int64_t){ 0, 0 }; + ret.hi = (x.hi << y) | (x.lo >> (32 - y)); + ret.lo = (x.lo << y); + } else { + y = -y; + if(y >= 32) + return (__int64_t){ 0, 0 }; + ret.lo = (x.lo >> y) | (x.hi << (32 - y)); + ret.hi = (x.hi >> y); + } + return ret; +} + +static inline __int64_t int64_mul_i32_i32(int32_t x, int32_t y) { + int16_t hi[2] = { (x >> 16), (y >> 16) }; + uint16_t lo[2] = { (x & 0xFFFF), (y & 0xFFFF) }; + + int32_t r_hi = hi[0] * hi[1]; + int32_t r_md = (hi[0] * lo[1]) + (hi[1] * lo[0]); + uint32_t r_lo = lo[0] * lo[1]; + + r_hi += (r_md >> 16); + r_lo += (r_md << 16); + + return (__int64_t){ r_hi, r_lo }; +} + +static inline __int64_t int64_mul_i64_i32(__int64_t x, int32_t y) { + int neg = ((x.hi ^ y) < 0); + if(x.hi < 0) + x = int64_neg(x); + if(y < 0) + y = -y; + + uint32_t _x[4] = { (x.hi >> 16), (x.hi & 0xFFFF), (x.lo >> 16), (x.lo & 0xFFFF) }; + uint32_t _y[2] = { (y >> 16), (y & 0xFFFF) }; + + uint32_t r[4]; + r[0] = (_x[0] * _y[0]); + r[1] = (_x[1] * _y[0]) + (_x[0] * _y[1]); + r[2] = (_x[1] * _y[1]) + (_x[2] * _y[0]); + r[3] = (_x[2] * _y[0]) + (_x[1] * _y[1]); + + __int64_t ret; + ret.lo = r[0] + (r[1] << 16); + ret.hi = (r[3] << 16) + r[2] + (r[1] >> 16); + return (neg ? int64_neg(ret) : ret); +} + +static inline __int64_t int64_div_i64_i32(__int64_t x, int32_t y) { + int neg = ((x.hi ^ y) < 0); + if(x.hi < 0) + x = int64_neg(x); + if(y < 0) + y = -y; + + __int64_t ret = { (x.hi / y) , (x.lo / y) }; + x.hi = x.hi % y; + x.lo = x.lo % y; + + __int64_t _y = int64_from_int32(y); + + __int64_t i; + for(i = int64_from_int32(1); int64_cmp_lt(_y, x); _y = int64_shift(_y, 1), i = int64_shift(i, 1)); + + while(x.hi) { + _y = int64_shift(_y, -1); + i = int64_shift(i, -1); + if(int64_cmp_ge(x, _y)) { + x = int64_sub(x, _y); + ret = int64_add(ret, i); + } + } + + ret = int64_add(ret, int64_from_int32(x.lo / y)); + return (neg ? int64_neg(ret) : ret); +} + +#define int64_t __int64_t + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libfixmath/fixmath/uint32.h b/libfixmath/fixmath/uint32.h new file mode 100755 index 0000000..1303338 --- /dev/null +++ b/libfixmath/fixmath/uint32.h @@ -0,0 +1,19 @@ +#ifndef __libfixmath_uint32_h__ +#define __libfixmath_uint32_h__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +/*! Performs an unsigned log-base2 on the specified unsigned integer and returns the result. +*/ +extern uint32_t uint32_log2(uint32_t inVal); + +#ifdef __cplusplus +} +#endif + +#endif -- cgit v1.2.3