From f3e2969e372570ccbcdb06bdf8c5072a4df683b5 Mon Sep 17 00:00:00 2001 From: ZERICO2005 <71151164+ZERICO2005@users.noreply.github.com> Date: Sun, 20 Apr 2025 21:25:30 -0600 Subject: [PATCH] float classification routines can now be constant folded in C. Also fixed math_test.cpp and constexpr addressof --- src/libc/include/math.h | 185 ++++- src/libcxx/include/memory | 2 +- src/libcxx/math_test.cpp | 136 ++-- .../compiletime_classification/autotest.json | 43 ++ .../compiletime_classification/makefile | 17 + .../compiletime_classification/src/main.c | 712 ++++++++++++++++++ .../compiletime_classification/src/test.asm | 44 ++ 7 files changed, 1043 insertions(+), 96 deletions(-) create mode 100644 test/floating_point/compiletime_classification/autotest.json create mode 100644 test/floating_point/compiletime_classification/makefile create mode 100644 test/floating_point/compiletime_classification/src/main.c create mode 100644 test/floating_point/compiletime_classification/src/test.asm diff --git a/src/libc/include/math.h b/src/libc/include/math.h index b0f1e7a74..eec450a8f 100644 --- a/src/libc/include/math.h +++ b/src/libc/include/math.h @@ -9,6 +9,137 @@ #include <__math_def.h> +static inline __attribute__((__always_inline__)) +bool __signbitf(float __x) { + if (__builtin_constant_p(__x)) { + return (__builtin_copysign(1.0f, __x) < 0.0f); + } + return _signbitf(__x); +} +static inline __attribute__((__always_inline__)) +bool __signbitl(long double __x) { + if (__builtin_constant_p(__x)) { + return (__builtin_copysign(1.0L, __x) < 0.0L); + } + return _signbitl(__x); +} + +static inline __attribute__((__always_inline__)) +bool __issignalingf(float __x) { + return _issignalingf(__x); +} +static inline __attribute__((__always_inline__)) +bool __issignalingl(long double __x) { + return _issignalingl(__x); +} + +static inline __attribute__((__always_inline__)) +bool __isnanf(float __x) { + if (__builtin_constant_p(__x)) { + return __builtin_isnan(__x); + } + return _isnanf(__x); +} +static inline __attribute__((__always_inline__)) +bool __isnanl(long double __x) { + if (__builtin_constant_p(__x)) { + return __builtin_isnan(__x); + } + return _isnanl(__x); +} + +static inline __attribute__((__always_inline__)) +bool __isinff(float __x) { + if (__builtin_constant_p(__x)) { + return __builtin_isinf(__x); + } + return _isinff(__x); +} +static inline __attribute__((__always_inline__)) +bool __isinfl(long double __x) { + if (__builtin_constant_p(__x)) { + return __builtin_isinf(__x); + } + return _isinfl(__x); +} + +static inline __attribute__((__always_inline__)) +bool __isfinitef(float __x) { + if (__builtin_constant_p(__x)) { + return __builtin_isfinite(__x); + } + return _isfinitef(__x); +} +static inline __attribute__((__always_inline__)) +bool __isfinitel(long double __x) { + if (__builtin_constant_p(__x)) { + return __builtin_isfinite(__x); + } + return _isfinitel(__x); +} + +static inline __attribute__((__always_inline__)) +bool __isnormalf(float __x) { + if (__builtin_constant_p(__x)) { + return __builtin_isnormal(__x); + } + return _isnormalf(__x); +} +static inline __attribute__((__always_inline__)) +bool __isnormall(long double __x) { + if (__builtin_constant_p(__x)) { + return __builtin_isnormal(__x); + } + return _isnormall(__x); +} + +static inline __attribute__((__always_inline__)) +bool __issubnormalf(float __x) { + if (__builtin_constant_p(__x)) { + return (FP_SUBNORMAL == __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x)); + } + return _issubnormalf(__x); +} +static inline __attribute__((__always_inline__)) +bool __issubnormall(long double __x) { + if (__builtin_constant_p(__x)) { + return (FP_SUBNORMAL == __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x)); + } + return _issubnormall(__x); +} + +static inline __attribute__((__always_inline__)) +bool __iszerof(float __x) { + if (__builtin_constant_p(__x)) { + return (__x == 0.0f); + } + return _iszerof(__x); +} +static inline __attribute__((__always_inline__)) +bool __iszerol(long double __x) { + if (__builtin_constant_p(__x)) { + return (__x == 0.0L); + } + return _iszerol(__x); +} + +static inline __attribute__((__always_inline__)) +int __fpclassifyf(float __x) { + if (__builtin_constant_p(__x)) { + return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); + } else { + return _fpclassifyf(__x); + } +} +static inline __attribute__((__always_inline__)) +int __fpclassifyl(long double __x) { + if (__builtin_constant_p(__x)) { + return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); + } else { + return _fpclassifyl(__x); + } +} + #define __math_promote(x) _Generic((x), \ float: ((float)0.f), \ default: ((double)0.), \ @@ -16,57 +147,57 @@ ) #define signbit(x) ((int)_Generic(__math_promote(x), \ - long double: _signbitl, \ - default: _signbitf, \ - float: _signbitf \ + long double: __signbitl, \ + default: __signbitf, \ + float: __signbitf \ )(x)) #define issignaling(x) ((int)_Generic(__math_promote(x), \ - long double: _issignalingl, \ - default: _issignalingf, \ - float: _issignalingf \ + long double: __issignalingl, \ + default: __issignalingf, \ + float: __issignalingf \ )(x)) #define isnan(x) ((int)_Generic(__math_promote(x), \ - long double: _isnanl, \ - default: _isnanf, \ - float: _isnanf \ + long double: __isnanl, \ + default: __isnanf, \ + float: __isnanf \ )(x)) #define isinf(x) ((int)_Generic(__math_promote(x), \ - long double: _isinfl, \ - default: _isinff, \ - float: _isinff \ + long double: __isinfl, \ + default: __isinff, \ + float: __isinff \ )(x)) #define isfinite(x) ((int)_Generic(__math_promote(x), \ - long double: _isfinitel, \ - default: _isfinitef, \ - float: _isfinitef \ + long double: __isfinitel, \ + default: __isfinitef, \ + float: __isfinitef \ )(x)) #define isnormal(x) ((int)_Generic(__math_promote(x), \ - long double: _isnormall, \ - default: _isnormalf, \ - float: _isnormalf \ + long double: __isnormall, \ + default: __isnormalf, \ + float: __isnormalf \ )(x)) #define issubnormal(x) ((int)_Generic(__math_promote(x), \ - long double: _issubnormall, \ - default: _issubnormalf, \ - float: _issubnormalf \ + long double: __issubnormall, \ + default: __issubnormalf, \ + float: __issubnormalf \ )(x)) #define iszero(x) ((int)_Generic(__math_promote(x), \ - long double: _iszerol, \ - default: _iszerof, \ - float: _iszerof \ + long double: __iszerol, \ + default: __iszerof, \ + float: __iszerof \ )(x)) #define fpclassify(x) ((int)_Generic(__math_promote(x), \ - long double: _fpclassifyl, \ - default: _fpclassifyf, \ - float: _fpclassifyf \ + long double: __fpclassifyl, \ + default: __fpclassifyf, \ + float: __fpclassifyf \ )(x)) #define isgreater(x, y) __builtin_isgreater(x, y) diff --git a/src/libcxx/include/memory b/src/libcxx/include/memory index 3fba7d73a..8d49ecca7 100644 --- a/src/libcxx/include/memory +++ b/src/libcxx/include/memory @@ -7,7 +7,7 @@ namespace std { template -inline _Tp* addressof(_Tp& __x) noexcept { +constexpr inline _Tp* addressof(_Tp& __x) noexcept { return __builtin_addressof(__x); } diff --git a/src/libcxx/math_test.cpp b/src/libcxx/math_test.cpp index 56a8467e0..52f71ab92 100644 --- a/src/libcxx/math_test.cpp +++ b/src/libcxx/math_test.cpp @@ -75,23 +75,23 @@ C((!iszero (std::numeric_limits::denorm_min()))); /* MIN */ -C((!signbit (std::numeric_limits::min()))); -C((!issignaling(std::numeric_limits::min()))); -C((!isnan (std::numeric_limits::min()))); -C((!isinf (std::numeric_limits::min()))); -C(( isfinite (std::numeric_limits::min()))); -C(( isnormal (std::numeric_limits::min()))); -C((!issubnormal(std::numeric_limits::min()))); -C((!iszero (std::numeric_limits::min()))); - -C((!signbit (std::numeric_limits::min()))); -C((!issignaling(std::numeric_limits::min()))); -C((!isnan (std::numeric_limits::min()))); -C((!isinf (std::numeric_limits::min()))); -C(( isfinite (std::numeric_limits::min()))); -C(( isnormal (std::numeric_limits::min()))); -C((!issubnormal(std::numeric_limits::min()))); -C((!iszero (std::numeric_limits::min()))); +C((!signbit (std::numeric_limits::min()))); +C((!issignaling(std::numeric_limits::min()))); +C((!isnan (std::numeric_limits::min()))); +C((!isinf (std::numeric_limits::min()))); +C(( isfinite (std::numeric_limits::min()))); +C(( isnormal (std::numeric_limits::min()))); +C((!issubnormal(std::numeric_limits::min()))); +C((!iszero (std::numeric_limits::min()))); + +C((!signbit (std::numeric_limits::min()))); +C((!issignaling(std::numeric_limits::min()))); +C((!isnan (std::numeric_limits::min()))); +C((!isinf (std::numeric_limits::min()))); +C(( isfinite (std::numeric_limits::min()))); +C(( isnormal (std::numeric_limits::min()))); +C((!issubnormal(std::numeric_limits::min()))); +C((!iszero (std::numeric_limits::min()))); C((!signbit (std::numeric_limits::min()))); C((!issignaling(std::numeric_limits::min()))); @@ -191,23 +191,23 @@ C((!iszero (3.1415926535897932384626433832795L))); /* MAX */ -C((!signbit (std::numeric_limits::max()))); -C((!issignaling(std::numeric_limits::max()))); -C((!isnan (std::numeric_limits::max()))); -C((!isinf (std::numeric_limits::max()))); -C(( isfinite (std::numeric_limits::max()))); -C(( isnormal (std::numeric_limits::max()))); -C((!issubnormal(std::numeric_limits::max()))); -C((!iszero (std::numeric_limits::max()))); - -C((!signbit (std::numeric_limits::max()))); -C((!issignaling(std::numeric_limits::max()))); -C((!isnan (std::numeric_limits::max()))); -C((!isinf (std::numeric_limits::max()))); -C(( isfinite (std::numeric_limits::max()))); -C(( isnormal (std::numeric_limits::max()))); -C((!issubnormal(std::numeric_limits::max()))); -C((!iszero (std::numeric_limits::max()))); +C((!signbit (std::numeric_limits::max()))); +C((!issignaling(std::numeric_limits::max()))); +C((!isnan (std::numeric_limits::max()))); +C((!isinf (std::numeric_limits::max()))); +C(( isfinite (std::numeric_limits::max()))); +C(( isnormal (std::numeric_limits::max()))); +C((!issubnormal(std::numeric_limits::max()))); +C((!iszero (std::numeric_limits::max()))); + +C((!signbit (std::numeric_limits::max()))); +C((!issignaling(std::numeric_limits::max()))); +C((!isnan (std::numeric_limits::max()))); +C((!isinf (std::numeric_limits::max()))); +C(( isfinite (std::numeric_limits::max()))); +C(( isnormal (std::numeric_limits::max()))); +C((!issubnormal(std::numeric_limits::max()))); +C((!iszero (std::numeric_limits::max()))); C((!signbit (std::numeric_limits::max()))); C((!issignaling(std::numeric_limits::max()))); @@ -369,23 +369,23 @@ C((!iszero (-std::numeric_limits::denorm_min()))); /* MIN */ -C(( signbit (-std::numeric_limits::min()))); -C((!issignaling(-std::numeric_limits::min()))); -C((!isnan (-std::numeric_limits::min()))); -C((!isinf (-std::numeric_limits::min()))); -C(( isfinite (-std::numeric_limits::min()))); -C(( isnormal (-std::numeric_limits::min()))); -C((!issubnormal(-std::numeric_limits::min()))); -C((!iszero (-std::numeric_limits::min()))); - -C(( signbit (-std::numeric_limits::min()))); -C((!issignaling(-std::numeric_limits::min()))); -C((!isnan (-std::numeric_limits::min()))); -C((!isinf (-std::numeric_limits::min()))); -C(( isfinite (-std::numeric_limits::min()))); -C(( isnormal (-std::numeric_limits::min()))); -C((!issubnormal(-std::numeric_limits::min()))); -C((!iszero (-std::numeric_limits::min()))); +C(( signbit (-std::numeric_limits::min()))); +C((!issignaling(-std::numeric_limits::min()))); +C((!isnan (-std::numeric_limits::min()))); +C((!isinf (-std::numeric_limits::min()))); +C(( isfinite (-std::numeric_limits::min()))); +C(( isnormal (-std::numeric_limits::min()))); +C((!issubnormal(-std::numeric_limits::min()))); +C((!iszero (-std::numeric_limits::min()))); + +C(( signbit (-std::numeric_limits::min()))); +C((!issignaling(-std::numeric_limits::min()))); +C((!isnan (-std::numeric_limits::min()))); +C((!isinf (-std::numeric_limits::min()))); +C(( isfinite (-std::numeric_limits::min()))); +C(( isnormal (-std::numeric_limits::min()))); +C((!issubnormal(-std::numeric_limits::min()))); +C((!iszero (-std::numeric_limits::min()))); C(( signbit (-std::numeric_limits::min()))); C((!issignaling(-std::numeric_limits::min()))); @@ -485,23 +485,23 @@ C((!iszero (-3.1415926535897932384626433832795L))); /* MAX */ -C(( signbit (-std::numeric_limits::max()))); -C((!issignaling(-std::numeric_limits::max()))); -C((!isnan (-std::numeric_limits::max()))); -C((!isinf (-std::numeric_limits::max()))); -C(( isfinite (-std::numeric_limits::max()))); -C(( isnormal (-std::numeric_limits::max()))); -C((!issubnormal(-std::numeric_limits::max()))); -C((!iszero (-std::numeric_limits::max()))); - -C(( signbit (-std::numeric_limits::max()))); -C((!issignaling(-std::numeric_limits::max()))); -C((!isnan (-std::numeric_limits::max()))); -C((!isinf (-std::numeric_limits::max()))); -C(( isfinite (-std::numeric_limits::max()))); -C(( isnormal (-std::numeric_limits::max()))); -C((!issubnormal(-std::numeric_limits::max()))); -C((!iszero (-std::numeric_limits::max()))); +C(( signbit (-std::numeric_limits::max()))); +C((!issignaling(-std::numeric_limits::max()))); +C((!isnan (-std::numeric_limits::max()))); +C((!isinf (-std::numeric_limits::max()))); +C(( isfinite (-std::numeric_limits::max()))); +C(( isnormal (-std::numeric_limits::max()))); +C((!issubnormal(-std::numeric_limits::max()))); +C((!iszero (-std::numeric_limits::max()))); + +C(( signbit (-std::numeric_limits::max()))); +C((!issignaling(-std::numeric_limits::max()))); +C((!isnan (-std::numeric_limits::max()))); +C((!isinf (-std::numeric_limits::max()))); +C(( isfinite (-std::numeric_limits::max()))); +C(( isnormal (-std::numeric_limits::max()))); +C((!issubnormal(-std::numeric_limits::max()))); +C((!iszero (-std::numeric_limits::max()))); C(( signbit (-std::numeric_limits::max()))); C((!issignaling(-std::numeric_limits::max()))); diff --git a/test/floating_point/compiletime_classification/autotest.json b/test/floating_point/compiletime_classification/autotest.json new file mode 100644 index 000000000..6dfa8370d --- /dev/null +++ b/test/floating_point/compiletime_classification/autotest.json @@ -0,0 +1,43 @@ +{ + "transfer_files": [ + "bin/DEMO.8xp" + ], + "target": { + "name": "DEMO", + "isASM": true + }, + "sequence": [ + "action|launch", + "delay|4000", + "hashWait|1", + "key|enter", + "delay|400", + "hashWait|2" + ], + "hashes": { + "1": { + "description": "All tests passed or GDB1 error", + "timeout": 6000, + "start": "vram_start", + "size": "vram_16_size", + "expected_CRCs": [ + "38E2AD5A", + "2C812DC2" + ] + }, + "2": { + "description": "Exit or GDB1 error", + "start": "vram_start", + "size": "vram_16_size", + "expected_CRCs": [ + "FFAF89BA", + "101734A5", + "9DA19F44", + "A32840C8", + "349F4775", + "271A9FBF", + "82FD0B1E" + ] + } + } +} diff --git a/test/floating_point/compiletime_classification/makefile b/test/floating_point/compiletime_classification/makefile new file mode 100644 index 000000000..953f6ea3d --- /dev/null +++ b/test/floating_point/compiletime_classification/makefile @@ -0,0 +1,17 @@ +# ---------------------------- +# Makefile Options +# ---------------------------- + +NAME = DEMO +ICON = icon.png +DESCRIPTION = "CE C Toolchain Demo" +COMPRESSED = NO + +CFLAGS = -Wall -Wextra -Wshadow -Wimplicit-float-conversion -Wimplicit-int-float-conversion -std=c17 -Oz +CXXFLAGS = -Wall -Wextra -Wshadow -Wimplicit-float-conversion -Wimplicit-int-float-conversion -std=c++20 -Oz + +PREFER_OS_LIBC = NO + +# ---------------------------- + +include $(shell cedev-config --makefile) diff --git a/test/floating_point/compiletime_classification/src/main.c b/test/floating_point/compiletime_classification/src/main.c new file mode 100644 index 000000000..da7d8ea38 --- /dev/null +++ b/test/floating_point/compiletime_classification/src/main.c @@ -0,0 +1,712 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +#error "This test is for C only" +#endif + +#define C(expr) if (!(expr)) { return __LINE__; } + +// basically a copy of math_test.cpp +int run_test(void) { + + // can't get issignaling to work at compile time at the moment + #undef issignaling + #define issignaling(...) true || true + +//------------------------------------------------------------------------------ +// Positive value tests +//------------------------------------------------------------------------------ + + /* ZERO */ + + C((!signbit (0.0f))); + C((!issignaling(0.0f))); + C((!isnan (0.0f))); + C((!isinf (0.0f))); + C(( isfinite (0.0f))); + C((!isnormal (0.0f))); + C((!issubnormal(0.0f))); + C(( iszero (0.0f))); + + C((!signbit (0.0))); + C((!issignaling(0.0))); + C((!isnan (0.0))); + C((!isinf (0.0))); + C(( isfinite (0.0))); + C((!isnormal (0.0))); + C((!issubnormal(0.0))); + C(( iszero (0.0))); + + C((!signbit (0.0L))); + C((!issignaling(0.0L))); + C((!isnan (0.0L))); + C((!isinf (0.0L))); + C(( isfinite (0.0L))); + C((!isnormal (0.0L))); + C((!issubnormal(0.0L))); + C(( iszero (0.0L))); + + /* TRUE_MIN */ + + C((!signbit (FLT_TRUE_MIN))); + C((!issignaling(FLT_TRUE_MIN))); + C((!isnan (FLT_TRUE_MIN))); + C((!isinf (FLT_TRUE_MIN))); + C(( isfinite (FLT_TRUE_MIN))); + C((!isnormal (FLT_TRUE_MIN))); + C(( issubnormal(FLT_TRUE_MIN))); + C((!iszero (FLT_TRUE_MIN))); + + C((!signbit (DBL_TRUE_MIN))); + C((!issignaling(DBL_TRUE_MIN))); + C((!isnan (DBL_TRUE_MIN))); + C((!isinf (DBL_TRUE_MIN))); + C(( isfinite (DBL_TRUE_MIN))); + C((!isnormal (DBL_TRUE_MIN))); + C(( issubnormal(DBL_TRUE_MIN))); + C((!iszero (DBL_TRUE_MIN))); + + C((!signbit (LDBL_TRUE_MIN))); + C((!issignaling(LDBL_TRUE_MIN))); + C((!isnan (LDBL_TRUE_MIN))); + C((!isinf (LDBL_TRUE_MIN))); + C(( isfinite (LDBL_TRUE_MIN))); + C((!isnormal (LDBL_TRUE_MIN))); + C(( issubnormal(LDBL_TRUE_MIN))); + C((!iszero (LDBL_TRUE_MIN))); + + /* MIN */ + + C((!signbit (FLT_MIN))); + C((!issignaling(FLT_MIN))); + C((!isnan (FLT_MIN))); + C((!isinf (FLT_MIN))); + C(( isfinite (FLT_MIN))); + C(( isnormal (FLT_MIN))); + C((!issubnormal(FLT_MIN))); + C((!iszero (FLT_MIN))); + + C((!signbit (DBL_MIN))); + C((!issignaling(DBL_MIN))); + C((!isnan (DBL_MIN))); + C((!isinf (DBL_MIN))); + C(( isfinite (DBL_MIN))); + C(( isnormal (DBL_MIN))); + C((!issubnormal(DBL_MIN))); + C((!iszero (DBL_MIN))); + + C((!signbit (LDBL_MIN))); + C((!issignaling(LDBL_MIN))); + C((!isnan (LDBL_MIN))); + C((!isinf (LDBL_MIN))); + C(( isfinite (LDBL_MIN))); + C(( isnormal (LDBL_MIN))); + C((!issubnormal(LDBL_MIN))); + C((!iszero (LDBL_MIN))); + + /* RECIP PI */ + + C((!signbit (0.31830988618379067153776752674503f))); + C((!issignaling(0.31830988618379067153776752674503f))); + C((!isnan (0.31830988618379067153776752674503f))); + C((!isinf (0.31830988618379067153776752674503f))); + C(( isfinite (0.31830988618379067153776752674503f))); + C(( isnormal (0.31830988618379067153776752674503f))); + C((!issubnormal(0.31830988618379067153776752674503f))); + C((!iszero (0.31830988618379067153776752674503f))); + + C((!signbit (0.31830988618379067153776752674503))); + C((!issignaling(0.31830988618379067153776752674503))); + C((!isnan (0.31830988618379067153776752674503))); + C((!isinf (0.31830988618379067153776752674503))); + C(( isfinite (0.31830988618379067153776752674503))); + C(( isnormal (0.31830988618379067153776752674503))); + C((!issubnormal(0.31830988618379067153776752674503))); + C((!iszero (0.31830988618379067153776752674503))); + + C((!signbit (0.31830988618379067153776752674503L))); + C((!issignaling(0.31830988618379067153776752674503L))); + C((!isnan (0.31830988618379067153776752674503L))); + C((!isinf (0.31830988618379067153776752674503L))); + C(( isfinite (0.31830988618379067153776752674503L))); + C(( isnormal (0.31830988618379067153776752674503L))); + C((!issubnormal(0.31830988618379067153776752674503L))); + C((!iszero (0.31830988618379067153776752674503L))); + + /* ONE */ + + C((!signbit (1.0f))); + C((!issignaling(1.0f))); + C((!isnan (1.0f))); + C((!isinf (1.0f))); + C(( isfinite (1.0f))); + C(( isnormal (1.0f))); + C((!issubnormal(1.0f))); + C((!iszero (1.0f))); + + C((!signbit (1.0))); + C((!issignaling(1.0))); + C((!isnan (1.0))); + C((!isinf (1.0))); + C(( isfinite (1.0))); + C(( isnormal (1.0))); + C((!issubnormal(1.0))); + C((!iszero (1.0))); + + C((!signbit (1.0L))); + C((!issignaling(1.0L))); + C((!isnan (1.0L))); + C((!isinf (1.0L))); + C(( isfinite (1.0L))); + C(( isnormal (1.0L))); + C((!issubnormal(1.0L))); + C((!iszero (1.0L))); + + /* PI */ + + C((!signbit (3.1415926535897932384626433832795f))); + C((!issignaling(3.1415926535897932384626433832795f))); + C((!isnan (3.1415926535897932384626433832795f))); + C((!isinf (3.1415926535897932384626433832795f))); + C(( isfinite (3.1415926535897932384626433832795f))); + C(( isnormal (3.1415926535897932384626433832795f))); + C((!issubnormal(3.1415926535897932384626433832795f))); + C((!iszero (3.1415926535897932384626433832795f))); + + C((!signbit (3.1415926535897932384626433832795))); + C((!issignaling(3.1415926535897932384626433832795))); + C((!isnan (3.1415926535897932384626433832795))); + C((!isinf (3.1415926535897932384626433832795))); + C(( isfinite (3.1415926535897932384626433832795))); + C(( isnormal (3.1415926535897932384626433832795))); + C((!issubnormal(3.1415926535897932384626433832795))); + C((!iszero (3.1415926535897932384626433832795))); + + C((!signbit (3.1415926535897932384626433832795L))); + C((!issignaling(3.1415926535897932384626433832795L))); + C((!isnan (3.1415926535897932384626433832795L))); + C((!isinf (3.1415926535897932384626433832795L))); + C(( isfinite (3.1415926535897932384626433832795L))); + C(( isnormal (3.1415926535897932384626433832795L))); + C((!issubnormal(3.1415926535897932384626433832795L))); + C((!iszero (3.1415926535897932384626433832795L))); + + /* MAX */ + + C((!signbit (FLT_MAX))); + C((!issignaling(FLT_MAX))); + C((!isnan (FLT_MAX))); + C((!isinf (FLT_MAX))); + C(( isfinite (FLT_MAX))); + C(( isnormal (FLT_MAX))); + C((!issubnormal(FLT_MAX))); + C((!iszero (FLT_MAX))); + + C((!signbit (DBL_MAX))); + C((!issignaling(DBL_MAX))); + C((!isnan (DBL_MAX))); + C((!isinf (DBL_MAX))); + C(( isfinite (DBL_MAX))); + C(( isnormal (DBL_MAX))); + C((!issubnormal(DBL_MAX))); + C((!iszero (DBL_MAX))); + + C((!signbit (LDBL_MAX))); + C((!issignaling(LDBL_MAX))); + C((!isnan (LDBL_MAX))); + C((!isinf (LDBL_MAX))); + C(( isfinite (LDBL_MAX))); + C(( isnormal (LDBL_MAX))); + C((!issubnormal(LDBL_MAX))); + C((!iszero (LDBL_MAX))); + + /* INFINITY */ + + C((!signbit (__builtin_inff()))); + C((!issignaling(__builtin_inff()))); + C((!isnan (__builtin_inff()))); + C(( isinf (__builtin_inff()))); + C((!isfinite (__builtin_inff()))); + C((!isnormal (__builtin_inff()))); + C((!issubnormal(__builtin_inff()))); + C((!iszero (__builtin_inff()))); + + C((!signbit (__builtin_inf()))); + C((!issignaling(__builtin_inf()))); + C((!isnan (__builtin_inf()))); + C(( isinf (__builtin_inf()))); + C((!isfinite (__builtin_inf()))); + C((!isnormal (__builtin_inf()))); + C((!issubnormal(__builtin_inf()))); + C((!iszero (__builtin_inf()))); + + C((!signbit (__builtin_infl()))); + C((!issignaling(__builtin_infl()))); + C((!isnan (__builtin_infl()))); + C(( isinf (__builtin_infl()))); + C((!isfinite (__builtin_infl()))); + C((!isnormal (__builtin_infl()))); + C((!issubnormal(__builtin_infl()))); + C((!iszero (__builtin_infl()))); + + /* NAN */ + + C((!signbit (__builtin_nanf("")))); + C(( issignaling(__builtin_nanf("")))); + C(( isnan (__builtin_nanf("")))); + C((!isinf (__builtin_nanf("")))); + C((!isfinite (__builtin_nanf("")))); + C((!isnormal (__builtin_nanf("")))); + C((!issubnormal(__builtin_nanf("")))); + C((!iszero (__builtin_nanf("")))); + + C((!signbit (__builtin_nan("")))); + C(( issignaling(__builtin_nan("")))); + C(( isnan (__builtin_nan("")))); + C((!isinf (__builtin_nan("")))); + C((!isfinite (__builtin_nan("")))); + C((!isnormal (__builtin_nan("")))); + C((!issubnormal(__builtin_nan("")))); + C((!iszero (__builtin_nan("")))); + + C((!signbit (__builtin_nanl("")))); + C(( issignaling(__builtin_nanl("")))); + C(( isnan (__builtin_nanl("")))); + C((!isinf (__builtin_nanl("")))); + C((!isfinite (__builtin_nanl("")))); + C((!isnormal (__builtin_nanl("")))); + C((!issubnormal(__builtin_nanl("")))); + C((!iszero (__builtin_nanl("")))); + + /* SIGNALING NAN */ + + C((!signbit (__builtin_nansf("")))); + C(( issignaling(__builtin_nansf("")))); + C(( isnan (__builtin_nansf("")))); + C((!isinf (__builtin_nansf("")))); + C((!isfinite (__builtin_nansf("")))); + C((!isnormal (__builtin_nansf("")))); + C((!issubnormal(__builtin_nansf("")))); + C((!iszero (__builtin_nansf("")))); + + C((!signbit (__builtin_nans("")))); + C(( issignaling(__builtin_nans("")))); + C(( isnan (__builtin_nans("")))); + C((!isinf (__builtin_nans("")))); + C((!isfinite (__builtin_nans("")))); + C((!isnormal (__builtin_nans("")))); + C((!issubnormal(__builtin_nans("")))); + C((!iszero (__builtin_nans("")))); + + C((!signbit (__builtin_nansl("")))); + C(( issignaling(__builtin_nansl("")))); + C(( isnan (__builtin_nansl("")))); + C((!isinf (__builtin_nansl("")))); + C((!isfinite (__builtin_nansl("")))); + C((!isnormal (__builtin_nansl("")))); + C((!issubnormal(__builtin_nansl("")))); + C((!iszero (__builtin_nansl("")))); + +//------------------------------------------------------------------------------ +// Negative value tests +//------------------------------------------------------------------------------ + + /* ZERO */ + + C(( signbit (-0.0f))); + C((!issignaling(-0.0f))); + C((!isnan (-0.0f))); + C((!isinf (-0.0f))); + C(( isfinite (-0.0f))); + C((!isnormal (-0.0f))); + C((!issubnormal(-0.0f))); + C(( iszero (-0.0f))); + + C(( signbit (-0.0))); + C((!issignaling(-0.0))); + C((!isnan (-0.0))); + C((!isinf (-0.0))); + C(( isfinite (-0.0))); + C((!isnormal (-0.0))); + C((!issubnormal(-0.0))); + C(( iszero (-0.0))); + + C(( signbit (-0.0L))); + C((!issignaling(-0.0L))); + C((!isnan (-0.0L))); + C((!isinf (-0.0L))); + C(( isfinite (-0.0L))); + C((!isnormal (-0.0L))); + C((!issubnormal(-0.0L))); + C(( iszero (-0.0L))); + + /* TRUE_MIN */ + + C(( signbit (-FLT_TRUE_MIN))); + C((!issignaling(-FLT_TRUE_MIN))); + C((!isnan (-FLT_TRUE_MIN))); + C((!isinf (-FLT_TRUE_MIN))); + C(( isfinite (-FLT_TRUE_MIN))); + C((!isnormal (-FLT_TRUE_MIN))); + C(( issubnormal(-FLT_TRUE_MIN))); + C((!iszero (-FLT_TRUE_MIN))); + + C(( signbit (-DBL_TRUE_MIN))); + C((!issignaling(-DBL_TRUE_MIN))); + C((!isnan (-DBL_TRUE_MIN))); + C((!isinf (-DBL_TRUE_MIN))); + C(( isfinite (-DBL_TRUE_MIN))); + C((!isnormal (-DBL_TRUE_MIN))); + C(( issubnormal(-DBL_TRUE_MIN))); + C((!iszero (-DBL_TRUE_MIN))); + + C(( signbit (-LDBL_TRUE_MIN))); + C((!issignaling(-LDBL_TRUE_MIN))); + C((!isnan (-LDBL_TRUE_MIN))); + C((!isinf (-LDBL_TRUE_MIN))); + C(( isfinite (-LDBL_TRUE_MIN))); + C((!isnormal (-LDBL_TRUE_MIN))); + C(( issubnormal(-LDBL_TRUE_MIN))); + C((!iszero (-LDBL_TRUE_MIN))); + + /* MIN */ + + C(( signbit (-FLT_MIN))); + C((!issignaling(-FLT_MIN))); + C((!isnan (-FLT_MIN))); + C((!isinf (-FLT_MIN))); + C(( isfinite (-FLT_MIN))); + C(( isnormal (-FLT_MIN))); + C((!issubnormal(-FLT_MIN))); + C((!iszero (-FLT_MIN))); + + C(( signbit (-DBL_MIN))); + C((!issignaling(-DBL_MIN))); + C((!isnan (-DBL_MIN))); + C((!isinf (-DBL_MIN))); + C(( isfinite (-DBL_MIN))); + C(( isnormal (-DBL_MIN))); + C((!issubnormal(-DBL_MIN))); + C((!iszero (-DBL_MIN))); + + C(( signbit (-LDBL_MIN))); + C((!issignaling(-LDBL_MIN))); + C((!isnan (-LDBL_MIN))); + C((!isinf (-LDBL_MIN))); + C(( isfinite (-LDBL_MIN))); + C(( isnormal (-LDBL_MIN))); + C((!issubnormal(-LDBL_MIN))); + C((!iszero (-LDBL_MIN))); + + /* RECIP PI */ + + C(( signbit (-0.31830988618379067153776752674503f))); + C((!issignaling(-0.31830988618379067153776752674503f))); + C((!isnan (-0.31830988618379067153776752674503f))); + C((!isinf (-0.31830988618379067153776752674503f))); + C(( isfinite (-0.31830988618379067153776752674503f))); + C(( isnormal (-0.31830988618379067153776752674503f))); + C((!issubnormal(-0.31830988618379067153776752674503f))); + C((!iszero (-0.31830988618379067153776752674503f))); + + C(( signbit (-0.31830988618379067153776752674503))); + C((!issignaling(-0.31830988618379067153776752674503))); + C((!isnan (-0.31830988618379067153776752674503))); + C((!isinf (-0.31830988618379067153776752674503))); + C(( isfinite (-0.31830988618379067153776752674503))); + C(( isnormal (-0.31830988618379067153776752674503))); + C((!issubnormal(-0.31830988618379067153776752674503))); + C((!iszero (-0.31830988618379067153776752674503))); + + C(( signbit (-0.31830988618379067153776752674503L))); + C((!issignaling(-0.31830988618379067153776752674503L))); + C((!isnan (-0.31830988618379067153776752674503L))); + C((!isinf (-0.31830988618379067153776752674503L))); + C(( isfinite (-0.31830988618379067153776752674503L))); + C(( isnormal (-0.31830988618379067153776752674503L))); + C((!issubnormal(-0.31830988618379067153776752674503L))); + C((!iszero (-0.31830988618379067153776752674503L))); + + /* ONE */ + + C(( signbit (-1.0f))); + C((!issignaling(-1.0f))); + C((!isnan (-1.0f))); + C((!isinf (-1.0f))); + C(( isfinite (-1.0f))); + C(( isnormal (-1.0f))); + C((!issubnormal(-1.0f))); + C((!iszero (-1.0f))); + + C(( signbit (-1.0))); + C((!issignaling(-1.0))); + C((!isnan (-1.0))); + C((!isinf (-1.0))); + C(( isfinite (-1.0))); + C(( isnormal (-1.0))); + C((!issubnormal(-1.0))); + C((!iszero (-1.0))); + + C(( signbit (-1.0L))); + C((!issignaling(-1.0L))); + C((!isnan (-1.0L))); + C((!isinf (-1.0L))); + C(( isfinite (-1.0L))); + C(( isnormal (-1.0L))); + C((!issubnormal(-1.0L))); + C((!iszero (-1.0L))); + + /* PI */ + + C(( signbit (-3.1415926535897932384626433832795f))); + C((!issignaling(-3.1415926535897932384626433832795f))); + C((!isnan (-3.1415926535897932384626433832795f))); + C((!isinf (-3.1415926535897932384626433832795f))); + C(( isfinite (-3.1415926535897932384626433832795f))); + C(( isnormal (-3.1415926535897932384626433832795f))); + C((!issubnormal(-3.1415926535897932384626433832795f))); + C((!iszero (-3.1415926535897932384626433832795f))); + + C(( signbit (-3.1415926535897932384626433832795))); + C((!issignaling(-3.1415926535897932384626433832795))); + C((!isnan (-3.1415926535897932384626433832795))); + C((!isinf (-3.1415926535897932384626433832795))); + C(( isfinite (-3.1415926535897932384626433832795))); + C(( isnormal (-3.1415926535897932384626433832795))); + C((!issubnormal(-3.1415926535897932384626433832795))); + C((!iszero (-3.1415926535897932384626433832795))); + + C(( signbit (-3.1415926535897932384626433832795L))); + C((!issignaling(-3.1415926535897932384626433832795L))); + C((!isnan (-3.1415926535897932384626433832795L))); + C((!isinf (-3.1415926535897932384626433832795L))); + C(( isfinite (-3.1415926535897932384626433832795L))); + C(( isnormal (-3.1415926535897932384626433832795L))); + C((!issubnormal(-3.1415926535897932384626433832795L))); + C((!iszero (-3.1415926535897932384626433832795L))); + + /* MAX */ + + C(( signbit (-FLT_MAX))); + C((!issignaling(-FLT_MAX))); + C((!isnan (-FLT_MAX))); + C((!isinf (-FLT_MAX))); + C(( isfinite (-FLT_MAX))); + C(( isnormal (-FLT_MAX))); + C((!issubnormal(-FLT_MAX))); + C((!iszero (-FLT_MAX))); + + C(( signbit (-DBL_MAX))); + C((!issignaling(-DBL_MAX))); + C((!isnan (-DBL_MAX))); + C((!isinf (-DBL_MAX))); + C(( isfinite (-DBL_MAX))); + C(( isnormal (-DBL_MAX))); + C((!issubnormal(-DBL_MAX))); + C((!iszero (-DBL_MAX))); + + C(( signbit (-LDBL_MAX))); + C((!issignaling(-LDBL_MAX))); + C((!isnan (-LDBL_MAX))); + C((!isinf (-LDBL_MAX))); + C(( isfinite (-LDBL_MAX))); + C(( isnormal (-LDBL_MAX))); + C((!issubnormal(-LDBL_MAX))); + C((!iszero (-LDBL_MAX))); + + /* INFINITY */ + + C(( signbit (-__builtin_inff()))); + C((!issignaling(-__builtin_inff()))); + C((!isnan (-__builtin_inff()))); + C(( isinf (-__builtin_inff()))); + C((!isfinite (-__builtin_inff()))); + C((!isnormal (-__builtin_inff()))); + C((!issubnormal(-__builtin_inff()))); + C((!iszero (-__builtin_inff()))); + + C(( signbit (-__builtin_inf()))); + C((!issignaling(-__builtin_inf()))); + C((!isnan (-__builtin_inf()))); + C(( isinf (-__builtin_inf()))); + C((!isfinite (-__builtin_inf()))); + C((!isnormal (-__builtin_inf()))); + C((!issubnormal(-__builtin_inf()))); + C((!iszero (-__builtin_inf()))); + + C(( signbit (-__builtin_infl()))); + C((!issignaling(-__builtin_infl()))); + C((!isnan (-__builtin_infl()))); + C(( isinf (-__builtin_infl()))); + C((!isfinite (-__builtin_infl()))); + C((!isnormal (-__builtin_infl()))); + C((!issubnormal(-__builtin_infl()))); + C((!iszero (-__builtin_infl()))); + + /* NAN */ + + C(( signbit (-__builtin_nanf("")))); + C(( issignaling(-__builtin_nanf("")))); + C(( isnan (-__builtin_nanf("")))); + C((!isinf (-__builtin_nanf("")))); + C((!isfinite (-__builtin_nanf("")))); + C((!isnormal (-__builtin_nanf("")))); + C((!issubnormal(-__builtin_nanf("")))); + C((!iszero (-__builtin_nanf("")))); + + C(( signbit (-__builtin_nan("")))); + C(( issignaling(-__builtin_nan("")))); + C(( isnan (-__builtin_nan("")))); + C((!isinf (-__builtin_nan("")))); + C((!isfinite (-__builtin_nan("")))); + C((!isnormal (-__builtin_nan("")))); + C((!issubnormal(-__builtin_nan("")))); + C((!iszero (-__builtin_nan("")))); + + C(( signbit (-__builtin_nanl("")))); + C(( issignaling(-__builtin_nanl("")))); + C(( isnan (-__builtin_nanl("")))); + C((!isinf (-__builtin_nanl("")))); + C((!isfinite (-__builtin_nanl("")))); + C((!isnormal (-__builtin_nanl("")))); + C((!issubnormal(-__builtin_nanl("")))); + C((!iszero (-__builtin_nanl("")))); + + /* SIGNALING NAN */ + + C(( signbit (-__builtin_nansf("")))); + C(( issignaling(-__builtin_nansf("")))); + C(( isnan (-__builtin_nansf("")))); + C((!isinf (-__builtin_nansf("")))); + C((!isfinite (-__builtin_nansf("")))); + C((!isnormal (-__builtin_nansf("")))); + C((!issubnormal(-__builtin_nansf("")))); + C((!iszero (-__builtin_nansf("")))); + + C(( signbit (-__builtin_nans("")))); + C(( issignaling(-__builtin_nans("")))); + C(( isnan (-__builtin_nans("")))); + C((!isinf (-__builtin_nans("")))); + C((!isfinite (-__builtin_nans("")))); + C((!isnormal (-__builtin_nans("")))); + C((!issubnormal(-__builtin_nans("")))); + C((!iszero (-__builtin_nans("")))); + + C(( signbit (-__builtin_nansl("")))); + C(( issignaling(-__builtin_nansl("")))); + C(( isnan (-__builtin_nansl("")))); + C((!isinf (-__builtin_nansl("")))); + C((!isfinite (-__builtin_nansl("")))); + C((!isnormal (-__builtin_nansl("")))); + C((!issubnormal(-__builtin_nansl("")))); + C((!iszero (-__builtin_nansl("")))); + +//------------------------------------------------------------------------------ +// Integer value tests +//------------------------------------------------------------------------------ + + /* int */ + + C((!signbit (0))); + C((!issignaling(0))); + C((!isnan (0))); + C((!isinf (0))); + C(( isfinite (0))); + C((!isnormal (0))); + C((!issubnormal(0))); + C(( iszero (0))); + + C((!signbit (1))); + C((!issignaling(1))); + C((!isnan (1))); + C((!isinf (1))); + C(( isfinite (1))); + C(( isnormal (1))); + C((!issubnormal(1))); + C((!iszero (1))); + + C((!signbit (10))); + C((!issignaling(10))); + C((!isnan (10))); + C((!isinf (10))); + C(( isfinite (10))); + C(( isnormal (10))); + C((!issubnormal(10))); + C((!iszero (10))); + + C(( signbit (-1))); + C((!issignaling(-1))); + C((!isnan (-1))); + C((!isinf (-1))); + C(( isfinite (-1))); + C(( isnormal (-1))); + C((!issubnormal(-1))); + C((!iszero (-1))); + + C(( signbit (-10))); + C((!issignaling(-10))); + C((!isnan (-10))); + C((!isinf (-10))); + C(( isfinite (-10))); + C(( isnormal (-10))); + C((!issubnormal(-10))); + C((!iszero (-10))); + + /* unsigned long long */ + + C((!signbit (0ull))); + C((!issignaling(0ull))); + C((!isnan (0ull))); + C((!isinf (0ull))); + C(( isfinite (0ull))); + C((!isnormal (0ull))); + C((!issubnormal(0ull))); + C(( iszero (0ull))); + + C((!signbit (1ull))); + C((!issignaling(1ull))); + C((!isnan (1ull))); + C((!isinf (1ull))); + C(( isfinite (1ull))); + C(( isnormal (1ull))); + C((!issubnormal(1ull))); + C((!iszero (1ull))); + + C((!signbit (10ull))); + C((!issignaling(10ull))); + C((!isnan (10ull))); + C((!isinf (10ull))); + C(( isfinite (10ull))); + C(( isnormal (10ull))); + C((!issubnormal(10ull))); + C((!iszero (10ull))); + + return 0; +} + +int main(void) { + os_ClrHome(); + + int failed_test = run_test(); + if (failed_test != 0) { + char buf[sizeof("Failed test L-8388608\n")]; + boot_sprintf(buf, "Failed test L%d\n", failed_test); + fputs(buf, stdout); + } else { + fputs("All tests passed", stdout); + } + + while (!os_GetCSC()); + + return 0; +} diff --git a/test/floating_point/compiletime_classification/src/test.asm b/test/floating_point/compiletime_classification/src/test.asm new file mode 100644 index 000000000..0ea434227 --- /dev/null +++ b/test/floating_point/compiletime_classification/src/test.asm @@ -0,0 +1,44 @@ + assume adl = 1 + + section .text + +; if a function call is emitted (hence not constant folded), it will conflict with one of these functions + + public __fpclassifyf + public __fpclassifyl + public __issignalingf + public __isnanf + public __isinff + public __isfinitef + public __isnormalf + public __issubnormalf + public __iszerof + public __issignalingl + public __isnanl + public __isinfl + public __isfinitel + public __isnormall + public __issubnormall + public __iszerol + public __signbitf + public __signbitl + +__fpclassifyf: +__fpclassifyl: +__issignalingf: +__isnanf: +__isinff: +__isfinitef: +__isnormalf: +__issubnormalf: +__iszerof: +__issignalingl: +__isnanl: +__isinfl: +__isfinitel: +__isnormall: +__issubnormall: +__iszerol: +__signbitf: +__signbitl: + ret