Commit 4b86bac2 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/lalrae/tags/mips-20160624' into staging



MIPS patches 2016-06-24

Changes:
* support IEEE 754-2008 in MIPS CPUs

# gpg: Signature made Fri 24 Jun 2016 16:09:38 BST
# gpg:                using RSA key 0x52118E3C0B29DA6B
# gpg: Good signature from "Leon Alrae <leon.alrae@imgtec.com>"
# Primary key fingerprint: 8DD3 2F98 5495 9D66 35D4  4FC0 5211 8E3C 0B29 DA6B

* remotes/lalrae/tags/mips-20160624:
  target-mips: Add FCR31's FS bit definition
  target-mips: Implement FCR31's R/W bitmask and related functionalities
  target-mips: Add nan2008 flavor of <CEIL|CVT|FLOOR|ROUND|TRUNC>.<L|W>.<S|D>
  target-mips: Add abs2008 flavor of <ABS|NEG>.<S|D>
  target-mips: Activate IEEE 754-2008 signaling NaN bit meaning for MSA
  linux-user: Update preprocessor constants for Mips-specific e_flags bits
  softfloat: Handle snan_bit_is_one == 0 in MIPS pickNaNMulAdd()
  softfloat: For Mips only, correct default NaN values
  softfloat: Clean code format in fpu/softfloat-specialize.h
  softfloat: Implement run-time-configurable meaning of signaling NaN bit

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 929bf947 77be4199
Loading
Loading
Loading
Loading
+333 −326

File changed.

Preview size limit exceeded, changes collapsed.

+75 −97
Original line number Diff line number Diff line
@@ -2105,7 +2105,7 @@ static float32 subFloat32Sigs(float32 a, float32 b, flag zSign,
            return propagateFloat32NaN(a, b, status);
        }
        float_raise(float_flag_invalid, status);
        return float32_default_nan;
        return float32_default_nan(status);
    }
    if ( aExp == 0 ) {
        aExp = 1;
@@ -2234,7 +2234,7 @@ float32 float32_mul(float32 a, float32 b, float_status *status)
        }
        if ( ( bExp | bSig ) == 0 ) {
            float_raise(float_flag_invalid, status);
            return float32_default_nan;
            return float32_default_nan(status);
        }
        return packFloat32( zSign, 0xFF, 0 );
    }
@@ -2244,7 +2244,7 @@ float32 float32_mul(float32 a, float32 b, float_status *status)
        }
        if ( ( aExp | aSig ) == 0 ) {
            float_raise(float_flag_invalid, status);
            return float32_default_nan;
            return float32_default_nan(status);
        }
        return packFloat32( zSign, 0xFF, 0 );
    }
@@ -2299,7 +2299,7 @@ float32 float32_div(float32 a, float32 b, float_status *status)
                return propagateFloat32NaN(a, b, status);
            }
            float_raise(float_flag_invalid, status);
            return float32_default_nan;
            return float32_default_nan(status);
        }
        return packFloat32( zSign, 0xFF, 0 );
    }
