diff --git a/src/crt/dcmp.c b/src/crt/dcmp.c index 101c1e047..f9739b2e2 100644 --- a/src/crt/dcmp.c +++ b/src/crt/dcmp.c @@ -12,23 +12,31 @@ typedef union F64_pun { #define F64_CMP_GREATER 1 /* doesn't trigger flags */ #define F64_CMP_UNORDERED 1 /* doesn't trigger flags */ +typedef struct f64_cmp_arg { + long double x; + bool x_sign; /* <-- unimplemented */ + unsigned int const return_address; + long double y; + bool y_sign; /* <-- unimplemented */ +} f64_cmp_arg; + // assumes no NaN -int _dcmp_c(const long double *__restrict x, const long double *__restrict y) { - F64_pun arg_x, arg_y; - arg_x.flt = *x; - arg_y.flt = *y; +int _dcmp_c(f64_cmp_arg *__restrict const arg) { + F64_pun x, y; + x.flt = arg->x; + y.flt = arg->y; - bool x_sign = signbit(arg_x.flt); - bool y_sign = signbit(arg_y.flt); + bool x_sign = signbit(x.flt); + bool y_sign = signbit(y.flt); if (x_sign != y_sign) { - if (iszero(arg_x.flt) && iszero(arg_y.flt)) { + if (iszero(x.flt) && iszero(y.flt)) { return F64_CMP_EQUAL; } return (x_sign ? F64_CMP_LESS : F64_CMP_GREATER); } - if (arg_x.bin == arg_y.bin) { + if (x.bin == y.bin) { return F64_CMP_EQUAL; } - return ((arg_x.bin < arg_y.bin) != x_sign) ? F64_CMP_LESS : F64_CMP_GREATER; + return ((x.bin < y.bin) != x_sign) ? F64_CMP_LESS : F64_CMP_GREATER; } diff --git a/src/crt/dcmp.src b/src/crt/dcmp.src index e090c5bed..0e29915c1 100644 --- a/src/crt/dcmp.src +++ b/src/crt/dcmp.src @@ -4,16 +4,18 @@ public __dcmp -; int _dcmp_c(const long double *__restrict x, const long double *__restrict y) +; int _dcmp_c(f64_cmp_arg const *__restrict const arg) __dcmp: - ; f64*_f64*_ret_i24 - push bc, de, hl, af, iy - ld iy, 6 - add iy, sp - pea iy + 12 - push iy + ; f64_cmp_arg*_ret_i24 + push bc, de, hl + or a, a + sbc hl, hl + add hl, sp + push iy, af + push hl ; f64_cmp_arg* call __dcmp_c - pop af, af, iy, af + pop af + pop af, iy ; Set the comparison flags add hl, de or a, a diff --git a/src/crt/ddiv.src b/src/crt/ddiv.src index ac632fab0..38f849d4f 100644 --- a/src/crt/ddiv.src +++ b/src/crt/ddiv.src @@ -4,14 +4,23 @@ public __ddiv -; float64_t f64_div(float64_t, const float64_t*) +; float64_t f64_div(bool, float64_t, const float64_t*) __ddiv: push af, iy ld iy, 9 - add iy, sp + add iy, sp + push iy, bc, de, hl + + ld a, b ; signbit(x) + xor a, (iy + 7) ; signbit(y) + rla + push af ; Carry = (signbit(x) != signbit(y)) + call _f64_div - pop af, af, af, af, iy, af + + pop af, af, af, af, af + pop iy, af ; restore ret extern _f64_div diff --git a/src/crt/dmul.src b/src/crt/dmul.src index 5c113b92d..b5f49cb05 100644 --- a/src/crt/dmul.src +++ b/src/crt/dmul.src @@ -4,14 +4,23 @@ public __dmul -; float64_t f64_mul(float64_t, const float64_t*) +; float64_t f64_mul(bool, float64_t, const float64_t*) __dmul: push af, iy ld iy, 9 - add iy, sp + add iy, sp + push iy, bc, de, hl + + ld a, b ; signbit(x) + xor a, (iy + 7) ; signbit(y) + rla + push af ; Carry = (signbit(x) != signbit(y)) + call _f64_mul - pop af, af, af, af, iy, af + + pop af, af, af, af, af + pop iy, af ; restore ret extern _f64_mul diff --git a/src/crt/drem.src b/src/crt/drem.src index 23ad1bd68..6634c5394 100644 --- a/src/crt/drem.src +++ b/src/crt/drem.src @@ -4,14 +4,20 @@ public __drem -; float64_t f64_rem(float64_t, const float64_t*) +; float64_t f64_rem(bool, float64_t, const float64_t*) __drem: push af, iy ld iy, 9 add iy, sp push iy, bc, de, hl + + rl b + push af ; Carry = signbit(x) + call _f64_rem - pop af, af, af, af, iy, af + + pop af, af, af, af, af + pop iy, af ; restore ret extern _f64_rem diff --git a/src/crt/dtol.src b/src/crt/dtol.src index 3261c7589..0828142ea 100644 --- a/src/crt/dtol.src +++ b/src/crt/dtol.src @@ -6,9 +6,17 @@ __dtol: ; f64_ret_i32 - push af, iy, bc, de, hl + push af, iy + ld a, b + push bc, de, hl + ld hl, 7 + add hl, sp + res 7, (hl) ; fabsl(x) + inc hl + rlca + ld (hl), a ; store the sign of x in the padding byte call __dtol_c - pop af, af, af, iy, af + pop af, af, bc, iy, af ret extern __dtol_c diff --git a/src/crt/dtoll.src b/src/crt/dtoll.src index 91ed03959..1bf02d054 100644 --- a/src/crt/dtoll.src +++ b/src/crt/dtoll.src @@ -6,7 +6,14 @@ __dtoll: ; f64_ret_i64 - push af, iy, bc, de, hl + push af, iy + ld a, b + res 7, b ; fabsl(x) + push bc, de, hl + ld hl, 8 + add hl, sp + rlca + ld (hl), a ; store the sign of x in the padding byte call __dtoll_c pop af, af, af, iy, af ret diff --git a/src/crt/dtoul.src b/src/crt/dtoul.src index 3bf26cfde..b5ca56b64 100644 --- a/src/crt/dtoul.src +++ b/src/crt/dtoul.src @@ -8,7 +8,7 @@ __dtoul: ; f64_ret_u32 push af, iy, bc, de, hl call __dtoul_c - pop af, af, af, iy, af + pop af, af, bc, iy, af ret extern __dtoul_c diff --git a/src/crt/float64_to_int.c b/src/crt/float64_to_int.c index 2196d23f0..c8c96d715 100644 --- a/src/crt/float64_to_int.c +++ b/src/crt/float64_to_int.c @@ -74,6 +74,11 @@ uint64_t _dtoull_c(long double x) { */ #define HANDLE_INT_MIN 1 +typedef struct f64_sign { + long double flt; + bool sign; +} f64_sign; + /** * @note val must have the signbit cleared */ @@ -123,10 +128,10 @@ uint32_t _dtoul_c(long double x) { return (uint32_t)f64_to_unsigned(val); } -int64_t _dtoll_c(long double x) { +int64_t _dtoll_c(f64_sign arg) { F64_pun val; - bool x_sign = signbit(x); - val.flt = fabsl(x); + bool x_sign = arg.sign; + val.flt = arg.flt; /* overflow || isinf(x) || isnan(x) */ if (val.reg.BC >= ((Float64_bias + Float64_i64_max_exp) << Float64_exp_BC_shift)) { @@ -145,10 +150,10 @@ int64_t _dtoll_c(long double x) { return ret; } -int32_t _dtol_c(long double x) { +int32_t _dtol_c(f64_sign arg) { F64_pun val; - bool x_sign = signbit(x); - val.flt = fabsl(x); + bool x_sign = arg.sign; + val.flt = arg.flt; /* overflow || isinf(x) || isnan(x) */ if (val.reg.BC >= ((Float64_bias + Float64_i32_max_exp) << Float64_exp_BC_shift)) { diff --git a/src/libc/ceill.c b/src/libc/ceill.c index aafdad86d..34db52654 100644 --- a/src/libc/ceill.c +++ b/src/libc/ceill.c @@ -1,9 +1,5 @@ #include -#ifdef ceill -#undef ceill -#endif - long double ceill(long double x) { if (signbit(x)) { return truncl(x); @@ -17,5 +13,3 @@ long double ceill(long double x) { } return x; } - -long double _debug_ceill(long double) __attribute__((alias("ceill"))); diff --git a/src/libc/copysignl.src b/src/libc/copysignl.src index d1c17033c..b6b8277e2 100644 --- a/src/libc/copysignl.src +++ b/src/libc/copysignl.src @@ -2,9 +2,7 @@ section .text - public _copysignl, __debug_copysignl - -__debug_copysignl: + public _copysignl _copysignl: ld hl, 19 ; upper 8 bits of y add hl, sp diff --git a/src/libc/fabsl.src b/src/libc/fabsl.src index ec7065305..11473b375 100644 --- a/src/libc/fabsl.src +++ b/src/libc/fabsl.src @@ -2,9 +2,8 @@ section .text - public _fabsl, __debug_fabsl + public _fabsl -__debug_fabsl: _fabsl: pop iy, hl ,de, bc push bc, de, hl diff --git a/src/libc/float64_rounding.c b/src/libc/float64_rounding.c index 0950c733b..197345ea2 100644 --- a/src/libc/float64_rounding.c +++ b/src/libc/float64_rounding.c @@ -47,10 +47,6 @@ long double roundevenl(long double x) { return ret.flt; } -#ifdef roundl -#undef roundl -#endif - long double roundl(long double x) { F64_pun arg_x, ret; arg_x.flt = x; @@ -93,10 +89,6 @@ long long llroundl(long double x) { } #endif -#ifdef nearbyintl -#undef nearbyintl -#endif - long double nearbyintl(long double x) { F64_pun arg_x, ret; arg_x.flt = x; @@ -104,10 +96,6 @@ long double nearbyintl(long double x) { return ret.flt; } -#ifdef rintl -#undef rintl -#endif - /* flags handled by softfloat */ long double rintl(long double x) { F64_pun arg_x, ret; @@ -129,8 +117,3 @@ long long llrintl(long double x) { arg_x.flt = x; return f64_to_i64(arg_x.soft, GET_FENV_SOFTFLOAT_ROUNDING(), true); } - -long double _debug_roundl(long double) __attribute__((alias("roundl"))); -long double _debug_rintl(long double) __attribute__((alias("rintl"))); -long double _debug_nearbyintl(long double) __attribute__((alias("nearbyintl"))); - diff --git a/src/libc/floorl.c b/src/libc/floorl.c index 604ee9db1..8790ca373 100644 --- a/src/libc/floorl.c +++ b/src/libc/floorl.c @@ -1,9 +1,5 @@ #include -#ifdef floorl -#undef floorl -#endif - long double floorl(long double x) { if (!signbit(x)) { return truncl(x); @@ -17,5 +13,3 @@ long double floorl(long double x) { } return x; } - -long double _debug_floorl(long double) __attribute__((alias("floorl"))); diff --git a/src/libc/fmal.src b/src/libc/fmal.src index e8f6e7cb9..e0772c47c 100644 --- a/src/libc/fmal.src +++ b/src/libc/fmal.src @@ -2,10 +2,19 @@ section .text - public _fmal, __debug_fmal + public _fmal -_fmal := _softfloat_mulAddF64 -__debug_fmal := _softfloat_mulAddF64 +_fmal: ; flags handled by softfloat + ld iy, 0 + add iy, sp + ld a, (iy + 28) + rlca + ld (iy + 11), a ; signC + ld a, (iy + 10) + xor a, (iy + 19) + rlca + ld (iy + 20), a ; signZ + jq _softfloat_mulAddF64 extern _softfloat_mulAddF64 diff --git a/src/libc/fmax.c b/src/libc/fmax.c index e8c43745a..256d7901c 100644 --- a/src/libc/fmax.c +++ b/src/libc/fmax.c @@ -13,10 +13,6 @@ float fmaxf(float x, float y) { double fmax(double, double) __attribute__((alias("fmaxf"))); -#ifdef fmaxl -#undef fmaxl -#endif - long double fmaxl(long double x, long double y) { return isless(x, y) ? y : @@ -27,5 +23,3 @@ long double fmaxl(long double x, long double y) { /* arguments are equal or signed zero */ signbit(x) ? y : x; } - -long double _debug_fmaxl(long double, long double) __attribute__((alias("fmaxl"))); diff --git a/src/libc/fmin.c b/src/libc/fmin.c index ec2a43952..7ba5a084b 100644 --- a/src/libc/fmin.c +++ b/src/libc/fmin.c @@ -13,10 +13,6 @@ float fminf(float x, float y) { double fmin(double, double) __attribute__((alias("fminf"))); -#ifdef fminl -#undef fminl -#endif - long double fminl(long double x, long double y) { return isless(x, y) ? x : @@ -27,5 +23,3 @@ long double fminl(long double x, long double y) { /* arguments are equal or signed zero */ signbit(x) ? x : y; } - -long double _debug_fminl(long double, long double) __attribute__((alias("fminl"))); diff --git a/src/libc/fmodl.c b/src/libc/fmodl.c deleted file mode 100644 index e4a68fda2..000000000 --- a/src/libc/fmodl.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include -#include "../softfloat/include/softfloat.h" - -typedef union F64_pun { - long double flt; - float64_t soft; - uint64_t bin; -} F64_pun; - -/* flags handled by softfloat */ - -long double fmodl(long double x, long double y) { - F64_pun arg_x, arg_y, ret; - arg_x.flt = x; - arg_y.flt = y; - - ret.soft = f64_rem(arg_x.soft, &arg_y.soft); - return ret.flt; -} diff --git a/src/libc/fmodl.src b/src/libc/fmodl.src new file mode 100644 index 000000000..82d5dbad9 --- /dev/null +++ b/src/libc/fmodl.src @@ -0,0 +1,31 @@ + assume adl = 1 + + section .text + + public _fmodl + +_fmodl: + call __frameset0 + + pea ix + 15 ; &y + + ld hl, (ix + 12) + push hl ; x[63:48] + + ld hl, (ix + 9) + push hl ; x[47:24] + + ld hl, (ix + 6) + push hl ; x[23:0] + + ld a, h + rla + push af ; Carry = signbit(x) + + call _f64_rem + ld sp, ix + pop ix + ret + + extern _f64_rem + extern __frameset0 diff --git a/src/libc/include/__math_def.h b/src/libc/include/__math_def.h index bdb0a6ada..dcce8953a 100644 --- a/src/libc/include/__math_def.h +++ b/src/libc/include/__math_def.h @@ -44,19 +44,21 @@ extern "C" { int _fpclassifyf(float) __NOEXCEPT_CONST; int _fpclassifyl(long double) __NOEXCEPT_CONST; -bool _isinff(float) __NOEXCEPT_CONST; +bool _issignalingf(float) __NOEXCEPT_CONST; bool _isnanf(float) __NOEXCEPT_CONST; -bool _isnormalf(float) __NOEXCEPT_CONST; +bool _isinff(float) __NOEXCEPT_CONST; bool _isfinitef(float) __NOEXCEPT_CONST; -bool _iszerof(float) __NOEXCEPT_CONST; +bool _isnormalf(float) __NOEXCEPT_CONST; bool _issubnormalf(float) __NOEXCEPT_CONST; +bool _iszerof(float) __NOEXCEPT_CONST; -bool _isinfl(long double) __NOEXCEPT_CONST; +bool _issignalingl(long double) __NOEXCEPT_CONST; bool _isnanl(long double) __NOEXCEPT_CONST; -bool _isnormall(long double) __NOEXCEPT_CONST; +bool _isinfl(long double) __NOEXCEPT_CONST; bool _isfinitel(long double) __NOEXCEPT_CONST; -bool _iszerol(long double) __NOEXCEPT_CONST; +bool _isnormall(long double) __NOEXCEPT_CONST; bool _issubnormall(long double) __NOEXCEPT_CONST; +bool _iszerol(long double) __NOEXCEPT_CONST; #if 0 /* disabled until builtin is optimized */ @@ -326,31 +328,6 @@ double trunc(double); float truncf(float); long double truncl(long double); -/* aliases */ - -long double _debug_fabsl(long double) __NOEXCEPT_CONST; -#define fabsl _debug_fabsl -long double _debug_copysignl(long double, long double) __NOEXCEPT_CONST; -#define copysignl _debug_copysignl -long double _debug_fmaxl(long double, long double); -#define fmaxl _debug_fmaxl -long double _debug_fminl(long double, long double); -#define fminl _debug_fminl -long double _debug_truncl(long double); -#define truncl _debug_truncl -long double _debug_floorl(long double); -#define floorl _debug_floorl -long double _debug_ceill(long double); -#define ceill _debug_ceill -long double _debug_roundl(long double); -#define roundl _debug_roundl -long double _debug_nearbyintl(long double); -#define nearbyintl _debug_nearbyintl -long double _debug_rintl(long double); -#define rintl _debug_rintl -long double _debug_fmal(long double, long double, long double); -#define fmal _debug_fmal - #ifdef __cplusplus } #endif diff --git a/src/libc/include/math.h b/src/libc/include/math.h index 3331cff7e..965b1d63d 100644 --- a/src/libc/include/math.h +++ b/src/libc/include/math.h @@ -21,10 +21,10 @@ float: _signbitf \ )(x)) -#define isinf(x) ((int)_Generic(__math_promote(x), \ - long double: _isinfl, \ - default: _isinff, \ - float: _isinff \ +#define issignaling(x) ((int)_Generic(__math_promote(x), \ + long double: _issignalingl, \ + default: _issignalingf, \ + float: _issignalingf \ )(x)) #define isnan(x) ((int)_Generic(__math_promote(x), \ @@ -33,10 +33,11 @@ float: _isnanf \ )(x)) -#define isnormal(x) ((int)_Generic(__math_promote(x), \ - long double: _isnormall, \ - default: _isnormalf, \ - float: _isnormalf \ + +#define isinf(x) ((int)_Generic(__math_promote(x), \ + long double: _isinfl, \ + default: _isinff, \ + float: _isinff \ )(x)) #define isfinite(x) ((int)_Generic(__math_promote(x), \ @@ -45,10 +46,10 @@ float: _isfinitef \ )(x)) -#define iszero(x) ((int)_Generic(__math_promote(x), \ - long double: _iszerol, \ - default: _iszerof, \ - float: _iszerof \ +#define isnormal(x) ((int)_Generic(__math_promote(x), \ + long double: _isnormall, \ + default: _isnormalf, \ + float: _isnormalf \ )(x)) #define issubnormal(x) ((int)_Generic(__math_promote(x), \ @@ -57,6 +58,12 @@ float: _issubnormalf \ )(x)) +#define iszero(x) ((int)_Generic(__math_promote(x), \ + long double: _iszerol, \ + default: _iszerof, \ + float: _iszerof \ +)(x)) + #define fpclassify(x) ((int)_Generic(__math_promote(x), \ long double: _fpclassifyl, \ default: _fpclassifyf, \ diff --git a/src/libc/issignalingf.src b/src/libc/issignalingf.src new file mode 100644 index 000000000..5eb2b798c --- /dev/null +++ b/src/libc/issignalingf.src @@ -0,0 +1,30 @@ + assume adl=1 + + section .text + + public __issignalingf + +; assumes quiet NaN is 0x7FC00000 or 0xFFC00000 +; bool _issignalingf(float) +__issignalingf: + ; based off __isnanf, unoptimized + xor a, a + ld iy, 0 + add iy, sp + ld hl, (iy + 3) + adc hl, hl + ret z ; infinity + ld a, (iy + 6) + rla + + or a, a + adc hl, hl + jr z, .quiet_nan + + add a, 1 ; attempt to overflow the exponent + sbc a, a + ret + +.quiet_nan: + xor a, a + ret diff --git a/src/libc/issignalingl.src b/src/libc/issignalingl.src new file mode 100644 index 000000000..8c90b7849 --- /dev/null +++ b/src/libc/issignalingl.src @@ -0,0 +1,34 @@ + assume adl=1 + + section .text + + public __issignalingl + +; assumes quiet NaN is 0x7FF8000000000000 or 0xFFF8000000000000 +; bool _issignalingl(long double) +__issignalingl: + ; based off __isnanl, unoptimized + pop bc, hl, de + xor a, a + adc hl, de + pop de + push bc, bc, bc, bc + ld a, e + jr nz, .mant_nonzero ; normal, subnormal, or NaN + jr c, .mant_nonzero ; normal, subnormal, or NaN + ; common NaN, inf, normal, or subnormal + ; quiet NaN will be along this path + xor a, $F8 + ret z ; quiet NaN + xor a, $F8 + ret z + dec a +.mant_nonzero: + add a, 16 ; overflows 0xF0 + sbc a, a + ret z + ld a, d + add a, a + add a, 2 + sbc a, a + ret diff --git a/src/libc/roundl.src b/src/libc/roundl.src deleted file mode 100644 index 7f795e58f..000000000 --- a/src/libc/roundl.src +++ /dev/null @@ -1,71 +0,0 @@ -; assume adl=1 -; -; section .text -; -; public _roundl, __debug_roundl -; -; if 0 -; -; ; long double roundl(long double) -; __debug_roundl: -; _roundl: -; ; return truncl(x + copysignl(0.5L, x)) -; pop iy, hl, de, bc -; push iy -; ex (sp), hl -; ; push the value of copysignl(0.5L, x) onto the stack -; ld hl, $7EE0 ; 0.5L with upper 8 bits left shifted by one -; ld a, b -; rla ; extract signbit of x -; rr h ; copy the carry flag into the signbit (carry not set) -; push hl -; sbc hl, hl -; push hl, hl -; ex (sp), hl -; ld a, (___fe_cur_env) -; call __dadd -; ld (___fe_cur_env), a -; push bc, de, hl -; call _truncl -; pop af, af, af -; ret -; -; else -; -; ; long double roundl(long double) -; __debug_roundl: -; _roundl: -; ; return truncl(copysignl(0.5L, x) + x) -; ld hl, 10 -; add hl, sp -; ld a, (hl) -; rlca -; add a, $10 -; jr c, .already_int_inf_nan -; -; ; loads the value of copysignl(0.5L, x) in BC:UDE:UHL -; ld bc, $7EE0 ; 0.5L with upper 8 bits left shifted by one -; ;rla ; extract signbit of x -; rra -; -; rr b ; copy the carry flag into the signbit (carry not set) -; ; set HL and DE to zero -; sbc hl, hl -; ex de, hl -; sbc hl, hl -; ld a, (___fe_cur_env) -; call __dadd -; ld (___fe_cur_env), a -; push bc, de, hl -; call _truncl -; pop af, af, af -; ret -; -; .already_int_inf_nan: -; pop iy, hl, de, bc -; push bc, de, hl -; jp (iy) -; -; end if -; -; extern ___fe_cur_env, __dadd, _truncl diff --git a/src/libc/sqrtl.src b/src/libc/sqrtl.src index 6f109c1e3..a0213f26a 100644 --- a/src/libc/sqrtl.src +++ b/src/libc/sqrtl.src @@ -3,7 +3,15 @@ section .text public _sqrtl -_sqrtl := _f64_sqrt + +_sqrtl: ; flags handled by softfloat + ld hl, 10 + add hl, sp + ld a, (hl) + rlca + inc hl + ld (hl), a + jq _f64_sqrt extern _f64_sqrt diff --git a/src/libc/truncl.c b/src/libc/truncl.c index 8a31402a1..7468d71a7 100644 --- a/src/libc/truncl.c +++ b/src/libc/truncl.c @@ -34,12 +34,6 @@ static long double _truncl_c_positive(long double x) { return val.flt; } -#ifdef truncl -#undef truncl -#endif - long double truncl(long double x) { return copysignl(_truncl_c_positive(fabsl(x)), x); } - -long double _debug_truncl(long double) __attribute__((alias("truncl"))); diff --git a/src/libcxx/include/cmath b/src/libcxx/include/cmath index e57b74f8f..ccd658ae3 100644 --- a/src/libcxx/include/cmath +++ b/src/libcxx/include/cmath @@ -34,27 +34,18 @@ template inline constexpr __cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool> signbit(_Tp __x) { return (__x < 0); } -inline constexpr bool isinf(float __x) { - if (__builtin_constant_p(__x)) { - return __builtin_isinf(__x); - } - return _isinff(__x); +inline constexpr bool issignaling(float __x) { + return _issignalingf(__x); } -inline constexpr bool isinf(double __x) { - if (__builtin_constant_p(__x)) { - return __builtin_isinf(__x); - } - return _isinff(__x); +inline constexpr bool issignaling(double __x) { + return _issignalingf(__x); } -inline constexpr bool isinf(long double __x) { - if (__builtin_constant_p(__x)) { - return __builtin_isinf(__x); - } - return _isinfl(__x); +inline constexpr bool issignaling(long double __x) { + return _issignalingl(__x); } template inline constexpr __cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool> -isinf(_Tp __x) { return false; } +issignaling(_Tp __x) { return false; } inline constexpr bool isnan(float __x) { if (__builtin_constant_p(__x)) { @@ -78,27 +69,27 @@ template inline constexpr __cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool> isnan(_Tp __x) { return false; } -inline constexpr bool isnormal(float __x) { +inline constexpr bool isinf(float __x) { if (__builtin_constant_p(__x)) { - return __builtin_isnormal(__x); + return __builtin_isinf(__x); } - return _isnormalf(__x); + return _isinff(__x); } -inline constexpr bool isnormal(double __x) { +inline constexpr bool isinf(double __x) { if (__builtin_constant_p(__x)) { - return __builtin_isnormal(__x); + return __builtin_isinf(__x); } - return _isnormalf(__x); + return _isinff(__x); } -inline constexpr bool isnormal(long double __x) { +inline constexpr bool isinf(long double __x) { if (__builtin_constant_p(__x)) { - return __builtin_isnormal(__x); + return __builtin_isinf(__x); } - return _isnormall(__x); + return _isinfl(__x); } template inline constexpr __cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool> -isnormal(_Tp __x) { return (__x != 0); } +isinf(_Tp __x) { return false; } inline constexpr bool isfinite(float __x) { if (__builtin_constant_p(__x)) { @@ -122,27 +113,27 @@ template inline constexpr __cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool> isfinite(_Tp __x) { return true; } -inline constexpr bool iszero(float __x) { +inline constexpr bool isnormal(float __x) { if (__builtin_constant_p(__x)) { - return (__x == 0.0f); + return __builtin_isnormal(__x); } - return _iszerof(__x); + return _isnormalf(__x); } -inline constexpr bool iszero(double __x) { +inline constexpr bool isnormal(double __x) { if (__builtin_constant_p(__x)) { - return (__x == 0.0); + return __builtin_isnormal(__x); } - return _iszerof(__x); + return _isnormalf(__x); } -inline constexpr bool iszero(long double __x) { +inline constexpr bool isnormal(long double __x) { if (__builtin_constant_p(__x)) { - return (__x == 0.0L); + return __builtin_isnormal(__x); } - return _iszerol(__x); + return _isnormall(__x); } template inline constexpr __cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool> -iszero(_Tp __x) { return (__x == 0); } +isnormal(_Tp __x) { return (__x != 0); } inline constexpr bool issubnormal(float __x) { if (__builtin_constant_p(__x)) { @@ -166,6 +157,28 @@ template inline constexpr __cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool> issubnormal(_Tp __x) { return false; } +inline constexpr bool iszero(float __x) { + if (__builtin_constant_p(__x)) { + return (__x == 0.0f); + } + return _iszerof(__x); +} +inline constexpr bool iszero(double __x) { + if (__builtin_constant_p(__x)) { + return (__x == 0.0); + } + return _iszerof(__x); +} +inline constexpr bool iszero(long double __x) { + if (__builtin_constant_p(__x)) { + return (__x == 0.0L); + } + return _iszerol(__x); +} +template inline constexpr +__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool> +iszero(_Tp __x) { return (__x == 0); } + inline constexpr int fpclassify(float __x) { if (__builtin_constant_p(__x)) { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); @@ -801,12 +814,13 @@ trunc(_Tp __x) { return trunc(__x); } } // namespace std using std::signbit; -using std::isinf; +using std::issignaling; using std::isnan; -using std::isnormal; +using std::isinf; using std::isfinite; -using std::iszero; +using std::isnormal; using std::issubnormal; +using std::iszero; using std::fpclassify; using std::isgreater; diff --git a/src/libcxx/math_test.cpp b/src/libcxx/math_test.cpp index a40f2263a..56a8467e0 100644 --- a/src/libcxx/math_test.cpp +++ b/src/libcxx/math_test.cpp @@ -8,6 +8,9 @@ #define C(expr) static_assert(expr, #expr) +// can't get issignaling to work at compile time at the moment +#define issignaling(...) true || true + //------------------------------------------------------------------------------ // Positive value tests //------------------------------------------------------------------------------ @@ -15,25 +18,28 @@ /* ZERO */ C((!signbit (0.0f))); -C(( isfinite (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(( isfinite (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(( isfinite (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))); @@ -41,25 +47,28 @@ C(( iszero (0.0L))); /* TRUE_MIN */ C((!signbit (std::numeric_limits::denorm_min()))); -C(( isfinite (std::numeric_limits::denorm_min()))); +C((!issignaling(std::numeric_limits::denorm_min()))); C((!isnan (std::numeric_limits::denorm_min()))); C((!isinf (std::numeric_limits::denorm_min()))); +C(( isfinite (std::numeric_limits::denorm_min()))); C((!isnormal (std::numeric_limits::denorm_min()))); C(( issubnormal(std::numeric_limits::denorm_min()))); C((!iszero (std::numeric_limits::denorm_min()))); C((!signbit (std::numeric_limits::denorm_min()))); -C(( isfinite (std::numeric_limits::denorm_min()))); +C((!issignaling(std::numeric_limits::denorm_min()))); C((!isnan (std::numeric_limits::denorm_min()))); C((!isinf (std::numeric_limits::denorm_min()))); +C(( isfinite (std::numeric_limits::denorm_min()))); C((!isnormal (std::numeric_limits::denorm_min()))); C(( issubnormal(std::numeric_limits::denorm_min()))); C((!iszero (std::numeric_limits::denorm_min()))); C((!signbit (std::numeric_limits::denorm_min()))); -C(( isfinite (std::numeric_limits::denorm_min()))); +C((!issignaling(std::numeric_limits::denorm_min()))); C((!isnan (std::numeric_limits::denorm_min()))); C((!isinf (std::numeric_limits::denorm_min()))); +C(( isfinite (std::numeric_limits::denorm_min()))); C((!isnormal (std::numeric_limits::denorm_min()))); C(( issubnormal(std::numeric_limits::denorm_min()))); C((!iszero (std::numeric_limits::denorm_min()))); @@ -67,25 +76,28 @@ C((!iszero (std::numeric_limits::denorm_min()))); /* MIN */ C((!signbit (std::numeric_limits::min()))); -C(( isfinite (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(( isfinite (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(( isfinite (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()))); @@ -93,25 +105,28 @@ C((!iszero (std::numeric_limits::min()))); /* RECIP PI */ C((!signbit (0.31830988618379067153776752674503f))); -C(( isfinite (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(( isfinite (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(( isfinite (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))); @@ -119,25 +134,28 @@ C((!iszero (0.31830988618379067153776752674503L))); /* ONE */ C((!signbit (1.0f))); -C(( isfinite (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(( isfinite (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(( isfinite (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))); @@ -145,25 +163,28 @@ C((!iszero (1.0L))); /* PI */ C((!signbit (3.1415926535897932384626433832795f))); -C(( isfinite (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(( isfinite (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(( isfinite (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))); @@ -171,25 +192,28 @@ C((!iszero (3.1415926535897932384626433832795L))); /* MAX */ C((!signbit (std::numeric_limits::max()))); -C(( isfinite (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(( isfinite (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(( isfinite (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()))); @@ -197,25 +221,28 @@ C((!iszero (std::numeric_limits::max()))); /* INFINITY */ C((!signbit (__builtin_inff()))); -C((!isfinite (__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((!isfinite (__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((!isfinite (__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()))); @@ -223,29 +250,61 @@ C((!iszero (__builtin_infl()))); /* NAN */ C((!signbit (__builtin_nanf("")))); -C((!isfinite (__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((!isfinite (__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((!isfinite (__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 //------------------------------------------------------------------------------ @@ -253,25 +312,28 @@ C((!iszero (__builtin_nanl("")))); /* ZERO */ C(( signbit (-0.0f))); -C(( isfinite (-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(( isfinite (-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(( isfinite (-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))); @@ -279,25 +341,28 @@ C(( iszero (-0.0L))); /* TRUE_MIN */ C(( signbit (-std::numeric_limits::denorm_min()))); -C(( isfinite (-std::numeric_limits::denorm_min()))); +C((!issignaling(-std::numeric_limits::denorm_min()))); C((!isnan (-std::numeric_limits::denorm_min()))); C((!isinf (-std::numeric_limits::denorm_min()))); +C(( isfinite (-std::numeric_limits::denorm_min()))); C((!isnormal (-std::numeric_limits::denorm_min()))); C(( issubnormal(-std::numeric_limits::denorm_min()))); C((!iszero (-std::numeric_limits::denorm_min()))); C(( signbit (-std::numeric_limits::denorm_min()))); -C(( isfinite (-std::numeric_limits::denorm_min()))); +C((!issignaling(-std::numeric_limits::denorm_min()))); C((!isnan (-std::numeric_limits::denorm_min()))); C((!isinf (-std::numeric_limits::denorm_min()))); +C(( isfinite (-std::numeric_limits::denorm_min()))); C((!isnormal (-std::numeric_limits::denorm_min()))); C(( issubnormal(-std::numeric_limits::denorm_min()))); C((!iszero (-std::numeric_limits::denorm_min()))); C(( signbit (-std::numeric_limits::denorm_min()))); -C(( isfinite (-std::numeric_limits::denorm_min()))); +C((!issignaling(-std::numeric_limits::denorm_min()))); C((!isnan (-std::numeric_limits::denorm_min()))); C((!isinf (-std::numeric_limits::denorm_min()))); +C(( isfinite (-std::numeric_limits::denorm_min()))); C((!isnormal (-std::numeric_limits::denorm_min()))); C(( issubnormal(-std::numeric_limits::denorm_min()))); C((!iszero (-std::numeric_limits::denorm_min()))); @@ -305,25 +370,28 @@ C((!iszero (-std::numeric_limits::denorm_min()))); /* MIN */ C(( signbit (-std::numeric_limits::min()))); -C(( isfinite (-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(( isfinite (-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(( isfinite (-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()))); @@ -331,25 +399,28 @@ C((!iszero (-std::numeric_limits::min()))); /* RECIP PI */ C(( signbit (-0.31830988618379067153776752674503f))); -C(( isfinite (-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(( isfinite (-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(( isfinite (-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))); @@ -357,25 +428,28 @@ C((!iszero (-0.31830988618379067153776752674503L))); /* ONE */ C(( signbit (-1.0f))); -C(( isfinite (-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(( isfinite (-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(( isfinite (-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))); @@ -383,25 +457,28 @@ C((!iszero (-1.0L))); /* PI */ C(( signbit (-3.1415926535897932384626433832795f))); -C(( isfinite (-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(( isfinite (-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(( isfinite (-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))); @@ -409,25 +486,28 @@ C((!iszero (-3.1415926535897932384626433832795L))); /* MAX */ C(( signbit (-std::numeric_limits::max()))); -C(( isfinite (-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(( isfinite (-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(( isfinite (-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()))); @@ -435,25 +515,28 @@ C((!iszero (-std::numeric_limits::max()))); /* INFINITY */ C(( signbit (-__builtin_inff()))); -C((!isfinite (-__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((!isfinite (-__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((!isfinite (-__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()))); @@ -461,29 +544,61 @@ C((!iszero (-__builtin_infl()))); /* NAN */ C(( signbit (-__builtin_nanf("")))); -C((!isfinite (-__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((!isfinite (-__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((!isfinite (-__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 //------------------------------------------------------------------------------ @@ -491,41 +606,46 @@ C((!iszero (-__builtin_nanl("")))); /* int */ C((!signbit (0))); -C(( isfinite (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(( isfinite (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(( isfinite (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(( isfinite (-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(( isfinite (-10))); +C((!issignaling(-10))); C((!isnan (-10))); C((!isinf (-10))); +C(( isfinite (-10))); C(( isnormal (-10))); C((!issubnormal(-10))); C((!iszero (-10))); @@ -533,25 +653,28 @@ C((!iszero (-10))); /* unsigned long long */ C((!signbit (0ull))); -C(( isfinite (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(( isfinite (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(( isfinite (10ull))); +C((!issignaling(10ull))); C((!isnan (10ull))); C((!isinf (10ull))); +C(( isfinite (10ull))); C(( isnormal (10ull))); C((!issubnormal(10ull))); C((!iszero (10ull))); diff --git a/src/softfloat/f64_div.c b/src/softfloat/f64_div.c index 92ff214f5..fb8b811ee 100644 --- a/src/softfloat/f64_div.c +++ b/src/softfloat/f64_div.c @@ -41,19 +41,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "specialize.h" #include "softfloat.h" -float64_t f64_div( float64_t a, const float64_t *b ) +float64_t f64_div( bool signZ, float64_t a, float64_t *__restrict b ) { union ui64_f64 uA; uint_fast64_t uiA; - bool signA; + // bool signA; int_fast16_t expA; uint_fast64_t sigA; union ui64_f64 uB; uint_fast64_t uiB; - bool signB; + // bool signB; int_fast16_t expB; uint_fast64_t sigB; - bool signZ; + // bool signZ; struct exp16_sig64 normExpSig; int_fast16_t expZ; uint32_t recip32, sig32Z, doubleTerm; @@ -67,15 +67,15 @@ float64_t f64_div( float64_t a, const float64_t *b ) *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; - signA = signF64UI( uiA ); + // signA = signF64UI( uiA ); expA = expF64UI( uiA ); sigA = fracF64UI( uiA ); uB.f = *b; uiB = uB.ui; - signB = signF64UI( uiB ); + // signB = signF64UI( uiB ); expB = expF64UI( uiB ); sigB = fracF64UI( uiB ); - signZ = signA ^ signB; + // signZ = signA ^ signB; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( expA == 0x7FF ) { diff --git a/src/softfloat/f64_mul.c b/src/softfloat/f64_mul.c index 661fb94b8..56f616063 100644 --- a/src/softfloat/f64_mul.c +++ b/src/softfloat/f64_mul.c @@ -41,19 +41,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "specialize.h" #include "softfloat.h" -float64_t f64_mul( float64_t a, const float64_t *b ) +float64_t f64_mul( bool signZ, float64_t a, float64_t *__restrict b ) { union ui64_f64 uA; uint_fast64_t uiA; - bool signA; + // bool signA; int_fast16_t expA; uint_fast64_t sigA; union ui64_f64 uB; uint_fast64_t uiB; - bool signB; + // bool signB; int_fast16_t expB; uint_fast64_t sigB; - bool signZ; + // bool signZ; uint_fast64_t magBits; struct exp16_sig64 normExpSig; int_fast16_t expZ; @@ -69,15 +69,15 @@ float64_t f64_mul( float64_t a, const float64_t *b ) *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; - signA = signF64UI( uiA ); + // signA = signF64UI( uiA ); expA = expF64UI( uiA ); sigA = fracF64UI( uiA ); uB.f = *b; uiB = uB.ui; - signB = signF64UI( uiB ); + // signB = signF64UI( uiB ); expB = expF64UI( uiB ); sigB = fracF64UI( uiB ); - signZ = signA ^ signB; + // signZ = signA ^ signB; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( expA == 0x7FF ) { diff --git a/src/softfloat/f64_rem.c b/src/softfloat/f64_rem.c index 9f0ee6f73..d3e313f43 100644 --- a/src/softfloat/f64_rem.c +++ b/src/softfloat/f64_rem.c @@ -41,11 +41,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "specialize.h" #include "softfloat.h" -float64_t f64_rem( float64_t a, const float64_t *b ) +float64_t f64_rem( bool signA, float64_t a, float64_t *__restrict b ) { union ui64_f64 uA; uint_fast64_t uiA; - bool signA; + // bool signA; int_fast16_t expA; uint_fast64_t sigA; union ui64_f64 uB; @@ -66,7 +66,7 @@ float64_t f64_rem( float64_t a, const float64_t *b ) *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; - signA = signF64UI( uiA ); + // signA = signF64UI( uiA ); expA = expF64UI( uiA ); sigA = fracF64UI( uiA ); uB.f = *b; diff --git a/src/softfloat/f64_sqrt.c b/src/softfloat/f64_sqrt.c index f12acdb41..7623ae122 100644 --- a/src/softfloat/f64_sqrt.c +++ b/src/softfloat/f64_sqrt.c @@ -41,11 +41,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "specialize.h" #include "softfloat.h" -float64_t f64_sqrt( float64_t a ) +float64_t f64_sqrt( f64_param A ) { union ui64_f64 uA; uint_fast64_t uiA; - bool signA; + bool signA = A.sign; int_fast16_t expA; uint_fast64_t sigA, uiZ; struct exp16_sig64 normExpSig; @@ -55,12 +55,13 @@ float64_t f64_sqrt( float64_t a ) uint32_t q; uint_fast64_t sigZ, shiftedSigZ; union ui64_f64 uZ; + uint_fast64_t a = A.ui; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; - signA = signF64UI( uiA ); + // signA = signF64UI( uiA ); expA = expF64UI( uiA ); sigA = fracF64UI( uiA ); /*------------------------------------------------------------------------ diff --git a/src/softfloat/include/internals.h b/src/softfloat/include/internals.h index 82ede024b..0eb0ccda0 100644 --- a/src/softfloat/include/internals.h +++ b/src/softfloat/include/internals.h @@ -106,7 +106,11 @@ float16_t #define fracF32UI( a ) ((a) & 0x007FFFFF) #define packToF32UI( sign, exp, sig ) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<23) + (sig)) +#if 0 #define isNaNF32UI( a ) (((~(a) & 0x7F800000) == 0) && ((a) & 0x007FFFFF)) +#else +bool isNaNF32UI(uint32_t a) __attribute__((__const__, __nothrow__, __leaf__)); +#endif struct exp16_sig32 { int_fast16_t exp; uint_fast32_t sig; }; struct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t ); @@ -127,7 +131,14 @@ float32_t #define fracF64UI( a ) ((a) & UINT64_C( 0x000FFFFFFFFFFFFF )) #define packToF64UI( sign, exp, sig ) ((uint64_t) (((uint_fast64_t) (sign)<<63) + ((uint_fast64_t) (exp)<<52) + (sig))) -#define isNaNF64UI( a ) (((~(a) & UINT64_C( 0x7FF0000000000000 )) == 0) && ((a) & UINT64_C( 0x000FFFFFFFFFFFFF ))) +#if 0 +#define softfloat_isSigNaNF64UI( uiA ) +((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF ))) + (((~(a) & UINT64_C( 0x7FF0000000000000 )) == 0) && ((a) & UINT64_C( 0x000FFFFFFFFFFFFF ))) +#define isNaNF64UI( a ) +#else +bool isNaNF64UI(uint64_t a) __attribute__((__const__, __nothrow__, __leaf__)); +#endif struct exp16_sig64 { int_fast16_t exp; uint_fast64_t sig; }; struct exp16_sig64 softfloat_normSubnormalF64Sig( uint_fast64_t ); @@ -142,13 +153,23 @@ float64_t softfloat_subMagsF64( uint_fast64_t, uint_fast64_t, bool ); float64_t softfloat_addMagsF64( uint_fast64_t, const uint_fast64_t*, bool ); float64_t softfloat_subMagsF64( uint_fast64_t, const uint_fast64_t*, bool ); #endif -#if 0 -float64_t - softfloat_mulAddF64( - uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast8_t ); -#else -float64_t softfloat_mulAddF64( uint_fast64_t, uint_fast64_t, uint_fast64_t ); -#endif + +typedef struct f64_param { + uint_fast64_t ui; + bool sign; +} f64_param; + +// #if 0 +// float64_t +// softfloat_mulAddF64( +// uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast8_t ); +// #elif 1 +// struct input_mulAddF64; +// float64_t softfloat_mulAddF64( uint_fast64_t, uint_fast64_t, uint_fast64_t); +// #else +// struct input_mulAddF64; +// float64_t softfloat_mulAddF64( bool, bool, struct input_mulAddF64 * ); +// #endif /*---------------------------------------------------------------------------- *----------------------------------------------------------------------------*/ diff --git a/src/softfloat/include/softfloat.h b/src/softfloat/include/softfloat.h index 80fb2ecd4..f9f065a1d 100644 --- a/src/softfloat/include/softfloat.h +++ b/src/softfloat/include/softfloat.h @@ -116,7 +116,13 @@ enum { /*---------------------------------------------------------------------------- | Routine to raise any or all of the software floating-point exception flags. *----------------------------------------------------------------------------*/ +#if 0 void softfloat_raiseFlags( uint_fast8_t ); +#else +inline void softfloat_raiseFlags( uint_fast8_t flags ) { + softfloat_exceptionFlags |= flags; +} +#endif /*---------------------------------------------------------------------------- | Integer-to-floating-point conversion routines. @@ -252,11 +258,17 @@ float64_t f64_roundToInt( float64_t, uint_fast8_t, bool ); float64_t f64_add( float64_t, float64_t ); float64_t f64_sub( float64_t, float64_t ); #endif +#if 0 float64_t f64_mul( float64_t, const float64_t* ); -float64_t f64_mulAdd( float64_t, float64_t, float64_t ); float64_t f64_div( float64_t, const float64_t* ); float64_t f64_rem( float64_t, const float64_t* ); -float64_t f64_sqrt( float64_t ); +#else +float64_t f64_mul( bool, float64_t, float64_t *__restrict ); +float64_t f64_div( bool, float64_t, float64_t *__restrict ); +float64_t f64_rem( bool, float64_t, float64_t *__restrict ); +#endif +float64_t f64_mulAdd( float64_t, float64_t, float64_t ); +// float64_t f64_sqrt( float64_t ); bool f64_eq( float64_t, float64_t ); bool f64_le( float64_t, float64_t ); bool f64_lt( float64_t, float64_t ); diff --git a/src/softfloat/include/specialize.h b/src/softfloat/include/specialize.h index a7d0bf5d1..407e8c772 100644 --- a/src/softfloat/include/specialize.h +++ b/src/softfloat/include/specialize.h @@ -127,7 +127,11 @@ uint_fast16_t | 32-bit floating-point signaling NaN. | Note: This macro evaluates its argument more than once. *----------------------------------------------------------------------------*/ +#if 0 #define softfloat_isSigNaNF32UI( uiA ) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF)) +#else +bool softfloat_isSigNaNF32UI(uint32_t a) __attribute__((__const__, __nothrow__, __leaf__)); +#endif /*---------------------------------------------------------------------------- | Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts @@ -162,7 +166,11 @@ uint_fast32_t | 64-bit floating-point signaling NaN. | Note: This macro evaluates its argument more than once. *----------------------------------------------------------------------------*/ +#if 0 #define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF ))) +#else +bool softfloat_isSigNaNF64UI(uint64_t a) __attribute__((__const__, __nothrow__, __leaf__)); +#endif /*---------------------------------------------------------------------------- | Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts diff --git a/src/softfloat/isNaNF32UI.src b/src/softfloat/isNaNF32UI.src new file mode 100644 index 000000000..cf559b653 --- /dev/null +++ b/src/softfloat/isNaNF32UI.src @@ -0,0 +1,8 @@ + assume adl = 1 + + section .text + + public _isNaNF32UI +_isNaNF32UI := __isnanf + + extern __isnanf diff --git a/src/softfloat/isNaNF64UI.src b/src/softfloat/isNaNF64UI.src new file mode 100644 index 000000000..008d9b18d --- /dev/null +++ b/src/softfloat/isNaNF64UI.src @@ -0,0 +1,8 @@ + assume adl = 1 + + section .text + + public _isNaNF64UI +_isNaNF64UI := __isnanl + + extern __isnanl diff --git a/src/softfloat/s_mulAddF64.c b/src/softfloat/s_mulAddF64.c index c3593c4fa..dfb0791fb 100644 --- a/src/softfloat/s_mulAddF64.c +++ b/src/softfloat/s_mulAddF64.c @@ -243,15 +243,29 @@ float64_t #else +#if 0 +typedef struct input_mulAddF64 { + uint_fast64_t uiA; + uint8_t pad1; + uint_fast64_t uiB; + uint8_t pad2; + uint_fast64_t uiC; +} input_mulAddF64; +#endif + float64_t softfloat_mulAddF64( - uint_fast64_t uiA, uint_fast64_t uiB, uint_fast64_t uiC /*, uint_fast8_t op */) -{ +#if 1 +f64_param A, f64_param B, uint_fast64_t uiC /*, uint_fast8_t op */ +#else + input_mulAddF64 * const input +#endif + ) { #define op 0 - bool signA; + // bool signA; int_fast16_t expA; uint64_t sigA; - bool signB; + // bool signB; int_fast16_t expB; uint64_t sigB; bool signC; @@ -266,19 +280,24 @@ float64_t int_fast16_t shiftDist, expDiff; uint32_t sig128C[4]; union ui64_f64 uZ; - + uint_fast64_t uiA, uiB; + uiA = A.ui; + uiB = B.ui; + /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - signA = signF64UI( uiA ); + // signA = signF64UI( uiA ); expA = expF64UI( uiA ); sigA = fracF64UI( uiA ); - signB = signF64UI( uiB ); + // signB = signF64UI( uiB ); expB = expF64UI( uiB ); sigB = fracF64UI( uiB ); - signC = signF64UI( uiC ) ^ (op == softfloat_mulAdd_subC); + // signC = signF64UI( uiC ) ^ (op == softfloat_mulAdd_subC); expC = expF64UI( uiC ); sigC = fracF64UI( uiC ); - signZ = signA ^ signB ^ (op == softfloat_mulAdd_subProd); + // signZ = signA ^ signB ^ (op == softfloat_mulAdd_subProd); + signC = A.sign; + signZ = B.sign; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ( expA == 0x7FF ) { diff --git a/src/softfloat/softfloat_isSigNaNF32UI.src b/src/softfloat/softfloat_isSigNaNF32UI.src new file mode 100644 index 000000000..459dbc0d2 --- /dev/null +++ b/src/softfloat/softfloat_isSigNaNF32UI.src @@ -0,0 +1,8 @@ + assume adl = 1 + + section .text + + public _softfloat_isSigNaNF32UI +_softfloat_isSigNaNF32UI := __issignalingf + + extern __issignalingf diff --git a/src/softfloat/softfloat_isSigNaNF64UI.src b/src/softfloat/softfloat_isSigNaNF64UI.src new file mode 100644 index 000000000..fc276c982 --- /dev/null +++ b/src/softfloat/softfloat_isSigNaNF64UI.src @@ -0,0 +1,8 @@ + assume adl = 1 + + section .text + + public _softfloat_isSigNaNF64UI +_softfloat_isSigNaNF64UI := __issignalingl + + extern __issignalingl diff --git a/src/softfloat/softfloat_raiseFlags.c b/src/softfloat/softfloat_raiseFlags.c index ed21af212..47a948d55 100644 --- a/src/softfloat/softfloat_raiseFlags.c +++ b/src/softfloat/softfloat_raiseFlags.c @@ -34,6 +34,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================*/ +#if 0 + #include "platform.h" #include "softfloat.h" #include @@ -49,3 +51,4 @@ void softfloat_raiseFlags( uint_fast8_t flags ) softfloat_exceptionFlags |= flags; } +#endif diff --git a/test/floating_point/float32_classification/src/main.c b/test/floating_point/float32_classification/src/main.c index 4cf326cad..5ccc05ddc 100644 --- a/test/floating_point/float32_classification/src/main.c +++ b/test/floating_point/float32_classification/src/main.c @@ -13,9 +13,10 @@ typedef struct testb { // uint32_t start; uint32_t end; - bool is_finite; - bool is_inf; + bool is_signaling; bool is_nan; + bool is_inf; + bool is_finite; bool is_normal; bool is_subnormal; bool is_zero; @@ -49,24 +50,28 @@ static_assert( #define NUM_TO_STR(x) MACRO_TO_STR(x) /** - * Basic Testing: 10 (Covers all exponent values and the MSB of the mantissa) + * Basic Testing: 11 (Covers all exponent values and the MSB of the mantissa) * Advanced Testing: 17 (Covers the upper 2 bytes and a bit more) */ -#define test_count 10 +#define test_count 11 /* fastest type that can handle 2^test_count */ typedef uint24_t test_count_t; static const testb test_values[] = { - {/* UINT32_C(0x00000000), */ UINT32_C(0x00000000), true , false, false, false, false, true , FP_ZERO }, - {/* UINT32_C(0x00000001), */ UINT32_C(0x007FFFFF), true , false, false, false, true , false, FP_SUBNORMAL}, - {/* UINT32_C(0x00800000), */ UINT32_C(0x7F7FFFFF), true , false, false, true , false, false, FP_NORMAL }, - {/* UINT32_C(0x7F800000), */ UINT32_C(0x7F800000), false, true , false, false, false, false, FP_INFINITE }, - {/* UINT32_C(0x7F800001), */ UINT32_C(0x7FFFFFFF), false, false, true , false, false, false, FP_NAN }, - {/* UINT32_C(0x80000000), */ UINT32_C(0x80000000), true , false, false, false, false, true , FP_ZERO }, - {/* UINT32_C(0x80000001), */ UINT32_C(0x807FFFFF), true , false, false, false, true , false, FP_SUBNORMAL}, - {/* UINT32_C(0x80800000), */ UINT32_C(0xFF7FFFFF), true , false, false, true , false, false, FP_NORMAL }, - {/* UINT32_C(0xFF800000), */ UINT32_C(0xFF800000), false, true , false, false, false, false, FP_INFINITE }, - {/* UINT32_C(0xFF800001), */ UINT32_C(0xFFFFFFFF), false, false, true , false, false, false, FP_NAN }, + {/* UINT32_C(0x00000000), */ UINT32_C(0x00000000), false, false, false, true , false, false, true , FP_ZERO }, + {/* UINT32_C(0x00000001), */ UINT32_C(0x007FFFFF), false, false, false, true , false, true , false, FP_SUBNORMAL}, + {/* UINT32_C(0x00800000), */ UINT32_C(0x7F7FFFFF), false, false, false, true , true , false, false, FP_NORMAL }, + {/* UINT32_C(0x7F800000), */ UINT32_C(0x7F800000), false, false, true , false, false, false, false, FP_INFINITE }, + {/* UINT32_C(0x7F800001), */ UINT32_C(0x7FBFFFFF), true , true , false, false, false, false, false, FP_NAN }, + {/* UINT32_C(0x7FC00000), */ UINT32_C(0x7FC00000), false, true , false, false, false, false, false, FP_NAN }, + {/* UINT32_C(0x7FC00001), */ UINT32_C(0x7FFFFFFF), true , true , false, false, false, false, false, FP_NAN }, + {/* UINT32_C(0x80000000), */ UINT32_C(0x80000000), false, false, false, true , false, false, true , FP_ZERO }, + {/* UINT32_C(0x80000001), */ UINT32_C(0x807FFFFF), false, false, false, true , false, true , false, FP_SUBNORMAL}, + {/* UINT32_C(0x80800000), */ UINT32_C(0xFF7FFFFF), false, false, false, true , true , false, false, FP_NORMAL }, + {/* UINT32_C(0xFF800000), */ UINT32_C(0xFF800000), false, false, true , false, false, false, false, FP_INFINITE }, + {/* UINT32_C(0xFF800001), */ UINT32_C(0xFFBFFFFF), true , true , false, false, false, false, false, FP_NAN }, + {/* UINT32_C(0xFFC00000), */ UINT32_C(0xFFC00000), false, true , false, false, false, false, false, FP_NAN }, + {/* UINT32_C(0xFFC00001), */ UINT32_C(0xFFFFFFFF), true , true , false, false, false, false, false, FP_NAN }, }; /** @@ -82,17 +87,19 @@ static test_result fpclassify_test(void) { const testb* ground_truth = &test_values[0]; int grouth_truth_index = 0; for (test_count_t i = 0; i < ((test_count_t)1 << test_count); i++) { + bool is_signaling = issignaling(x.flt); + bool is_nan = isnan(x.flt); bool is_finite = isfinite(x.flt); bool is_inf = isinf(x.flt); - bool is_nan = isnan(x.flt); bool is_normal = isnormal(x.flt); bool is_subnormal = issubnormal(x.flt); bool is_zero = iszero(x.flt); int fp_class = fpclassify(x.flt); if ( - is_finite != ground_truth->is_finite || - is_inf != ground_truth->is_inf || + is_signaling != ground_truth->is_signaling || is_nan != ground_truth->is_nan || + is_inf != ground_truth->is_inf || + is_finite != ground_truth->is_finite || is_normal != ground_truth->is_normal || is_subnormal != ground_truth->is_subnormal || is_zero != ground_truth->is_zero || @@ -101,16 +108,18 @@ static test_result fpclassify_test(void) { ret.passed = false; ret.failed_index = x.bin; ret.truth = - (ground_truth->is_finite << (0 * 4)) | (ground_truth->is_inf << (1 * 4)) - | (ground_truth->is_nan << (2 * 4)) | (ground_truth->is_normal << (3 * 4)) - | (ground_truth->is_subnormal << (4 * 4)) | (ground_truth->is_zero << (5 * 4)); + (ground_truth->is_signaling << (0 * 3)) | (ground_truth->is_nan << (1 * 3)) + | (ground_truth->is_inf << (2 * 3)) | (ground_truth->is_finite << (3 * 3)) + | (ground_truth->is_normal << (4 * 3)) | (ground_truth->is_subnormal << (5 * 3)) + | (ground_truth->is_zero << (6 * 3)); ret.truth_fp = ground_truth->fp_class; ret.guess = - (is_finite << (0 * 4)) | (is_inf << (1 * 4)) - | (is_nan << (2 * 4)) | (is_normal << (3 * 4)) - | (is_subnormal << (4 * 4)) | (is_zero << (5 * 4)); - + (is_signaling << (0 * 3)) | (is_nan << (1 * 3)) + | (is_inf << (2 * 3)) | (is_finite << (3 * 3)) + | (is_normal << (4 * 3)) | (is_subnormal << (5 * 3)) + | (is_zero << (6 * 3)); + ret.guess_fp = fp_class; return ret; } @@ -136,7 +145,7 @@ int main(void) { printf("All tests passed"); } else { printf( - "Failed test:\n0x%08lX\nTruth: %06X_%d\nGuess: %06X_%d", + "Failed test:\n0x%08lX\nTruth: %06o_%d\nGuess: %06o_%d", ret.failed_index, ret.truth, ret.truth_fp, ret.guess, ret.guess_fp ); } @@ -144,4 +153,4 @@ int main(void) { while (!os_GetCSC()); return 0; -} \ No newline at end of file +} diff --git a/test/floating_point/float64_arithmetic/src/data.asm b/test/floating_point/float64_arithmetic/src/data.asm new file mode 100644 index 000000000..204c222be --- /dev/null +++ b/test/floating_point/float64_arithmetic/src/data.asm @@ -0,0 +1,27 @@ + assume adl=1 + + section .text + + public _f64_pos_zero +_f64_pos_zero: + db $00, $00, $00, $00, $00, $00, $00, $00 + + public _f64_neg_zero +_f64_neg_zero: + db $00, $00, $00, $00, $00, $00, $00, $80 + + public _f64_pos_one +_f64_pos_one: + db $00, $00, $00, $00, $00, $00, $F0, $3F + + public _f64_neg_one +_f64_neg_one: + db $00, $00, $00, $00, $00, $00, $F0, $BF + + public _f64_pos_pi +_f64_pos_pi: + db $18, $2D, $44, $54, $FB, $21, $09, $40 + + public _f64_neg_pi +_f64_neg_pi: + db $18, $2D, $44, $54, $FB, $21, $09, $C0 diff --git a/test/floating_point/float64_arithmetic/src/main.cpp b/test/floating_point/float64_arithmetic/src/main.cpp index f6d0ed4a1..b762cea45 100644 --- a/test/floating_point/float64_arithmetic/src/main.cpp +++ b/test/floating_point/float64_arithmetic/src/main.cpp @@ -61,16 +61,54 @@ static size_t run_test(int64_t* fail_ulp) { return SIZE_MAX; } +#define C(expr) if (!(expr)) { return __LINE__; } + +extern volatile long double f64_pos_zero; +extern volatile long double f64_neg_zero; +extern volatile long double f64_pos_one; +extern volatile long double f64_neg_one; +extern volatile long double f64_pos_pi; +extern volatile long double f64_neg_pi; + +int comparison_test(void) { + C(f64_pos_one == f64_pos_one ); + C(f64_neg_one < f64_pos_one ); + C(f64_pos_one >= f64_neg_one ); + C(f64_pos_one != f64_neg_one ); + C(f64_pos_zero < f64_pos_one ); + C(f64_neg_zero > f64_neg_one ); + + C(f64_pos_zero == f64_pos_zero); + C(f64_neg_zero == f64_neg_zero); + C(f64_pos_zero >= f64_neg_zero); + C(f64_neg_zero == f64_pos_zero); + + C(f64_pos_pi == f64_pos_pi ); + C(f64_pos_pi > f64_pos_one ); + C(f64_neg_pi < f64_neg_one ); + C(f64_pos_pi > f64_pos_zero); + C(f64_neg_pi <= f64_neg_zero); + C(f64_neg_pi != f64_neg_zero); + C(f64_pos_pi != f64_neg_pi ); + C(f64_pos_pi >= f64_neg_pi ); + + return 0; +} + int main(void) { os_ClrHome(); - int64_t fail_ulp = 0; - size_t fail_index = run_test(&fail_ulp); - if (fail_index == SIZE_MAX) { - printf("All tests passed"); + int comparison_result = comparison_test(); + if (comparison_result != 0) { + printf("Failed test L%d\n", comparison_result); } else { - printf("Failed test: %zu\nULP: %lld", fail_index, fail_ulp); + int64_t fail_ulp = 0; + size_t fail_index = run_test(&fail_ulp); + if (fail_index == SIZE_MAX) { + printf("All tests passed"); + } else { + printf("Failed test: %zu\nULP: %lld", fail_index, fail_ulp); + } } - while (!os_GetCSC()); return 0; diff --git a/test/floating_point/float64_classification/autotest.json b/test/floating_point/float64_classification/autotest.json index 3bf241778..3eab2fe28 100644 --- a/test/floating_point/float64_classification/autotest.json +++ b/test/floating_point/float64_classification/autotest.json @@ -8,7 +8,7 @@ }, "sequence": [ "action|launch", - "delay|3000", + "delay|6000", "hashWait|1", "key|enter", "delay|300", @@ -17,7 +17,7 @@ "hashes": { "1": { "description": "All tests passed or GDB1 error", - "timeout": 5000, + "timeout": 8000, "start": "vram_start", "size": "vram_16_size", "expected_CRCs": [ diff --git a/test/floating_point/float64_classification/src/main.c b/test/floating_point/float64_classification/src/main.c index 40b236dd9..b2fb70752 100644 --- a/test/floating_point/float64_classification/src/main.c +++ b/test/floating_point/float64_classification/src/main.c @@ -13,9 +13,10 @@ typedef struct testb { // uint64_t start; uint64_t end; - bool is_finite; - bool is_inf; + bool is_signaling; bool is_nan; + bool is_inf; + bool is_finite; bool is_normal; bool is_subnormal; bool is_zero; @@ -49,24 +50,28 @@ static_assert( #define NUM_TO_STR(x) MACRO_TO_STR(x) /** - * Basic Testing: 13 (Covers all exponent values and the MSB of the mantissa) + * Basic Testing: 14 (Covers all exponent values and the MSB of the mantissa) * Advanced Testing: 18 (Covers bugs that involve checking if the lower 48 bits are zero) */ -#define test_count 13 +#define test_count 14 /* fastest type that can handle 2^test_count */ typedef uint24_t test_count_t; static const testb test_values[] = { - {/* UINT64_C(0x0000000000000000), */ UINT64_C(0x0000000000000000), true , false, false, false, false, true , FP_ZERO }, - {/* UINT64_C(0x0000000000000001), */ UINT64_C(0x000FFFFFFFFFFFFF), true , false, false, false, true , false, FP_SUBNORMAL}, - {/* UINT64_C(0x0010000000000000), */ UINT64_C(0x7FEFFFFFFFFFFFFF), true , false, false, true , false, false, FP_NORMAL }, - {/* UINT64_C(0x7FF0000000000000), */ UINT64_C(0x7FF0000000000000), false, true , false, false, false, false, FP_INFINITE }, - {/* UINT64_C(0x7FF0000000000001), */ UINT64_C(0x7FFFFFFFFFFFFFFF), false, false, true , false, false, false, FP_NAN }, - {/* UINT64_C(0x8000000000000000), */ UINT64_C(0x8000000000000000), true , false, false, false, false, true , FP_ZERO }, - {/* UINT64_C(0x8000000000000001), */ UINT64_C(0x800FFFFFFFFFFFFF), true , false, false, false, true , false, FP_SUBNORMAL}, - {/* UINT64_C(0x8010000000000000), */ UINT64_C(0xFFEFFFFFFFFFFFFF), true , false, false, true , false, false, FP_NORMAL }, - {/* UINT64_C(0xFFF0000000000000), */ UINT64_C(0xFFF0000000000000), false, true , false, false, false, false, FP_INFINITE }, - {/* UINT64_C(0xFFF0000000000001), */ UINT64_C(0xFFFFFFFFFFFFFFFF), false, false, true , false, false, false, FP_NAN }, + {/* UINT64_C(0x0000000000000000), */ UINT64_C(0x0000000000000000), false, false, false, true , false, false, true , FP_ZERO }, + {/* UINT64_C(0x0000000000000001), */ UINT64_C(0x000FFFFFFFFFFFFF), false, false, false, true , false, true , false, FP_SUBNORMAL}, + {/* UINT64_C(0x0010000000000000), */ UINT64_C(0x7FEFFFFFFFFFFFFF), false, false, false, true , true , false, false, FP_NORMAL }, + {/* UINT64_C(0x7FF0000000000000), */ UINT64_C(0x7FF0000000000000), false, false, true , false, false, false, false, FP_INFINITE }, + {/* UINT64_C(0x7FF0000000000001), */ UINT64_C(0x7FF7FFFFFFFFFFFF), true , true , false, false, false, false, false, FP_NAN }, + {/* UINT64_C(0x7FF8000000000000), */ UINT64_C(0x7FF8000000000000), false, true , false, false, false, false, false, FP_NAN }, + {/* UINT64_C(0x7FF8000000000001), */ UINT64_C(0x7FFFFFFFFFFFFFFF), true , true , false, false, false, false, false, FP_NAN }, + {/* UINT64_C(0x8000000000000000), */ UINT64_C(0x8000000000000000), false, false, false, true , false, false, true , FP_ZERO }, + {/* UINT64_C(0x8000000000000001), */ UINT64_C(0x800FFFFFFFFFFFFF), false, false, false, true , false, true , false, FP_SUBNORMAL}, + {/* UINT64_C(0x8010000000000000), */ UINT64_C(0xFFEFFFFFFFFFFFFF), false, false, false, true , true , false, false, FP_NORMAL }, + {/* UINT64_C(0xFFF0000000000000), */ UINT64_C(0xFFF0000000000000), false, false, true , false, false, false, false, FP_INFINITE }, + {/* UINT64_C(0xFFF0000000000001), */ UINT64_C(0xFFF7FFFFFFFFFFFF), true , true , false, false, false, false, false, FP_NAN }, + {/* UINT64_C(0xFFF8000000000000), */ UINT64_C(0xFFF8000000000000), false, true , false, false, false, false, false, FP_NAN }, + {/* UINT64_C(0xFFF8000000000001), */ UINT64_C(0xFFFFFFFFFFFFFFFF), true , true , false, false, false, false, false, FP_NAN }, }; /** @@ -82,17 +87,19 @@ static test_result fpclassify_test(void) { const testb* ground_truth = &test_values[0]; int grouth_truth_index = 0; for (test_count_t i = 0; i < ((test_count_t)1 << test_count); i++) { + bool is_signaling = issignaling(x.flt); + bool is_nan = isnan(x.flt); bool is_finite = isfinite(x.flt); bool is_inf = isinf(x.flt); - bool is_nan = isnan(x.flt); bool is_normal = isnormal(x.flt); bool is_subnormal = issubnormal(x.flt); bool is_zero = iszero(x.flt); int fp_class = fpclassify(x.flt); if ( - is_finite != ground_truth->is_finite || - is_inf != ground_truth->is_inf || + is_signaling != ground_truth->is_signaling || is_nan != ground_truth->is_nan || + is_inf != ground_truth->is_inf || + is_finite != ground_truth->is_finite || is_normal != ground_truth->is_normal || is_subnormal != ground_truth->is_subnormal || is_zero != ground_truth->is_zero || @@ -101,15 +108,17 @@ static test_result fpclassify_test(void) { ret.passed = false; ret.failed_index = x.bin; ret.truth = - (ground_truth->is_finite << (0 * 4)) | (ground_truth->is_inf << (1 * 4)) - | (ground_truth->is_nan << (2 * 4)) | (ground_truth->is_normal << (3 * 4)) - | (ground_truth->is_subnormal << (4 * 4)) | (ground_truth->is_zero << (5 * 4)); + (ground_truth->is_signaling << (0 * 3)) | (ground_truth->is_nan << (1 * 3)) + | (ground_truth->is_inf << (2 * 3)) | (ground_truth->is_finite << (3 * 3)) + | (ground_truth->is_normal << (4 * 3)) | (ground_truth->is_subnormal << (5 * 3)) + | (ground_truth->is_zero << (6 * 3)); ret.truth_fp = ground_truth->fp_class; ret.guess = - (is_finite << (0 * 4)) | (is_inf << (1 * 4)) - | (is_nan << (2 * 4)) | (is_normal << (3 * 4)) - | (is_subnormal << (4 * 4)) | (is_zero << (5 * 4)); + (is_signaling << (0 * 3)) | (is_nan << (1 * 3)) + | (is_inf << (2 * 3)) | (is_finite << (3 * 3)) + | (is_normal << (4 * 3)) | (is_subnormal << (5 * 3)) + | (is_zero << (6 * 3)); ret.guess_fp = fp_class; return ret; @@ -138,7 +147,7 @@ int main(void) { // just in-case printf does not support long long or uint64_t const uint32_t* failed_index_split = (const uint32_t*)((const void*)&(ret.failed_index)); printf( - "Failed test:\n0x%08lX%08lX\nTruth: %06X_%d\nGuess: %06X_%d", + "Failed test:\n0x%08lX%08lX\nTruth: %06o_%d\nGuess: %06o_%d", failed_index_split[1], failed_index_split[0], ret.truth, ret.truth_fp, ret.guess, ret.guess_fp ); } @@ -146,4 +155,4 @@ int main(void) { while (!os_GetCSC()); return 0; -} \ No newline at end of file +}