~ubuntu-branches/ubuntu/natty/qemu-linaro/natty

« back to all changes in this revision

Viewing changes to fpu/softfloat.c

  • Committer: Package Import Robot
  • Author(s): Steve Langasek, Loïc Minier, Steve Langasek
  • Date: 2011-03-07 22:55:03 UTC
  • Revision ID: package-import@ubuntu.com-20110307225503-3opjapw0ksg7glo6
[ Loïc Minier ]
* Also pass -fno-var-tracking on armhf.

[ Steve Langasek ]
* New upstream release.
* Build with -marm on armel/armhf; Peter Maydell reports that building for
  Thumb-2 gives an emulator that doesn't work.
* Add support for cross-compiling the package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
67
67
#endif
68
68
 
69
69
/*----------------------------------------------------------------------------
 
70
| Returns the fraction bits of the half-precision floating-point value `a'.
 
71
*----------------------------------------------------------------------------*/
 
72
 
 
73
INLINE uint32_t extractFloat16Frac(float16 a)
 
74
{
 
75
    return float16_val(a) & 0x3ff;
 
76
}
 
77
 
 
78
/*----------------------------------------------------------------------------
 
79
| Returns the exponent bits of the half-precision floating-point value `a'.
 
80
*----------------------------------------------------------------------------*/
 
81
 
 
82
INLINE int16 extractFloat16Exp(float16 a)
 
83
{
 
84
    return (float16_val(a) >> 10) & 0x1f;
 
85
}
 
86
 
 
87
/*----------------------------------------------------------------------------
 
88
| Returns the sign bit of the single-precision floating-point value `a'.
 
89
*----------------------------------------------------------------------------*/
 
90
 
 
91
INLINE flag extractFloat16Sign(float16 a)
 
92
{
 
93
    return float16_val(a)>>15;
 
94
}
 
95
 
 
96
/*----------------------------------------------------------------------------
70
97
| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
71
98
| and 7, and returns the properly rounded 32-bit integer corresponding to the
72
99
| input.  If `zSign' is 1, the input is negated before being converted to an
1534
1561
    aExp = extractFloat32Exp( a );
1535
1562
    aSign = extractFloat32Sign( a );
1536
1563
    if ( aExp == 0xFF ) {
1537
 
        if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a STATUS_VAR ));
 
1564
        if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
1538
1565
        return packFloat64( aSign, 0x7FF, 0 );
1539
1566
    }
1540
1567
    if ( aExp == 0 ) {
1566
1593
    aExp = extractFloat32Exp( a );
1567
1594
    aSign = extractFloat32Sign( a );
1568
1595
    if ( aExp == 0xFF ) {
1569
 
        if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a STATUS_VAR ) );
 
1596
        if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
1570
1597
        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
1571
1598
    }
1572
1599
    if ( aExp == 0 ) {
1600
1627
    aExp = extractFloat32Exp( a );
1601
1628
    aSign = extractFloat32Sign( a );
1602
1629
    if ( aExp == 0xFF ) {
1603
 
        if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a STATUS_VAR ) );
 
1630
        if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
1604
1631
        return packFloat128( aSign, 0x7FFF, 0, 0 );
1605
1632
    }
1606
1633
    if ( aExp == 0 ) {
2172
2199
 
2173
2200
static const float64 float32_exp2_coefficients[15] =
2174
2201
{
2175
 
    make_float64( 0x3ff0000000000000ll ), /*  1 */
2176
 
    make_float64( 0x3fe0000000000000ll ), /*  2 */
2177
 
    make_float64( 0x3fc5555555555555ll ), /*  3 */
2178
 
    make_float64( 0x3fa5555555555555ll ), /*  4 */
2179
 
    make_float64( 0x3f81111111111111ll ), /*  5 */
2180
 
    make_float64( 0x3f56c16c16c16c17ll ), /*  6 */
2181
 
    make_float64( 0x3f2a01a01a01a01all ), /*  7 */
2182
 
    make_float64( 0x3efa01a01a01a01all ), /*  8 */
2183
 
    make_float64( 0x3ec71de3a556c734ll ), /*  9 */
2184
 
    make_float64( 0x3e927e4fb7789f5cll ), /* 10 */
2185
 
    make_float64( 0x3e5ae64567f544e4ll ), /* 11 */
2186
 
    make_float64( 0x3e21eed8eff8d898ll ), /* 12 */
2187
 
    make_float64( 0x3de6124613a86d09ll ), /* 13 */
2188
 
    make_float64( 0x3da93974a8c07c9dll ), /* 14 */
2189
 
    make_float64( 0x3d6ae7f3e733b81fll ), /* 15 */
 
2202
    const_float64( 0x3ff0000000000000ll ), /*  1 */
 
2203
    const_float64( 0x3fe0000000000000ll ), /*  2 */
 
2204
    const_float64( 0x3fc5555555555555ll ), /*  3 */
 