@@ -2313,7 +2313,7 @@ float32 float32_div(float32 a, float32 b, float_status *status)
        if ( bSig == 0 ) {
            if ( ( aExp | aSig ) == 0 ) {
                float_raise(float_flag_invalid, status);
                return float32_default_nan;
                return float32_default_nan(status);
            }
            float_raise(float_flag_divbyzero, status);
            return packFloat32( zSign, 0xFF, 0 );
@@ -2367,7 +2367,7 @@ float32 float32_rem(float32 a, float32 b, float_status *status)
            return propagateFloat32NaN(a, b, status);
        }
        float_raise(float_flag_invalid, status);
        return float32_default_nan;
        return float32_default_nan(status);
    }
    if ( bExp == 0xFF ) {
        if (bSig) {
@@ -2378,7 +2378,7 @@ float32 float32_rem(float32 a, float32 b, float_status *status)
    if ( bExp == 0 ) {
        if ( bSig == 0 ) {
            float_raise(float_flag_invalid, status);
            return float32_default_nan;
            return float32_default_nan(status);
        }
        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
    }
@@ -2493,7 +2493,7 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags,

    if (infzero) {
        float_raise(float_flag_invalid, status);
        return float32_default_nan;
        return float32_default_nan(status);
    }

    if (flags & float_muladd_negate_c) {
@@ -2514,7 +2514,7 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags,
        if (pInf && (pSign ^ cSign)) {
            /* addition of opposite-signed infinities => InvalidOperation */
            float_raise(float_flag_invalid, status);
            return float32_default_nan;
            return float32_default_nan(status);
        }
        /* Otherwise generate an infinity of the same sign */
        return packFloat32(cSign ^ signflip, 0xff, 0);
@@ -2690,12 +2690,12 @@ float32 float32_sqrt(float32 a, float_status *status)
        }
        if ( ! aSign ) return a;
        float_raise(float_flag_invalid, status);
        return float32_default_nan;
        return float32_default_nan(status);
    }
    if ( aSign ) {
        if ( ( aExp | aSig ) == 0 ) return a;
        float_raise(float_flag_invalid, status);
        return float32_default_nan;
        return float32_default_nan(status);
    }
    if ( aExp == 0 ) {
        if ( aSig == 0 ) return float32_zero;
@@ -2828,7 +2828,7 @@ float32 float32_log2(float32 a, float_status *status)
    }
    if ( aSign ) {
        float_raise(float_flag_invalid, status);
        return float32_default_nan;
        return float32_default_nan(status);
    }
    if ( aExp == 0xFF ) {
        if (aSig) {
@@ -2974,7 +2974,8 @@ int float32_eq_quiet(float32 a, float32 b, float_status *status)
    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
       ) {
        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
        if (float32_is_signaling_nan(a, status)
         || float32_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 0;
@@ -3000,7 +3001,8 @@ int float32_le_quiet(float32 a, float32 b, float_status *status)
    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
       ) {
        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
        if (float32_is_signaling_nan(a, status)
         || float32_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 0;
@@ -3031,7 +3033,8 @@ int float32_lt_quiet(float32 a, float32 b, float_status *status)
    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
       ) {
        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
        if (float32_is_signaling_nan(a, status)
         || float32_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 0;
@@ -3060,7 +3063,8 @@ int float32_unordered_quiet(float32 a, float32 b, float_status *status)
    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
       ) {
        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
        if (float32_is_signaling_nan(a, status)
         || float32_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 1;
@@ -3896,7 +3900,7 @@ static float64 subFloat64Sigs(float64 a, float64 b, flag zSign,
            return propagateFloat64NaN(a, b, status);
        }
        float_raise(float_flag_invalid, status);
        return float64_default_nan;
        return float64_default_nan(status);
    }
    if ( aExp == 0 ) {
        aExp = 1;
@@ -4023,7 +4027,7 @@ float64 float64_mul(float64 a, float64 b, float_status *status)
        }
        if ( ( bExp | bSig ) == 0 ) {
            float_raise(float_flag_invalid, status);
            return float64_default_nan;
            return float64_default_nan(status);
        }
        return packFloat64( zSign, 0x7FF, 0 );
    }
@@ -4033,7 +4037,7 @@ float64 float64_mul(float64 a, float64 b, float_status *status)
        }
        if ( ( aExp | aSig ) == 0 ) {
            float_raise(float_flag_invalid, status);
            return float64_default_nan;
            return float64_default_nan(status);
        }
        return packFloat64( zSign, 0x7FF, 0 );
    }
@@ -4090,7 +4094,7 @@ float64 float64_div(float64 a, float64 b, float_status *status)
                return propagateFloat64NaN(a, b, status);
            }
            float_raise(float_flag_invalid, status);
            return float64_default_nan;
            return float64_default_nan(status);
        }
        return packFloat64( zSign, 0x7FF, 0 );
    }
