Example #1
0
/*----------------------------------------------------------------------------
| Converts the common NaN pointed to by `aPtr' into a 128-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer.
*----------------------------------------------------------------------------*/
struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr )
{
    struct uint128 uiZ;

    uiZ = softfloat_shortShiftRight128( aPtr->v64, aPtr->v0, 16 );
    uiZ.v64 |= (uint_fast64_t) aPtr->sign<<63 | UINT64_C( 0x7FFF800000000000 );
    return uiZ;

}
float128_t  f128_scaledResult(int_fast16_t scale)
{
    int_fast32_t exp;
    union ui128_f128 uZ;
    struct exp32_sig128 z;
    struct uint128 uA;

    exp = softfloat_raw.Exp + 16382 + scale;

    /* Note that the high-order bit of the saved significand is the units position.  This is effectively    */
    /* added to the exponent in packToF128UI64 so that the units position disappears and the exponent is    */
    /* incremented.  So going in, the exponent limit must be one less than the float128 maximum of 0x7FFE.  */

    /* Note also that, unlike the C << operator, the function softfloat_shortShiftLeft128 behaves very      */
    /* badly when passed a shift count of zero.  When passed zero, softfloat_shortShiftLeft128 or's the     */
    /* the second half of the 128-bit significand into the first.  Not a bug, really, because this          */
    /* function is not a part of the Softfloat 3a API, but troubling nontheless.  Softfloat 3b did not      */
    /* change this behavior.                                                                                */

    if (exp < 0 || exp > 0x7FFD)
    {
        uZ.ui.v64 = (defaultNaNF128UI64 & ~UINT64_C(0x0000800000000000)) | UINT64_C(0x00000DEAD0000000);
        uZ.ui.v0 = defaultNaNF128UI0;
    }
    else
    {
        uA = softfloat_shortShiftRight128(softfloat_raw.Sig64, softfloat_raw.Sig0, 14);
        if (softfloat_raw.Tiny && (uA.v64 < 0x0001000000000000ULL))          /* result an unnormallized subnormal?  */
        {
            z = softfloat_normSubnormalF128Sig(uA.v64, uA.v0);
            exp += (z.exp - 1);
            uZ.ui.v64 = packToF128UI64(softfloat_raw.Sign, exp, z.sig.v64);  /* should not be needed  */
            uZ.ui.v0 = z.sig.v0;
        }
        else
        {
            uZ.ui.v64 = packToF128UI64(softfloat_raw.Sign, exp, uA.v64); 
            uZ.ui.v0 = uA.v0;
        }
    }

    softfloat_exceptionFlags &= ~(softfloat_flag_inexact | softfloat_flag_incremented | softfloat_flag_tiny);
    softfloat_exceptionFlags |= (softfloat_raw.Inexact ?  softfloat_flag_inexact     : 0) |
                                (softfloat_raw.Incre   ?  softfloat_flag_incremented : 0);

    return uZ.f;

}