From: Toni Wilen Date: Mon, 23 Jul 2018 18:54:31 +0000 (+0300) Subject: Softfloat FPU updates. New undocumented features emulated. X-Git-Tag: 4100~144 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=f29b784f4d7aecaefb2b0ccb0d700769701df418;p=francis%2Fwinuae.git Softfloat FPU updates. New undocumented features emulated. --- diff --git a/fpp.cpp b/fpp.cpp index 545b1181..f7d3c7fc 100644 --- a/fpp.cpp +++ b/fpp.cpp @@ -431,9 +431,10 @@ static void fpsr_check_arithmetic_exception(uae_u32 mask, fpdata *src, uae_u32 o uae_u32 exception; // Any exception status bit and matching exception enable bits set? exception = regs.fpsr & regs.fpcr & 0xff00; - // Add 68040/68060 nonmaskable exceptions - if (currprefs.cpu_model >= 68040 && currprefs.fpu_model) + // Add 68040/68060 nonmaskable exceptions. Only if no unimplemented instruction emulation. + if (currprefs.cpu_model >= 68040 && currprefs.fpu_model && currprefs.fpu_no_unimplemented) { exception |= regs.fpsr & (FPSR_OVFL | FPSR_UNFL | mask); + } if (exception) { regs.fp_exp_pend = fpsr_get_vector(exception); @@ -614,7 +615,7 @@ static uae_u32 fpsr_make_status(void) // return exceptions that interrupt calculation exception = regs.fpsr & regs.fpcr & (FPSR_SNAN | FPSR_OPERR | FPSR_DZ); - if (currprefs.cpu_model >= 68040 && currprefs.fpu_model) + if (currprefs.cpu_model >= 68040 && currprefs.fpu_model && currprefs.fpu_no_unimplemented) exception |= regs.fpsr & (FPSR_OVFL | FPSR_UNFL); return exception; @@ -1000,7 +1001,7 @@ static void fp_unimp_datatype(uae_u16 opcode, uae_u16 extra, uae_u32 ea, uaecptr } if (warned > 0) { write_log (_T("FPU unimplemented datatype (%s): OP=%04X-%04X SRC=%08X-%08X-%08X EA=%08X PC=%08X\n"), - packed ? "packed" : "denormal", opcode, extra, + packed ? _T("packed") : _T("denormal"), opcode, extra, packed ? fsave_data.fpt[2] : fsave_data.et[0], fsave_data.et[1], fsave_data.et[2], ea, oldpc); #if EXCEPTION_FPP == 0 warned--; @@ -1306,18 +1307,6 @@ static bool fault_if_68040_integer_nonmaskable(uae_u16 opcode, uae_u16 extra, ua return false; } -#if 0 -// 68040/060 automatically converts infinity -static void check_and_fix_infinity(fpdata *value) -{ - if (fpp_fix_infinity && (currprefs.fpu_model == 68040 || currprefs.fpu_model == 68060)) { - if (fpp_is_infinity(value)) { - fpp_fix_infinity(value); - } - } -} -#endif - static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr oldpc, uae_u32 *adp) { int size, mode, reg; @@ -1331,9 +1320,6 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old if (fault_if_no_fpu (opcode, extra, 0, oldpc)) return -1; *src = regs.fp[(extra >> 10) & 7]; -#if 0 - check_and_fix_infinity(src); -#endif normalize_or_fault_if_no_denormal_support(opcode, extra, 0, oldpc, src); return 1; } @@ -3112,10 +3098,6 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra) v = fp_arithmetic(&src, &dst, extra); -#if 0 - check_and_fix_infinity(&dst); -#endif - fpsr_check_arithmetic_exception(0, &src, opcode, extra, ad); if (v) @@ -3163,7 +3145,7 @@ void fpu_modechange(void) fpp_from_exten_fmovem(®s.fp[i], &temp_ext[i][0], &temp_ext[i][1], &temp_ext[i][2]); } if (currprefs.fpu_mode > 0) { - fp_init_softfloat(); + fp_init_softfloat(currprefs.fpu_model); #ifdef MSVC_LONG_DOUBLE use_long_double = false; } else if (currprefs.fpu_mode < 0) { @@ -3201,7 +3183,7 @@ static void fpu_test(void) void fpu_reset (void) { if (currprefs.fpu_mode > 0) { - fp_init_softfloat(); + fp_init_softfloat(currprefs.fpu_model); #ifdef MSVC_LONG_DOUBLE use_long_double = false; } else if (currprefs.fpu_mode < 0) { diff --git a/fpp_softfloat.cpp b/fpp_softfloat.cpp index aa754c92..e11a772e 100644 --- a/fpp_softfloat.cpp +++ b/fpp_softfloat.cpp @@ -733,15 +733,15 @@ static void fp_from_pack(fpdata *fp, uae_u32 *wrd, int kfactor) } } -void fp_init_softfloat(void) +void fp_init_softfloat(int fpu_model) { - float_status fsx = { 0 }; - - fsx.fpu_model = currprefs.fpu_model; - fs.fpu_model = currprefs.fpu_model; - - set_floatx80_rounding_precision(80, &fsx); - set_float_rounding_mode(float_round_to_zero, &fsx); + if (fpu_model == 68040) { + set_special_flags(cmp_signed_nan, &fs); + } else if (fpu_model == 68060) { + set_special_flags(infinity_clear_intbit, &fs); + } else { + set_special_flags(addsub_swap_inf, &fs); + } fpp_print = fp_print; fpp_unset_snan = fp_unset_snan; diff --git a/include/fpp.h b/include/fpp.h index 32c8ca9b..49eaa348 100644 --- a/include/fpp.h +++ b/include/fpp.h @@ -20,7 +20,7 @@ extern void fp_init_native(void); #ifdef MSVC_LONG_DOUBLE extern void fp_init_native_80(void); #endif -extern void fp_init_softfloat(void); +extern void fp_init_softfloat(int); extern void fpsr_set_exception(uae_u32 exception); extern void fpu_modechange(void); extern void fpu_clearstatus(void); diff --git a/softfloat/softfloat.cpp b/softfloat/softfloat.cpp index 59f9e118..f2f0787a 100644 --- a/softfloat/softfloat.cpp +++ b/softfloat/softfloat.cpp @@ -2157,16 +2157,17 @@ floatx80 floatx80_round_to_int(floatx80 a, float_status *status) flag aSign; int32_t aExp; uint64_t lastBitMask, roundBitsMask; - floatx80 z; + int8_t roundingMode; + floatx80 z; - if (floatx80_invalid_encoding(a)) { - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } + roundingMode = status->float_rounding_mode; + aSign = extractFloatx80Sign(a); aExp = extractFloatx80Exp( a ); if ( 0x403E <= aExp ) { - if ( ( aExp == 0x7FFF ) && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) { - return propagateFloatx80NaNOneArg(a, status); + if ( aExp == 0x7FFF ) { + if ((uint64_t) ( extractFloatx80Frac( a )<<1 ) ) + return propagateFloatx80NaNOneArg(a, status); + return inf_clear_intbit(status) ? packFloatx80(aSign, aExp, 0) : a; } return a; } @@ -2180,7 +2181,6 @@ floatx80 floatx80_round_to_int(floatx80 a, float_status *status) return a; } status->float_exception_flags |= float_flag_inexact; - aSign = extractFloatx80Sign( a ); switch (status->float_rounding_mode) { case float_round_nearest_even: if ( ( aExp == 0x3FFE ) && (uint64_t) ( extractFloatx80Frac( a )<<1 ) @@ -2255,10 +2255,13 @@ floatx80 floatx80_round_to_int_toward_zero( floatx80 a, float_status *status) uint64_t lastBitMask, roundBitsMask; floatx80 z; - aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign(a); + aExp = extractFloatx80Exp( a ); if ( 0x403E <= aExp ) { - if ( ( aExp == 0x7FFF ) && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) { - return propagateFloatx80NaNOneArg( a, status ); + if ( aExp == 0x7FFF ) { + if ( (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) + return propagateFloatx80NaNOneArg( a, status ); + return inf_clear_intbit(status) ? packFloatx80(aSign, aExp, 0) : a; } return a; } @@ -2272,7 +2275,6 @@ floatx80 floatx80_round_to_int_toward_zero( floatx80 a, float_status *status) return a; } status->float_exception_flags |= float_flag_inexact; - aSign = extractFloatx80Sign( a ); return packFloatx80( aSign, 0, 0 ); } lastBitMask = 1; @@ -2320,10 +2322,9 @@ static floatx80 addFloatx80Sigs(floatx80 a, floatx80 b, flag zSign, expDiff = aExp - bExp; if ( 0 < expDiff ) { if ( aExp == 0x7FFF ) { - if ((uint64_t)(aSig << 1)) { + if ((uint64_t)(aSig << 1)) return propagateFloatx80NaN(a, b, status); - } - return a; + return inf_clear_intbit(status) ? packFloatx80(extractFloatx80Sign(a), aExp, 0) : a; } #ifndef SOFTFLOAT_68K if ( bExp == 0 ) --expDiff; @@ -2333,10 +2334,10 @@ static floatx80 addFloatx80Sigs(floatx80 a, floatx80 b, flag zSign, } else if ( expDiff < 0 ) { if ( bExp == 0x7FFF ) { - if ((uint64_t)(bSig << 1)) { + if ((uint64_t)(bSig << 1)) return propagateFloatx80NaN(a, b, status); - } - return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low ); + if (inf_clear_intbit(status)) bSig = 0; + return packFloatx80( zSign, bExp, bSig ); } #ifndef SOFTFLOAT_68K if ( aExp == 0 ) ++expDiff; @@ -2349,7 +2350,8 @@ static floatx80 addFloatx80Sigs(floatx80 a, floatx80 b, flag zSign, if ( (uint64_t) ( ( aSig | bSig )<<1 ) ) { return propagateFloatx80NaN(a, b, status); } - return a; + if (inf_clear_intbit(status)) return packFloatx80(extractFloatx80Sign(a), aExp, 0); + return faddsub_swap_inf(status) ? b : a; } zSig1 = 0; zSig0 = aSig + bSig; @@ -2418,11 +2420,10 @@ static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, flag zSign, return packFloatx80(status->float_rounding_mode == float_round_down, 0, 0); bExpBigger: if ( bExp == 0x7FFF ) { - if ((uint64_t)(bSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } + if ((uint64_t)(bSig << 1)) return propagateFloatx80NaN(a, b, status); + if (inf_clear_intbit(status)) bSig = 0; + return packFloatx80(zSign ^ 1, bExp, bSig); + } #ifndef SOFTFLOAT_68K if ( aExp == 0 ) ++expDiff; #endif @@ -2434,11 +2435,9 @@ static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, flag zSign, goto normalizeRoundAndPack; aExpBigger: if ( aExp == 0x7FFF ) { - if ((uint64_t)(aSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - return a; - } + if ((uint64_t)(aSig << 1)) return propagateFloatx80NaN(a, b, status); + return inf_clear_intbit(status) ? packFloatx80(extractFloatx80Sign(a), aExp, 0) : a; + } #ifndef SOFTFLOAT_68K if ( bExp == 0 ) --expDiff; #endif @@ -2530,8 +2529,9 @@ floatx80 floatx80_mul(floatx80 a, floatx80 b, float_status *status) return propagateFloatx80NaN(a, b, status); } if ( ( bExp | bSig ) == 0 ) goto invalid; - return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low ); - } + if (inf_clear_intbit(status)) aSig = 0; + return packFloatx80(zSign, aExp, aSig); + } if ( bExp == 0x7FFF ) { if ((uint64_t)(bSig << 1)) { return propagateFloatx80NaN(a, b, status); @@ -2541,8 +2541,9 @@ floatx80 floatx80_mul(floatx80 a, floatx80 b, float_status *status) float_raise(float_flag_invalid, status); return floatx80_default_nan(status); } - return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low ); - } + if (inf_clear_intbit(status)) bSig = 0; + return packFloatx80(zSign, bExp, bSig); + } if ( aExp == 0 ) { if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); @@ -2567,7 +2568,6 @@ floatx80 floatx80_sglmul( floatx80 a, floatx80 b, float_status *status ) flag aSign, bSign, zSign; int32_t aExp, bExp, zExp; uint64_t aSig, bSig, zSig0, zSig1; - floatx80 z; aSig = extractFloatx80Frac( a ); aExp = extractFloatx80Exp( a ); @@ -2582,18 +2582,18 @@ floatx80 floatx80_sglmul( floatx80 a, floatx80 b, float_status *status ) return propagateFloatx80NaN( a, b, status ); } if ( ( bExp | bSig ) == 0 ) goto invalid; - return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low ); + if (inf_clear_intbit(status)) aSig = 0; + return packFloatx80(zSign, aExp, aSig); } if ( bExp == 0x7FFF ) { if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, status ); if ( ( aExp | aSig ) == 0 ) { invalid: float_raise( float_flag_invalid, status ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; + return floatx80_default_nan(status); } - return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low ); + if (inf_clear_intbit(status)) bSig = 0; + return packFloatx80(zSign, bExp, bSig); } if ( aExp == 0 ) { if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); @@ -2651,8 +2651,9 @@ floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status) } goto invalid; } - return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low ); - } + if (inf_clear_intbit(status)) aSig = 0; + return packFloatx80(zSign, aExp, aSig); + } if ( bExp == 0x7FFF ) { if ((uint64_t)(bSig << 1)) { return propagateFloatx80NaN(a, b, status); @@ -2709,7 +2710,6 @@ floatx80 floatx80_sgldiv( floatx80 a, floatx80 b, float_status *status ) int32_t aExp, bExp, zExp; uint64_t aSig, bSig, zSig0, zSig1; uint64_t rem0, rem1, rem2, term0, term1, term2; - floatx80 z; aSig = extractFloatx80Frac( a ); aExp = extractFloatx80Exp( a ); @@ -2724,7 +2724,8 @@ floatx80 floatx80_sgldiv( floatx80 a, floatx80 b, float_status *status ) if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, status ); goto invalid; } - return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low ); + if (inf_clear_intbit(status)) aSig = 0; + return packFloatx80(zSign, aExp, aSig); } if ( bExp == 0x7FFF ) { if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, status ); @@ -2735,9 +2736,7 @@ floatx80 floatx80_sgldiv( floatx80 a, floatx80 b, float_status *status ) if ( ( aExp | aSig ) == 0 ) { invalid: float_raise( float_flag_invalid, status ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; + return floatx80_default_nan(status); } float_raise( float_flag_divbyzero, status ); return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low ); @@ -2884,7 +2883,6 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b, uint64_t *q, flag *s, float_statu int32_t aExp, bExp, expDiff; uint64_t aSig0, aSig1, bSig; uint64_t qTemp, term0, term1, alternateASig0, alternateASig1; - floatx80 z; aSig0 = extractFloatx80Frac( a ); aExp = extractFloatx80Exp( a ); @@ -2910,9 +2908,7 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b, uint64_t *q, flag *s, float_statu if ( bSig == 0 ) { invalid: float_raise( float_flag_invalid, status ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; + return floatx80_default_nan(status); } normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); } @@ -2999,7 +2995,6 @@ floatx80 floatx80_mod( floatx80 a, floatx80 b, uint64_t *q, flag *s, float_statu int32_t aExp, bExp, expDiff; uint64_t aSig0, aSig1, bSig; uint64_t qTemp, term0, term1; - floatx80 z; aSig0 = extractFloatx80Frac( a ); aExp = extractFloatx80Exp( a ); @@ -3025,10 +3020,8 @@ floatx80 floatx80_mod( floatx80 a, floatx80 b, uint64_t *q, flag *s, float_statu if ( bSig == 0 ) { invalid: float_raise( float_flag_invalid, status ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } + return floatx80_default_nan(status); + } normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); } if ( aExp == 0 ) { @@ -3105,10 +3098,9 @@ floatx80 floatx80_sqrt(floatx80 a, float_status *status) aExp = extractFloatx80Exp( a ); aSign = extractFloatx80Sign( a ); if ( aExp == 0x7FFF ) { - if ((uint64_t)(aSig0 << 1)) { + if ((uint64_t)(aSig0 << 1)) return propagateFloatx80NaNOneArg(a, status); - } - if ( ! aSign ) return a; + if (!aSign) return inf_clear_intbit(status) ? packFloatx80(aSign, aExp, 0) : a; goto invalid; } if ( aSign ) { @@ -3175,9 +3167,7 @@ floatx80 floatx80_getman( floatx80 a, float_status *status) 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; + return floatx80_default_nan(status); } if ( aExp == 0 ) { @@ -3206,9 +3196,7 @@ floatx80 floatx80_getexp( floatx80 a, float_status *status) 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; + return floatx80_default_nan(status); } if ( aExp == 0 ) { @@ -3246,13 +3234,11 @@ floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status) return propagateFloatx80NaN( a, b, status ); } float_raise( float_flag_invalid, status ); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; + return floatx80_default_nan(status); } if ( aExp == 0x7FFF ) { if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b, status ); - return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + return a; } if ( aExp == 0 ) { if ( aSig == 0 ) return packFloatx80( aSign, 0, 0); @@ -3294,8 +3280,9 @@ floatx80 floatx80_abs(floatx80 a, float_status *status) if ( aExp == 0x7FFF ) { if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaNOneArg( a, status ); - return packFloatx80( 0, 0x7FFF, floatx80_default_infinity_low ); - } + if (inf_clear_intbit(status)) aSig = 0; + return packFloatx80(0, aExp, aSig); + } if ( aExp == 0 ) { if ( aSig == 0 ) return packFloatx80( 0, 0, 0 ); @@ -3326,8 +3313,9 @@ floatx80 floatx80_neg(floatx80 a, float_status *status) if ( aExp == 0x7FFF ) { if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaNOneArg( a, status ); - return packFloatx80 ( !aSign, 0x7FFF, floatx80_default_infinity_low ); - } + if (inf_clear_intbit(status)) aSig = 0; + return packFloatx80(!aSign, aExp, aSig); + } aSign = !aSign; @@ -3363,9 +3351,8 @@ floatx80 floatx80_cmp( floatx80 a, floatx80 b, float_status *status ) if ( ( aExp == 0x7FFF && (uint64_t) ( aSig<<1 ) ) || ( bExp == 0x7FFF && (uint64_t) ( bSig<<1 ) ) ) { // 68040 FCMP -NaN return N flag set - if (status->fpu_model == 68040) - return propagateFloatx80NaN( packFloatx80( aSign, aExp, aSig ), - packFloatx80( bSign, bExp, bSig ), status ); + if (fcmp_signed_nan(status)) + return propagateFloatx80NaN(a, b, status ); return propagateFloatx80NaN(packFloatx80(0, aExp, aSig), packFloatx80(0, bExp, bSig), status); } @@ -3413,8 +3400,8 @@ floatx80 floatx80_move( floatx80 a, float_status *status ) aSign = extractFloatx80Sign( a ); if ( aExp == 0x7FFF ) { - if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaNOneArg( a, status ); - return a; + if ((uint64_t)(aSig << 1)) return propagateFloatx80NaNOneArg(a, status); + return inf_clear_intbit(status) ? packFloatx80(aSign, aExp, 0) : a; } if ( aExp == 0 ) { if ( aSig == 0 ) return a; diff --git a/softfloat/softfloat.h b/softfloat/softfloat.h index 061eca5d..727ad888 100644 --- a/softfloat/softfloat.h +++ b/softfloat/softfloat.h @@ -221,7 +221,7 @@ typedef struct float_status { flag flush_inputs_to_zero; flag default_nan_mode; flag snan_bit_is_one; - uint32_t fpu_model; + flag floatx80_special_flags; } float_status; /*---------------------------------------------------------------------------- @@ -298,6 +298,30 @@ static inline flag get_default_nan_mode(float_status *status) return status->default_nan_mode; } +/*---------------------------------------------------------------------------- +| Special flags for indicating some unique behavior is required. +*----------------------------------------------------------------------------*/ +enum { + cmp_signed_nan = 0x01, addsub_swap_inf = 0x02, infinity_clear_intbit = 0x04 +}; + +static inline void set_special_flags(uint8_t flags, float_status *status) +{ + status->floatx80_special_flags = flags; +} +static inline int8_t fcmp_signed_nan(float_status *status) +{ + return status->floatx80_special_flags & cmp_signed_nan; +} +static inline int8_t faddsub_swap_inf(float_status *status) +{ + return status->floatx80_special_flags & addsub_swap_inf; +} +static inline int8_t inf_clear_intbit(float_status *status) +{ + return status->floatx80_special_flags & infinity_clear_intbit; +} + /*---------------------------------------------------------------------------- | Routine to raise any or all of the software IEC/IEEE floating-point | exception flags. diff --git a/softfloat/softfloat_fpsp.cpp b/softfloat/softfloat_fpsp.cpp index 177b0f10..7753cf01 100644 --- a/softfloat/softfloat_fpsp.cpp +++ b/softfloat/softfloat_fpsp.cpp @@ -92,9 +92,7 @@ floatx80 floatx80_acos(floatx80 a, float_status *status) } } else { // |X| > 1 float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; + return floatx80_default_nan(status); } } // |X| < 1 @@ -152,9 +150,7 @@ floatx80 floatx80_asin(floatx80 a, float_status *status) return floatx80_move(a, status); } else { // |X| > 1 float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; + return floatx80_default_nan(status); } } // |X| < 1 @@ -369,9 +365,7 @@ floatx80 floatx80_atanh(floatx80 a, float_status *status) return packFloatx80(aSign, 0x7FFF, floatx80_default_infinity_low); } else { // |X| > 1 float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; + return floatx80_default_nan(status); } } // |X| < 1 @@ -417,9 +411,7 @@ floatx80 floatx80_cos(floatx80 a, float_status *status) 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; + return floatx80_default_nan(status); } if (aExp == 0 && aSig == 0) { @@ -619,7 +611,7 @@ floatx80 floatx80_cosh(floatx80 a, float_status *status) if (aExp == 0x7FFF) { if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); - return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low); + return packFloatx80(0, aExp, aSig); } if (aExp == 0 && aSig == 0) { @@ -687,7 +679,7 @@ floatx80 floatx80_etox(floatx80 a, float_status *status) 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); + return a; } if (aExp == 0 && aSig == 0) { @@ -822,7 +814,7 @@ floatx80 floatx80_etoxm1(floatx80 a, float_status *status) 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); + return a; } if (aExp == 0 && aSig == 0) { @@ -1005,7 +997,7 @@ floatx80 floatx80_log10(floatx80 a, float_status *status) if (aExp == 0x7FFF) { if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); if (aSign == 0) - return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low); + return a; } if (aExp == 0 && aSig == 0) { @@ -1015,9 +1007,7 @@ floatx80 floatx80_log10(floatx80 a, float_status *status) if (aSign) { float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; + return floatx80_default_nan(status); } SET_PREC; @@ -1053,7 +1043,7 @@ floatx80 floatx80_log2(floatx80 a, float_status *status) if (aExp == 0x7FFF) { if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); if (aSign == 0) - return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low); + return a; } if (aExp == 0) { @@ -1066,9 +1056,7 @@ floatx80 floatx80_log2(floatx80 a, float_status *status) if (aSign) { float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; + return floatx80_default_nan(status); } SET_PREC; @@ -1111,7 +1099,7 @@ floatx80 floatx80_logn(floatx80 a, float_status *status) if (aExp == 0x7FFF) { if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); if (aSign == 0) - return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low); + return a; } adjk = 0; @@ -1135,9 +1123,7 @@ floatx80 floatx80_logn(floatx80 a, float_status *status) if (aSign) { float_raise(float_flag_invalid, status); - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; + return floatx80_default_nan(status); } SET_PREC; @@ -1247,11 +1233,9 @@ floatx80 floatx80_lognp1(floatx80 a, float_status *status) if ((uint64_t) (aSig<<1)) return 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 floatx80_default_nan(status); } - return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low); + return a; } if (aExp == 0 && aSig == 0) { @@ -1264,9 +1248,7 @@ floatx80 floatx80_lognp1(floatx80 a, float_status *status) return 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; + return floatx80_default_nan(status); } if (aExp < 0x3f99 || (aExp == 0x3f99 && aSig == one_sig)) { // <= min threshold @@ -1409,9 +1391,7 @@ floatx80 floatx80_sin(floatx80 a, float_status *status) 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; + return floatx80_default_nan(status); } if (aExp == 0 && aSig == 0) { @@ -1612,7 +1592,7 @@ floatx80 floatx80_sinh(floatx80 a, float_status *status) if (aExp == 0x7FFF) { if ((uint64_t) (aSig<<1)) return propagateFloatx80NaNOneArg(a, status); - return packFloatx80(aSign, 0x7FFF, floatx80_default_infinity_low); + return a; } if (aExp == 0 && aSig == 0) { @@ -1687,9 +1667,7 @@ floatx80 floatx80_tan(floatx80 a, float_status *status) 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; + return floatx80_default_nan(status); } if (aExp == 0 && aSig == 0) { @@ -1962,7 +1940,7 @@ floatx80 floatx80_tentox(floatx80 a, float_status *status) 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); + return a; } if (aExp == 0 && aSig == 0) { @@ -2079,7 +2057,7 @@ floatx80 floatx80_twotox(floatx80 a, float_status *status) 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); + return a; } if (aExp == 0 && aSig == 0) {