@@ -4104,7 +4108,7 @@ float64 float64_div(float64 a, float64 b, float_status *status)
        if ( bSig == 0 ) {
            if ( ( aExp | aSig ) == 0 ) {
                float_raise(float_flag_invalid, status);
                return float64_default_nan;
                return float64_default_nan(status);
            }
            float_raise(float_flag_divbyzero, status);
            return packFloat64( zSign, 0x7FF, 0 );
@@ -4162,7 +4166,7 @@ float64 float64_rem(float64 a, float64 b, float_status *status)
            return propagateFloat64NaN(a, b, status);
        }
        float_raise(float_flag_invalid, status);
        return float64_default_nan;
        return float64_default_nan(status);
    }
    if ( bExp == 0x7FF ) {
        if (bSig) {
@@ -4173,7 +4177,7 @@ float64 float64_rem(float64 a, float64 b, float_status *status)
    if ( bExp == 0 ) {
        if ( bSig == 0 ) {
            float_raise(float_flag_invalid, status);
            return float64_default_nan;
            return float64_default_nan(status);
        }
        normalizeFloat64Subnormal( bSig, &bExp, &bSig );
    }
@@ -4275,7 +4279,7 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags,

    if (infzero) {
        float_raise(float_flag_invalid, status);
        return float64_default_nan;
        return float64_default_nan(status);
    }

    if (flags & float_muladd_negate_c) {
@@ -4296,7 +4300,7 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags,
        if (pInf && (pSign ^ cSign)) {
            /* addition of opposite-signed infinities => InvalidOperation */
            float_raise(float_flag_invalid, status);
            return float64_default_nan;
            return float64_default_nan(status);
        }
        /* Otherwise generate an infinity of the same sign */
        return packFloat64(cSign ^ signflip, 0x7ff, 0);
@@ -4494,12 +4498,12 @@ float64 float64_sqrt(float64 a, float_status *status)
        }
        if ( ! aSign ) return a;
        float_raise(float_flag_invalid, status);
        return float64_default_nan;
        return float64_default_nan(status);
    }
    if ( aSign ) {
        if ( ( aExp | aSig ) == 0 ) return a;
        float_raise(float_flag_invalid, status);
        return float64_default_nan;
        return float64_default_nan(status);
    }
    if ( aExp == 0 ) {
        if ( aSig == 0 ) return float64_zero;
@@ -4547,7 +4551,7 @@ float64 float64_log2(float64 a, float_status *status)
    }
    if ( aSign ) {
        float_raise(float_flag_invalid, status);
        return float64_default_nan;
        return float64_default_nan(status);
    }
    if ( aExp == 0x7FF ) {
        if (aSig) {
@@ -4694,7 +4698,8 @@ int float64_eq_quiet(float64 a, float64 b, float_status *status)
    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
       ) {
        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
        if (float64_is_signaling_nan(a, status)
         || float64_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 0;
@@ -4722,7 +4727,8 @@ int float64_le_quiet(float64 a, float64 b, float_status *status)
    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
       ) {
        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
        if (float64_is_signaling_nan(a, status)
         || float64_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 0;
@@ -4753,7 +4759,8 @@ int float64_lt_quiet(float64 a, float64 b, float_status *status)
    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
       ) {
        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
        if (float64_is_signaling_nan(a, status)
         || float64_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 0;
@@ -4782,7 +4789,8 @@ int float64_unordered_quiet(float64 a, float64 b, float_status *status)
    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
       ) {
        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
        if (float64_is_signaling_nan(a, status)
         || float64_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 1;
@@ -5207,7 +5215,6 @@ static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, flag zSign,
    int32_t aExp, bExp, zExp;
    uint64_t aSig, bSig, zSig0, zSig1;
    int32_t expDiff;
    floatx80 z;

    aSig = extractFloatx80Frac( a );
    aExp = extractFloatx80Exp( a );
@@ -5221,9 +5228,7 @@ static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, flag zSign,
            return propagateFloatx80NaN(a, b, status);
        }
        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);
    }
    if ( aExp == 0 ) {
        aExp = 1;
@@ -5317,7 +5322,6 @@ floatx80 floatx80_mul(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 );
@@ -5341,9 +5345,7 @@ floatx80 floatx80_mul(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);
        }
        return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
    }
@@ -5377,7 +5379,6 @@ floatx80 floatx80_div(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 );
@@ -5409,9 +5410,7 @@ floatx80 floatx80_div(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, LIT64( 0x8000000000000000 ) );
@@ -5461,7 +5460,6 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
    int32_t aExp, bExp, expDiff;
    uint64_t aSig0, aSig1, bSig;
    uint64_t q, term0, term1, alternateASig0, alternateASig1;
    floatx80 z;

    aSig0 = extractFloatx80Frac( a );
    aExp = extractFloatx80Exp( a );
@@ -5485,9 +5483,7 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
        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 );
    }
@@ -5559,7 +5555,6 @@ floatx80 floatx80_sqrt(floatx80 a, float_status *status)
    int32_t aExp, zExp;
    uint64_t aSig0, aSig1, zSig0, zSig1, doubleZSig0;
    uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
    floatx80 z;

    aSig0 = extractFloatx80Frac( a );
    aExp = extractFloatx80Exp( a );
@@ -5575,9 +5570,7 @@ floatx80 floatx80_sqrt(floatx80 a, float_status *status)
        if ( ( aExp | aSig0 ) == 0 ) return a;
 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);
    }
    if ( aExp == 0 ) {
        if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
@@ -5745,8 +5738,8 @@ int floatx80_eq_quiet(floatx80 a, floatx80 b, float_status *status)
         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
       ) {
        if (    floatx80_is_signaling_nan( a )
             || floatx80_is_signaling_nan( b ) ) {
        if (floatx80_is_signaling_nan(a, status)
         || floatx80_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 0;
@@ -5776,8 +5769,8 @@ int floatx80_le_quiet(floatx80 a, floatx80 b, float_status *status)
         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
       ) {
        if (    floatx80_is_signaling_nan( a )
             || floatx80_is_signaling_nan( b ) ) {
        if (floatx80_is_signaling_nan(a, status)
         || floatx80_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 0;
@@ -5812,8 +5805,8 @@ int floatx80_lt_quiet(floatx80 a, floatx80 b, float_status *status)
         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
       ) {
        if (    floatx80_is_signaling_nan( a )
             || floatx80_is_signaling_nan( b ) ) {
        if (floatx80_is_signaling_nan(a, status)
         || floatx80_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 0;
@@ -5845,8 +5838,8 @@ int floatx80_unordered_quiet(floatx80 a, floatx80 b, float_status *status)
         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
       ) {
        if (    floatx80_is_signaling_nan( a )
             || floatx80_is_signaling_nan( b ) ) {
        if (floatx80_is_signaling_nan(a, status)
         || floatx80_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 1;
@@ -6385,7 +6378,6 @@ static float128 subFloat128Sigs(float128 a, float128 b, flag zSign,
    int32_t aExp, bExp, zExp;
    uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
    int32_t expDiff;
    float128 z;

    aSig1 = extractFloat128Frac1( a );
    aSig0 = extractFloat128Frac0( a );
@@ -6403,9 +6395,7 @@ static float128 subFloat128Sigs(float128 a, float128 b, flag zSign,
            return propagateFloat128NaN(a, b, status);
        }
        float_raise(float_flag_invalid, status);
        z.low = float128_default_nan_low;
        z.high = float128_default_nan_high;
        return z;
        return float128_default_nan(status);
    }
    if ( aExp == 0 ) {
        aExp = 1;
@@ -6515,7 +6505,6 @@ float128 float128_mul(float128 a, float128 b, float_status *status)
    flag aSign, bSign, zSign;
    int32_t aExp, bExp, zExp;
    uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
    float128 z;

    aSig1 = extractFloat128Frac1( a );
    aSig0 = extractFloat128Frac0( a );
@@ -6541,9 +6530,7 @@ float128 float128_mul(float128 a, float128 b, float_status *status)
        if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
 invalid:
            float_raise(float_flag_invalid, status);
            z.low = float128_default_nan_low;
            z.high = float128_default_nan_high;
            return z;
            return float128_default_nan(status);
        }
        return packFloat128( zSign, 0x7FFF, 0, 0 );
    }
@@ -6582,7 +6569,6 @@ float128 float128_div(float128 a, float128 b, float_status *status)
    int32_t aExp, bExp, zExp;
    uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
    uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
    float128 z;

    aSig1 = extractFloat128Frac1( a );
    aSig0 = extractFloat128Frac0( a );
@@ -6616,9 +6602,7 @@ float128 float128_div(float128 a, float128 b, float_status *status)
            if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
 invalid:
                float_raise(float_flag_invalid, status);
                z.low = float128_default_nan_low;
                z.high = float128_default_nan_high;
                return z;
                return float128_default_nan(status);
            }
            float_raise(float_flag_divbyzero, status);
            return packFloat128( zSign, 0x7FFF, 0, 0 );
@@ -6673,7 +6657,6 @@ float128 float128_rem(float128 a, float128 b, float_status *status)
    uint64_t aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2;
    uint64_t allZero, alternateASig0, alternateASig1, sigMean1;
    int64_t sigMean0;
    float128 z;

    aSig1 = extractFloat128Frac1( a );
    aSig0 = extractFloat128Frac0( a );
@@ -6699,9 +6682,7 @@ float128 float128_rem(float128 a, float128 b, float_status *status)
        if ( ( bSig0 | bSig1 ) == 0 ) {
 invalid:
            float_raise(float_flag_invalid, status);
            z.low = float128_default_nan_low;
            z.high = float128_default_nan_high;
            return z;
            return float128_default_nan(status);
        }
        normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
    }
@@ -6782,7 +6763,6 @@ float128 float128_sqrt(float128 a, float_status *status)
    int32_t aExp, zExp;
    uint64_t aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0;
    uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
    float128 z;

    aSig1 = extractFloat128Frac1( a );
    aSig0 = extractFloat128Frac0( a );
@@ -6799,9 +6779,7 @@ float128 float128_sqrt(float128 a, float_status *status)
        if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a;
 invalid:
        float_raise(float_flag_invalid, status);
        z.low = float128_default_nan_low;
        z.high = float128_default_nan_high;
        return z;
        return float128_default_nan(status);
    }
    if ( aExp == 0 ) {
        if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 );
@@ -6969,8 +6947,8 @@ int float128_eq_quiet(float128 a, float128 b, float_status *status)
         || (    ( extractFloat128Exp( b ) == 0x7FFF )
              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
       ) {
        if (    float128_is_signaling_nan( a )
             || float128_is_signaling_nan( b ) ) {
        if (float128_is_signaling_nan(a, status)
         || float128_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 0;
@@ -7000,8 +6978,8 @@ int float128_le_quiet(float128 a, float128 b, float_status *status)
         || (    ( extractFloat128Exp( b ) == 0x7FFF )
              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
       ) {
        if (    float128_is_signaling_nan( a )
             || float128_is_signaling_nan( b ) ) {
        if (float128_is_signaling_nan(a, status)
         || float128_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 0;
@@ -7036,8 +7014,8 @@ int float128_lt_quiet(float128 a, float128 b, float_status *status)
         || (    ( extractFloat128Exp( b ) == 0x7FFF )
              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
       ) {
        if (    float128_is_signaling_nan( a )
             || float128_is_signaling_nan( b ) ) {
        if (float128_is_signaling_nan(a, status)
         || float128_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 0;
@@ -7070,8 +7048,8 @@ int float128_unordered_quiet(float128 a, float128 b, float_status *status)
         || (    ( extractFloat128Exp( b ) == 0x7FFF )
              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
       ) {
        if (    float128_is_signaling_nan( a )
             || float128_is_signaling_nan( b ) ) {
        if (float128_is_signaling_nan(a, status)
         || float128_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return 1;
@@ -7351,8 +7329,8 @@ static inline int float ## s ## _compare_internal(float ## s a, float ## s b,\
        ( ( extractFloat ## s ## Exp( b ) == nan_exp ) &&                    \
          extractFloat ## s ## Frac( b ) )) {                                \
        if (!is_quiet ||                                                     \
            float ## s ## _is_signaling_nan( a ) ||                          \
            float ## s ## _is_signaling_nan( b ) ) {                         \
            float ## s ## _is_signaling_nan(a, status) ||                  \
            float ## s ## _is_signaling_nan(b, status)) {                 \
            float_raise(float_flag_invalid, status);                         \
        }                                                                    \
        return float_relation_unordered;                                     \
@@ -7401,8 +7379,8 @@ static inline int floatx80_compare_internal(floatx80 a, floatx80 b,
        ( ( extractFloatx80Exp( b ) == 0x7fff ) &&
          ( extractFloatx80Frac( b )<<1 ) )) {
        if (!is_quiet ||
            floatx80_is_signaling_nan( a ) ||
            floatx80_is_signaling_nan( b ) ) {
            floatx80_is_signaling_nan(a, status) ||
            floatx80_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return float_relation_unordered;
@@ -7447,8 +7425,8 @@ static inline int float128_compare_internal(float128 a, float128 b,
        ( ( extractFloat128Exp( b ) == 0x7fff ) &&
          ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )) {
        if (!is_quiet ||
            float128_is_signaling_nan( a ) ||
            float128_is_signaling_nan( b ) ) {
            float128_is_signaling_nan(a, status) ||
            float128_is_signaling_nan(b, status)) {
            float_raise(float_flag_invalid, status);
        }
        return float_relation_unordered;
@@ -7508,10 +7486,10 @@ static inline float ## s float ## s ## _minmax(float ## s a, float ## s b, \
    if (float ## s ## _is_any_nan(a) ||                                 \
        float ## s ## _is_any_nan(b)) {                                 \
        if (isieee) {                                                   \
            if (float ## s ## _is_quiet_nan(a) &&                       \
            if (float ## s ## _is_quiet_nan(a, status) &&               \
                !float ## s ##_is_any_nan(b)) {                         \
                return b;                                               \
            } else if (float ## s ## _is_quiet_nan(b) &&                \
            } else if (float ## s ## _is_quiet_nan(b, status) &&        \
                       !float ## s ## _is_any_nan(a)) {                \
                return a;                                               \
            }                                                           \
+2 −0
Original line number Diff line number Diff line
@@ -53,6 +53,8 @@ typedef int64_t Elf64_Sxword;
#define EF_MIPS_OPTIONS_FIRST	0x00000080
#define EF_MIPS_32BITMODE	0x00000100
#define EF_MIPS_ABI		0x0000f000
#define EF_MIPS_FP64      0x00000200
#define EF_MIPS_NAN2008   0x00000400
#define EF_MIPS_ARCH      0xf0000000

/* These constants define the different elf file types */
+25 −20
Original line number Diff line number Diff line
@@ -205,6 +205,7 @@ typedef struct float_status {
    /* should denormalised inputs go to zero and set the input_denormal flag? */
    flag flush_inputs_to_zero;
    flag default_nan_mode;
    flag snan_bit_is_one;
} float_status;

static inline void set_float_detect_tininess(int val, float_status *status)
@@ -236,6 +237,10 @@ static inline void set_default_nan_mode(flag val, float_status *status)
{
    status->default_nan_mode = val;
}
static inline void set_snan_bit_is_one(flag val, float_status *status)
{
    status->snan_bit_is_one = val;
}
static inline int get_float_detect_tininess(float_status *status)
{
    return status->float_detect_tininess;
@@ -342,9 +347,9 @@ float64 float16_to_float64(float16 a, flag ieee, float_status *status);
/*----------------------------------------------------------------------------
| Software half-precision operations.
*----------------------------------------------------------------------------*/
int float16_is_quiet_nan( float16 );
int float16_is_signaling_nan( float16 );
float16 float16_maybe_silence_nan( float16 );
int float16_is_quiet_nan(float16, float_status *status);
int float16_is_signaling_nan(float16, float_status *status);
float16 float16_maybe_silence_nan(float16, float_status *status);

static inline int float16_is_any_nan(float16 a)
{
@@ -354,7 +359,7 @@ static inline int float16_is_any_nan(float16 a)
/*----------------------------------------------------------------------------
| The pattern for a default generated half-precision NaN.
*----------------------------------------------------------------------------*/
extern const float16 float16_default_nan;
float16 float16_default_nan(float_status *status);

/*----------------------------------------------------------------------------
| Software IEC/IEEE single-precision conversion routines.
@@ -404,9 +409,9 @@ float32 float32_minnum(float32, float32, float_status *status);
float32 float32_maxnum(float32, float32, float_status *status);
float32 float32_minnummag(float32, float32, float_status *status);
float32 float32_maxnummag(float32, float32, float_status *status);
int float32_is_quiet_nan( float32 );
int float32_is_signaling_nan( float32 );
float32 float32_maybe_silence_nan( float32 );
int float32_is_quiet_nan(float32, float_status *status);
int float32_is_signaling_nan(float32, float_status *status);
float32 float32_maybe_silence_nan(float32, float_status *status);
float32 float32_scalbn(float32, int, float_status *status);

static inline float32 float32_abs(float32 a)
@@ -466,7 +471,7 @@ static inline float32 float32_set_sign(float32 a, int sign)
/*----------------------------------------------------------------------------
| The pattern for a default generated single-precision NaN.
*----------------------------------------------------------------------------*/
extern const float32 float32_default_nan;
float32 float32_default_nan(float_status *status);

/*----------------------------------------------------------------------------
| Software IEC/IEEE double-precision conversion routines.
@@ -516,9 +521,9 @@ float64 float64_minnum(float64, float64, float_status *status);
float64 float64_maxnum(float64, float64, float_status *status);
float64 float64_minnummag(float64, float64, float_status *status);
float64 float64_maxnummag(float64, float64, float_status *status);
int float64_is_quiet_nan( float64 a );
int float64_is_signaling_nan( float64 );
float64 float64_maybe_silence_nan( float64 );
int float64_is_quiet_nan(float64 a, float_status *status);
int float64_is_signaling_nan(float64, float_status *status);
float64 float64_maybe_silence_nan(float64, float_status *status);
float64 float64_scalbn(float64, int, float_status *status);

static inline float64 float64_abs(float64 a)
@@ -578,7 +583,7 @@ static inline float64 float64_set_sign(float64 a, int sign)
/*----------------------------------------------------------------------------
| The pattern for a default generated double-precision NaN.
*----------------------------------------------------------------------------*/
extern const float64 float64_default_nan;
float64 float64_default_nan(float_status *status);

/*----------------------------------------------------------------------------
| Software IEC/IEEE extended double-precision conversion routines.
@@ -611,9 +616,9 @@ int floatx80_lt_quiet(floatx80, floatx80, float_status *status);
int floatx80_unordered_quiet(floatx80, floatx80, float_status *status);
int floatx80_compare(floatx80, floatx80, float_status *status);
int floatx80_compare_quiet(floatx80, floatx80, float_status *status);
int floatx80_is_quiet_nan( floatx80 );
int floatx80_is_signaling_nan( floatx80 );
floatx80 floatx80_maybe_silence_nan( floatx80 );
int floatx80_is_quiet_nan(floatx80, float_status *status);
int floatx80_is_signaling_nan(floatx80, float_status *status);
floatx80 floatx80_maybe_silence_nan(floatx80, float_status *status);
floatx80 floatx80_scalbn(floatx80, int, float_status *status);

static inline floatx80 floatx80_abs(floatx80 a)
@@ -663,7 +668,7 @@ static inline int floatx80_is_any_nan(floatx80 a)
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
extern const floatx80 floatx80_default_nan;
floatx80 floatx80_default_nan(float_status *status);

/*----------------------------------------------------------------------------
| Software IEC/IEEE quadruple-precision conversion routines.
@@ -696,9 +701,9 @@ int float128_lt_quiet(float128, float128, float_status *status);
int float128_unordered_quiet(float128, float128, float_status *status);
int float128_compare(float128, float128, float_status *status);
int float128_compare_quiet(float128, float128, float_status *status);
int float128_is_quiet_nan( float128 );
int float128_is_signaling_nan( float128 );
float128 float128_maybe_silence_nan( float128 );
int float128_is_quiet_nan(float128, float_status *status);
int float128_is_signaling_nan(float128, float_status *status);
float128 float128_maybe_silence_nan(float128, float_status *status);
float128 float128_scalbn(float128, int, float_status *status);

static inline float128 float128_abs(float128 a)
@@ -744,6 +749,6 @@ static inline int float128_is_any_nan(float128 a)
/*----------------------------------------------------------------------------
| The pattern for a default generated quadruple-precision NaN.
*----------------------------------------------------------------------------*/
extern const float128 float128_default_nan;
float128 float128_default_nan(float_status *status);

#endif /* !SOFTFLOAT_H */
+14 −0
Original line number Diff line number Diff line
@@ -4687,6 +4687,20 @@ int main(int argc, char **argv, char **envp)
        if (regs->cp0_epc & 1) {
            env->hflags |= MIPS_HFLAG_M16;
        }
        if (((info->elf_flags & EF_MIPS_NAN2008) != 0) !=
            ((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) {
            if ((env->active_fpu.fcr31_rw_bitmask &
                  (1 << FCR31_NAN2008)) == 0) {
                fprintf(stderr, "ELF binary's NaN mode not supported by CPU\n");
                exit(1);
            }
            if ((info->elf_flags & EF_MIPS_NAN2008) != 0) {
                env->active_fpu.fcr31 |= (1 << FCR31_NAN2008);
            } else {
                env->active_fpu.fcr31 &= ~(1 << FCR31_NAN2008);
            }
            restore_snan_bit_mode(env);
        }
    }
#elif defined(TARGET_OPENRISC)
    {
Loading