2205
    const_float64( 0x3fa5555555555555ll ), /*  4 */
 
2206
    const_float64( 0x3f81111111111111ll ), /*  5 */
 
2207
    const_float64( 0x3f56c16c16c16c17ll ), /*  6 */
 
2208
    const_float64( 0x3f2a01a01a01a01all ), /*  7 */
 
2209
    const_float64( 0x3efa01a01a01a01all ), /*  8 */
 
2210
    const_float64( 0x3ec71de3a556c734ll ), /*  9 */
 
2211
    const_float64( 0x3e927e4fb7789f5cll ), /* 10 */
 
2212
    const_float64( 0x3e5ae64567f544e4ll ), /* 11 */
 
2213
    const_float64( 0x3e21eed8eff8d898ll ), /* 12 */
 
2214
    const_float64( 0x3de6124613a86d09ll ), /* 13 */
 
2215
    const_float64( 0x3da93974a8c07c9dll ), /* 14 */
 
2216
    const_float64( 0x3d6ae7f3e733b81fll ), /* 15 */
2190
2217
};
2191
2218
 
2192
2219
float32 float32_exp2( float32 a STATUS_PARAM )
2689
2716
    aExp = extractFloat64Exp( a );
2690
2717
    aSign = extractFloat64Sign( a );
2691
2718
    if ( aExp == 0x7FF ) {
2692
 
        if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a STATUS_VAR ) );
 
2719
        if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
2693
2720
        return packFloat32( aSign, 0xFF, 0 );
2694
2721
    }
2695
2722
    shift64RightJamming( aSig, 22, &aSig );
