From: Toni Wilen Date: Sat, 22 Apr 2017 05:21:14 +0000 (+0300) Subject: FPU cleanups. X-Git-Tag: 3500~51 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=5fff81b08c8eb7b918f627dbb96fef00b9673015;p=francis%2Fwinuae.git FPU cleanups. --- diff --git a/fpp.cpp b/fpp.cpp index e0ac93fb..8e8c12c1 100644 --- a/fpp.cpp +++ b/fpp.cpp @@ -453,7 +453,7 @@ static void fpsr_check_arithmetic_exception(uae_u32 mask, fpdata *src, uae_u32 o regs.fpu_exp_state = 1; // 68040 UNIMP frame uae_u32 reg = (extra >> 7) & 7; - uae_u32 size = (extra >> 10) & 7; + int size = (extra >> 10) & 7; fsave_data.fpiarcu = regs.fpiar; @@ -1866,6 +1866,8 @@ void fpuop_save (uae_u32 opcode) if (fault_if_no_fpu (opcode, 0, ad, pc)) return; +// write_log(_T("FSAVE %08x %08x\n"), M68K_GETPC, ad); + if (currprefs.fpu_model == 68060) { /* 12 byte 68060 NULL/IDLE/EXCP frame. */ @@ -2092,7 +2094,7 @@ void fpuop_restore (uae_u32 opcode) int fpu_version = get_fpu_version(); int frame_version; uaecptr pc = m68k_getpc () - 2; - uae_u32 ad; + uae_u32 ad, ad_orig; uae_u32 d; regs.fp_exception = false; @@ -2111,8 +2113,11 @@ void fpuop_restore (uae_u32 opcode) if (fault_if_no_fpu (opcode, 0, ad, pc)) return; + ad_orig = ad; regs.fpiar = pc; +// write_log(_T("FRESTORE %08x %08x\n"), M68K_GETPC, ad); + // FRESTORE does not support predecrement d = x_get_long (ad); @@ -2142,7 +2147,7 @@ void fpuop_restore (uae_u32 opcode) regs.fp_exp_pend = 48 + v; } } else if (ff) { - write_log (_T("FRESTORE invalid frame format %02X!\n"), ff); + write_log (_T("FRESTORE invalid frame format %02X! ADDR=%08x\n"), ff, ad_orig); Exception(14); return; } else { @@ -2211,7 +2216,7 @@ void fpuop_restore (uae_u32 opcode) fpsr_check_arithmetic_exception(0, &src, regs.fp_opword, cmdreg1b, regs.fp_ea); } else { - write_log (_T("FRESTORE resume of opclass %d instruction not supported!\n"), opclass); + write_log (_T("FRESTORE resume of opclass %d instruction not supported %08x\n"), opclass, ad_orig); } } @@ -2224,7 +2229,7 @@ void fpuop_restore (uae_u32 opcode) regs.fpu_state = 1; regs.fpu_exp_state = 0; } else { - write_log (_T("FRESTORE invalid frame size %02X!\n"), frame_size); + write_log (_T("FRESTORE invalid frame size %02X %08x\n"), frame_size, ad_orig); Exception(14); return; @@ -2233,7 +2238,7 @@ void fpuop_restore (uae_u32 opcode) } else if (frame_version == 0x00) { // null frame fpu_null(); } else { - write_log (_T("FRESTORE invalid frame version %02X!\n"), frame_version); + write_log (_T("FRESTORE invalid frame version %02X %08x\n"), frame_version, ad_orig); Exception(14); return; } @@ -2271,17 +2276,17 @@ void fpuop_restore (uae_u32 opcode) regs.fp_exp_pend = 0; } } else if (frame_size == 0xB4 || frame_size == 0xD4) { - write_log (_T("FRESTORE of busy frame not supported\n")); + write_log (_T("FRESTORE of busy frame not supported %08x\n"), ad_orig); ad += frame_size; } else { - write_log (_T("FRESTORE invalid frame size %02X!\n"), frame_size); + write_log (_T("FRESTORE invalid frame size %02X %08x\n"), frame_size, ad_orig); Exception(14); return; } } else if (frame_version == 0x00) { // null frame fpu_null(); } else { - write_log (_T("FRESTORE invalid frame version %02X!\n"), frame_version); + write_log (_T("FRESTORE invalid frame version %02X %08x\n"), frame_version, ad_orig); Exception(14); return; } diff --git a/fpp_native.cpp b/fpp_native.cpp index 3e0a3229..143b5b88 100644 --- a/fpp_native.cpp +++ b/fpp_native.cpp @@ -546,7 +546,7 @@ static void fp_round_double(fpdata *fpd) static const TCHAR *fp_print(fpdata *fpd, int mode) { static TCHAR fsout[32]; - bool n, d; + bool n; if (mode < 0) { uae_u32 w1, w2, w3; @@ -556,7 +556,6 @@ static const TCHAR *fp_print(fpdata *fpd, int mode) } n = signbit(fpd->fp) ? 1 : 0; - d = isnormal(fpd->fp) ? 0 : 1; if(isinf(fpd->fp)) { _stprintf(fsout, _T("%c%s"), n ? '-' : '+', _T("inf")); diff --git a/fpp_softfloat.cpp b/fpp_softfloat.cpp index 873e4f47..4ea988b3 100644 --- a/fpp_softfloat.cpp +++ b/fpp_softfloat.cpp @@ -600,234 +600,6 @@ static void from_native(fptype fp, fpdata *fpd) } } -#if 0 /* Old fallback functions disabled */ - -static bool to_native_checked(fptype *fp, fpdata *fpd, fpdata *dst) -{ - uint64_t aSig = extractFloatx80Frac(fpd->fpx); - int32_t aExp = extractFloatx80Exp(fpd->fpx); - if (aExp == 0x7FFF && (uint64_t)(aSig << 1)) { - dst->fpx = propagateFloatx80NaN(fpd->fpx, fpd->fpx, &fs); - return true; - } - to_native(fp, fpd); - return false; -} - -static void fp_lognp1(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_lognp1_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = logl(a->fp + 1.0); - from_native(fpa, a); -} -static void fp_sin(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_sin_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = sinl(fpa); - from_native(fpa, a); -} -static void fp_tan(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_tan_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = tanl(fpa); - from_native(fpa, a); -} -static void fp_logn(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_logn_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = logl(fpa); - from_native(fpa, a); -} -static void fp_log10(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_log10_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = log10l(fpa); - from_native(fpa, a); -} -static void fp_log2(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_log2_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = log2l(fpa); - from_native(fpa, a); -} - -static void fp_cos(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_sin_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = cosl(fpa); - from_native(fpa, a); -} - -static void fp_sinh(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_sinh_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = sinhl(fpa); - from_native(fpa, a); - fp_round(a); -} -static void fp_etoxm1(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_etoxm1_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = expl(fpa) - 1.0; - from_native(fpa, a); - fp_round(a); -} -static void fp_tanh(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_tanh_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = tanhl(fpa); - from_native(fpa, a); - fp_round(a); -} -static void fp_atan(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_atan_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = atanl(fpa); - from_native(fpa, a); - fp_round(a); -} -static void fp_asin(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_asin_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = asinl(fpa); - from_native(fpa, a); - fp_round(a); -} -static void fp_atanh(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_atanh_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = atanhl(fpa); - from_native(fpa, a); - fp_round(a); -} -static void fp_etox(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_etox_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = expl(fpa); - from_native(fpa, a); - fp_round(a); -} -static void fp_twotox(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_twotox_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = powl(2.0, fpa); - from_native(fpa, a); - fp_round(a); -} -static void fp_tentox(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_tentox_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = powl(10.0, fpa); - from_native(fpa, a); - fp_round(a); -} -static void fp_cosh(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_cosh_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = coshl(fpa); - from_native(fpa, a); - fp_round(a); -} -static void fp_acos(fpdata *a, fpdata *b) -{ - fptype fpa; - flag e = 0; - a->fpx = floatx80_acos_check(b->fpx, &e, &fs); - if (e) - return; - to_native(&fpa, b); - fpa = acosl(fpa); - from_native(fpa, a); - fp_round(a); -} - -#endif - static void fp_normalize(fpdata *a) { a->fpx = floatx80_normalize(a->fpx); diff --git a/softfloat/softfloat-specialize.h b/softfloat/softfloat-specialize.h index 8645142c..f8f84923 100644 --- a/softfloat/softfloat-specialize.h +++ b/softfloat/softfloat-specialize.h @@ -94,7 +94,7 @@ static inline flag floatx80_is_nan( floatx80 a ) /*---------------------------------------------------------------------------- | The pattern for a default generated extended double-precision NaN. *----------------------------------------------------------------------------*/ -static floatx80 floatx80_default_nan(float_status *status) +static inline floatx80 floatx80_default_nan(float_status *status) { floatx80 r; r.high = 0x7FFF; @@ -152,7 +152,7 @@ static inline flag float32_is_signaling_nan( float32 a ) | exception is raised. *----------------------------------------------------------------------------*/ -static commonNaNT float32ToCommonNaN( float32 a, float_status *status ) +static inline commonNaNT float32ToCommonNaN( float32 a, float_status *status ) { commonNaNT z; @@ -169,7 +169,7 @@ static commonNaNT float32ToCommonNaN( float32 a, float_status *status ) | precision floating-point format. *----------------------------------------------------------------------------*/ -static float32 commonNaNToFloat32( commonNaNT a ) +static inline float32 commonNaNToFloat32( commonNaNT a ) { return ( ( (uint32_t) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); @@ -182,7 +182,7 @@ static float32 commonNaNToFloat32( commonNaNT a ) | signaling NaN, the invalid exception is raised. *----------------------------------------------------------------------------*/ -static float32 propagateFloat32NaN( float32 a, float32 b, float_status *status ) +static inline float32 propagateFloat32NaN( float32 a, float32 b, float_status *status ) { flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; @@ -234,7 +234,7 @@ static inline flag float64_is_signaling_nan( float64 a ) | exception is raised. *----------------------------------------------------------------------------*/ -static commonNaNT float64ToCommonNaN(float64 a, float_status *status) +static inline commonNaNT float64ToCommonNaN(float64 a, float_status *status) { commonNaNT z; @@ -252,7 +252,7 @@ static commonNaNT float64ToCommonNaN(float64 a, float_status *status) | precision floating-point format. *----------------------------------------------------------------------------*/ -static float64 commonNaNToFloat64(commonNaNT a, float_status *status) +static inline float64 commonNaNToFloat64(commonNaNT a, float_status *status) { return ( ( (uint64_t) a.sign )<<63 ) @@ -260,32 +260,6 @@ static float64 commonNaNToFloat64(commonNaNT a, float_status *status) | ( a.high>>12 ); } -/*---------------------------------------------------------------------------- -| Takes two double-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -static float64 propagateFloat64NaN( float64 a, float64 b, float_status *status ) -{ - flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; - - aIsNaN = float64_is_nan( a ); - aIsSignalingNaN = float64_is_signaling_nan( a ); - bIsNaN = float64_is_nan( b ); - bIsSignalingNaN = float64_is_signaling_nan( b ); - a |= LIT64( 0x0008000000000000 ); - b |= LIT64( 0x0008000000000000 ); - if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_signaling, status ); - if ( aIsNaN ) { - return ( aIsSignalingNaN & bIsNaN ) ? b : a; - } - else { - return b; - } - -} - /*---------------------------------------------------------------------------- | Returns 1 if the extended double-precision floating-point value `a' is a | signaling NaN; otherwise returns 0. @@ -309,7 +283,7 @@ static inline flag floatx80_is_signaling_nan( floatx80 a ) | invalid exception is raised. *----------------------------------------------------------------------------*/ -static commonNaNT floatx80ToCommonNaN( floatx80 a, float_status *status ) +static inline commonNaNT floatx80ToCommonNaN( floatx80 a, float_status *status ) { commonNaNT z; @@ -326,7 +300,7 @@ static commonNaNT floatx80ToCommonNaN( floatx80 a, float_status *status ) | double-precision floating-point format. *----------------------------------------------------------------------------*/ -static floatx80 commonNaNToFloatx80(commonNaNT a, float_status *status) +static inline floatx80 commonNaNToFloatx80(commonNaNT a, float_status *status) { floatx80 z; #ifdef SOFTFLOAT_68K @@ -344,7 +318,7 @@ static floatx80 commonNaNToFloatx80(commonNaNT a, float_status *status) | `b' is a signaling NaN, the invalid exception is raised. *----------------------------------------------------------------------------*/ -static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b, float_status *status ) +static inline floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b, float_status *status ) { flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; diff --git a/softfloat/softfloat.cpp b/softfloat/softfloat.cpp index 0f694738..ed717cad 100644 --- a/softfloat/softfloat.cpp +++ b/softfloat/softfloat.cpp @@ -821,27 +821,6 @@ static float32 roundAndPackFloat32(flag zSign, int zExp, uint32_t zSig, } -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper single-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `roundAndPackFloat32' except that `zSig' does not have to be normalized. -| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ - -static float32 - normalizeRoundAndPackFloat32(flag zSign, int zExp, uint32_t zSig, - float_status *status) -{ - int8_t shiftCount; - - shiftCount = countLeadingZeros32( zSig ) - 1; - return roundAndPackFloat32(zSign, zExp - shiftCount, zSig< -#include - -/*============================================================================ - -This C source file is an extension to the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2a. - -=============================================================================*/ - -#include "softfloat/softfloat.h" -#include "softfloat/softfloat-specialize.h" - -/*---------------------------------------------------------------------------- -| Methods for detecting special conditions for mathematical functions -| supported by MC68881 and MC68862 mathematical coprocessor. -*----------------------------------------------------------------------------*/ - -#define pi_sig0 LIT64(0xc90fdaa22168c234) -#define pi_sig1 LIT64(0xc4c6628b80dc1cd1) - -#define pi_exp 0x4000 -#define piby2_exp 0x3FFF -#define piby4_exp 0x3FFE - -#define one_exp 0x3FFF -#define one_sig LIT64(0x8000000000000000) - -/*---------------------------------------------------------------------------- - | Arc cosine - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_acos_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF && (uint64_t) (aSig<<1)) { - return propagateFloatx80NaNOneArg(a, status); - } - - if (aExp > one_exp || (aExp == one_exp && aSig > one_sig)) { - float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; - } - - if (aExp == 0) { - if (aSig == 0) return roundAndPackFloatx80(status->floatx80_rounding_precision, - 0, piby2_exp, pi_sig0, pi_sig1, status); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | Arc sine - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_asin_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF && (uint64_t) (aSig<<1)) { - return propagateFloatx80NaNOneArg(a, status); - } - - if (aExp > one_exp || (aExp == one_exp && aSig > one_sig)) { - float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; - } - - if (aExp == 0) { - if (aSig == 0) return packFloatx80(aSign, 0, 0); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | Arc tangent - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_atan_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); - return roundAndPackFloatx80(status->floatx80_rounding_precision, - aSign, piby2_exp, pi_sig0, pi_sig1, status); - } - - if (aExp == 0) { - if (aSig == 0) return packFloatx80(aSign, 0, 0); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | Hyperbolic arc tangent - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_atanh_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF && (uint64_t) (aSig<<1)) { - return propagateFloatx80NaNOneArg(a, status); - } - - if (aExp >= one_exp) { - if (aExp == one_exp && aSig == one_sig) { - float_raise(float_flag_divbyzero, status); - packFloatx80(aSign, 0x7FFF, floatx80_default_infinity_low); - } - float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; - } - - if (aExp == 0) { - if (aSig == 0) return packFloatx80(aSign, 0, 0); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | Cosine - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_cos_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); - float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; - } - - if (aExp == 0) { - if (aSig == 0) return packFloatx80(0, one_exp, one_sig); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | Hyperbolic cosine - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_cosh_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); - return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low); - } - - if (aExp == 0) { - if (aSig == 0) return packFloatx80(0, one_exp, one_sig); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | e to x - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_etox_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); - if (aSign) return packFloatx80(0, 0, 0); - return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low); - } - - if (aExp == 0) { - if (aSig == 0) return packFloatx80(0, one_exp, one_sig); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | e to x minus 1 - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_etoxm1_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); - if (aSign) return packFloatx80(aSign, one_exp, one_sig); - return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low); - } - - if (aExp == 0) { - if (aSig == 0) return packFloatx80(aSign, 0, 0); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | Log base 10 - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_log10_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) propagateFloatx80NaNOneArg(a, status); - if (aSign == 0) - return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low); - } - - if (aExp == 0) { - if (aSig == 0) { - float_raise(float_flag_divbyzero, status); - return packFloatx80(1, 0x7FFF, floatx80_default_infinity_low); - } - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - if (aSign) { - float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | Log base 2 - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_log2_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) propagateFloatx80NaNOneArg(a, status); - if (aSign == 0) - return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low); - } - - if (aExp == 0) { - if (aSig == 0) { - float_raise(float_flag_divbyzero, status); - return packFloatx80(1, 0x7FFF, floatx80_default_infinity_low); - } - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - if (aSign) { - float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | Log base e - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_logn_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) propagateFloatx80NaNOneArg(a, status); - if (aSign == 0) - return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low); - } - - if (aExp == 0) { - if (aSig == 0) { - float_raise(float_flag_divbyzero, status); - return packFloatx80(1, 0x7FFF, floatx80_default_infinity_low); - } - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - if (aSign) { - float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | Log base e of x plus 1 - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_lognp1_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) propagateFloatx80NaNOneArg(a, status); - if (aSign) { - float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; - } - return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low); - } - - if (aExp == 0) { - if (aSig == 0) return packFloatx80(aSign, 0, 0); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - if (aSign && aExp >= one_exp) { - if (aExp == one_exp && aSig == one_sig) { - float_raise(float_flag_divbyzero, status); - packFloatx80(aSign, 0x7FFF, floatx80_default_infinity_low); /* NaN? */ - } - float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | Sine - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_sin_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); - float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; - } - - if (aExp == 0) { - if (aSig == 0) return packFloatx80(aSign, 0, 0); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | Hyperbolic sine - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_sinh_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); - return packFloatx80(aSign, 0x7FFF, floatx80_default_infinity_low); - } - - if (aExp == 0) { - if (aSig == 0) return packFloatx80(aSign, 0, 0); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | Tangent - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_tan_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); - float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; - } - - if (aExp == 0) { - if (aSig == 0) return packFloatx80(aSign, 0, 0); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | Hyperbolic tangent - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_tanh_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); - return packFloatx80(aSign, one_exp, one_sig); - } - - if (aExp == 0) { - if (aSig == 0) return packFloatx80(aSign, 0, 0); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | 10 to x - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_tentox_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); - if (aSign) return packFloatx80(0, 0, 0); - return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low); - } - - if (aExp == 0) { - if (aSig == 0) return packFloatx80(0, one_exp, one_sig); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - *e = 0; - return a; -} - -/*---------------------------------------------------------------------------- - | 2 to x - *----------------------------------------------------------------------------*/ - -floatx80 floatx80_twotox_check(floatx80 a, flag *e, float_status *status) -{ - flag aSign; - int32_t aExp; - uint64_t aSig; - - *e = 1; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); - if (aSign) return packFloatx80(0, 0, 0); - return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low); - } - - if (aExp == 0) { - if (aSig == 0) return packFloatx80(0, one_exp, one_sig); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - - *e = 0; - return a; -}