2713
2740
| than the desired result exponent whenever `zSig' is a complete, normalized
2714
2741
| significand.
2715
2742
*----------------------------------------------------------------------------*/
2716
 
static bits16 packFloat16(flag zSign, int16 zExp, bits16 zSig)
 
2743
static float16 packFloat16(flag zSign, int16 zExp, bits16 zSig)
2717
2744
{
2718
 
    return (((bits32)zSign) << 15) + (((bits32)zExp) << 10) + zSig;
 
2745
    return make_float16(
 
2746
        (((bits32)zSign) << 15) + (((bits32)zExp) << 10) + zSig);
2719
2747
}
2720
2748
 
2721
2749
/* Half precision floats come in two formats: standard IEEE and "ARM" format.
2722
2750
   The latter gains extra exponent range by omitting the NaN/Inf encodings.  */
2723
 
  
2724
 
float32 float16_to_float32( bits16 a, flag ieee STATUS_PARAM )
 
2751
 
 
2752
float32 float16_to_float32(float16 a, flag ieee STATUS_PARAM)
2725
2753
{
2726
2754
    flag aSign;
2727
2755
    int16 aExp;
2728
2756
    bits32 aSig;
2729
2757
 
2730
 
    aSign = a >> 15;
2731
 
    aExp = (a >> 10) & 0x1f;
2732
 
    aSig = a & 0x3ff;
 
2758
    aSign = extractFloat16Sign(a);
 
2759
    aExp = extractFloat16Exp(a);
 
2760
    aSig = extractFloat16Frac(a);
2733
2761
 
2734
2762
    if (aExp == 0x1f && ieee) {
2735
2763
        if (aSig) {
2736
 
            /* Make sure correct exceptions are raised.  */
2737
 
            float32ToCommonNaN(a STATUS_VAR);
2738
 
            aSig |= 0x200;
 
2764
            return commonNaNToFloat32(float16ToCommonNaN(a STATUS_VAR) STATUS_VAR);
2739
2765
        }
2740
2766
        return packFloat32(aSign, 0xff, aSig << 13);
2741
2767
    }
2753
2779
    return packFloat32( aSign, aExp + 0x70, aSig << 13);
2754
2780
}
2755
2781
 
2756
 
bits16 float32_to_float16( float32 a, flag ieee STATUS_PARAM)
 
2782
float16 float32_to_float16(float32 a, flag ieee STATUS_PARAM)
2757
2783
{
2758
2784
    flag aSign;
2759
2785
    int16 aExp;
2768
2794
    aSign = extractFloat32Sign( a );
2769
2795
    if ( aExp == 0xFF ) {
2770
2796
        if (aSig) {
2771
 
            /* Make sure correct exceptions are raised.  */
2772
 
            float32ToCommonNaN(a STATUS_VAR);
2773
 
            aSig |= 0x00400000;
2774
 
        }
2775
 
        return packFloat16(aSign, 0x1f, aSig >> 13);
 
2797
            /* Input is a NaN */
 
2798
            float16 r = commonNaNToFloat16( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
 
2799
            if (!ieee) {
 
2800
                return packFloat16(aSign, 0, 0);
 
2801
            }
 
2802
            return r;
 
2803
        }
 
2804
        /* Infinity */
 
2805
        if (!ieee) {
 
2806
            float_raise(float_flag_invalid STATUS_VAR);
 
2807
            return packFloat16(aSign, 0x1f, 0x3ff);
 
2808
        }
 
2809
        return packFloat16(aSign, 0x1f, 0);
2776
2810
    }
2777
 
    if (aExp == 0 && aSign == 0) {
 
2811
    if (aExp == 0 && aSig == 0) {
2778
2812
        return packFloat16(aSign, 0, 0);
2779
2813
    }
2780
2814
    /* Decimal point between bits 22 and 23.  */
2781
2815
    aSig |= 0x00800000;
2782
2816
    aExp -= 0x7f;
2783
2817
    if (aExp < -14) {
2784
 
        mask = 0x007fffff;
2785
 
        if (aExp < -24) {
2786
 
            aExp = -25;
2787
 
        } else {
2788
 
            mask >>= 24 + aExp;
 
2818
        mask = 0x00ffffff;
 
2819
        if (aExp >= -24) {
 
2820
            mask >>= 25 + aExp;
2789
2821
        }
2790
2822
    } else {
2791
2823
        mask = 0x00001fff;
2827
2859
        }
2828
2860
    } else {
2829
2861
        if (aExp > 16) {
2830
 
            float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
 
2862
            float_raise(float_flag_invalid | float_flag_inexact STATUS_VAR);
2831
2863
            return packFloat16(aSign, 0x1f, 0x3ff);
2832
2864
        }
2833
2865
    }
2861
2893
    aExp = extractFloat64Exp( a );
2862
2894
    aSign = extractFloat64Sign( a );
2863
2895
    if ( aExp == 0x7FF ) {
2864
 
        if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a STATUS_VAR ) );
 
2896
        if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
2865
2897
        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
2866
2898
    }
2867
2899
    if ( aExp == 0 ) {
2896
2928
    aExp = extractFloat64Exp( a );
2897
2929
    aSign = extractFloat64Sign( a );
2898
2930
    if ( aExp == 0x7FF ) {
2899
 
        if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a STATUS_VAR ) );
 
2931
        if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
2900
2932
        return packFloat128( aSign, 0x7FFF, 0, 0 );
2901
2933
    }
2902
2934
    if ( aExp == 0 ) {
3843
3875
    aSign = extractFloatx80Sign( a );
3844
3876
    if ( aExp == 0x7FFF ) {
3845
3877
        if ( (bits64) ( aSig<<1 ) ) {
3846
 
            return commonNaNToFloat32( floatx80ToCommonNaN( a STATUS_VAR ) );
 
3878
            return commonNaNToFloat32( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
3847
3879
        }
3848
3880
        return packFloat32( aSign, 0xFF, 0 );
3849
3881
    }
3871
3903
    aSign = extractFloatx80Sign( a );
3872
3904
    if ( aExp == 0x7FFF ) {
3873
3905
        if ( (bits64) ( aSig<<1 ) ) {
3874
 
            return commonNaNToFloat64( floatx80ToCommonNaN( a STATUS_VAR ) );
 
3906
            return commonNaNToFloat64( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
3875
3907
        }
3876
3908
        return packFloat64( aSign, 0x7FF, 0 );
3877
3909
    }
3900
3932
    aExp = extractFloatx80Exp( a );
3901
3933
    aSign = extractFloatx80Sign( a );
3902
3934
    if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) {
3903
 
        return commonNaNToFloat128( floatx80ToCommonNaN( a STATUS_VAR ) );
 
3935
        return commonNaNToFloat128( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
3904
3936
    }
3905
3937
    shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 );
3906
3938
    return packFloat128( aSign, aExp, zSig0, zSig1 );
4863
4895
    aSign = extractFloat128Sign( a );
4864
4896
    if ( aExp == 0x7FFF ) {
4865
4897
        if ( aSig0 | aSig1 ) {
4866
 
            return commonNaNToFloat32( float128ToCommonNaN( a STATUS_VAR ) );
 
4898
            return commonNaNToFloat32( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
4867
4899
        }
4868
4900
        return packFloat32( aSign, 0xFF, 0 );
4869
4901
    }
4897
4929
    aSign = extractFloat128Sign( a );
4898
4930
    if ( aExp == 0x7FFF ) {
4899
4931
        if ( aSig0 | aSig1 ) {
4900
 
            return commonNaNToFloat64( float128ToCommonNaN( a STATUS_VAR ) );
 
4932
            return commonNaNToFloat64( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
4901
4933
        }
4902
4934
        return packFloat64( aSign, 0x7FF, 0 );
4903
4935
    }
4932
4964
    aSign = extractFloat128Sign( a );
4933
4965
    if ( aExp == 0x7FFF ) {
4934
4966
        if ( aSig0 | aSig1 ) {
4935
 
            return commonNaNToFloatx80( float128ToCommonNaN( a STATUS_VAR ) );
 
4967
            return commonNaNToFloatx80( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
4936
4968
        }
4937
4969
        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
4938
4970
    }