summaryrefslogtreecommitdiffstats
path: root/lib/libc/softfloat/bits64
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2012-01-20 06:16:14 +0000
committerdas <das@FreeBSD.org>2012-01-20 06:16:14 +0000
commit6003be2b93b55b2c4ddc36327b2368bfbf1cd580 (patch)
treeca7e1949c416c8eaa7e890e6031477d283c8ddb9 /lib/libc/softfloat/bits64
parent9386d0d604b43db6adc33e4d48dacd735ccff9fb (diff)
downloadFreeBSD-src-6003be2b93b55b2c4ddc36327b2368bfbf1cd580.zip
FreeBSD-src-6003be2b93b55b2c4ddc36327b2368bfbf1cd580.tar.gz
Merge in the latest SoftFloat changes from NetBSD. (NetBSD isn't the
original vendor, but we're using their heavily modified version.) This brings in functions for long double emulation (both extended and quad formats), which may be useful for testing, and also for replacing libc/sparc64/fpu/.
Diffstat (limited to 'lib/libc/softfloat/bits64')
-rw-r--r--lib/libc/softfloat/bits64/softfloat-macros6
-rw-r--r--lib/libc/softfloat/bits64/softfloat.c99
2 files changed, 100 insertions, 5 deletions
diff --git a/lib/libc/softfloat/bits64/softfloat-macros b/lib/libc/softfloat/bits64/softfloat-macros
index 9b478e8..f4647de 100644
--- a/lib/libc/softfloat/bits64/softfloat-macros
+++ b/lib/libc/softfloat/bits64/softfloat-macros
@@ -1,4 +1,4 @@
-/* $NetBSD: softfloat-macros,v 1.1 2002/05/21 23:51:08 bjh21 Exp $ */
+/* $NetBSD: softfloat-macros,v 1.2 2009/02/16 10:23:35 tron Exp $ */
/* $FreeBSD$ */
/*
@@ -387,7 +387,7 @@ INLINE void
carry0 = ( z1 < a1 );
z0 = a0 + b0;
z1 += carry1;
- z0 += ( z1 < carry1 );
+ z0 += ( z1 < (bits64)carry1 );
z0 += carry0;
*z2Ptr = z2;
*z1Ptr = z1;
@@ -444,7 +444,7 @@ INLINE void
z1 = a1 - b1;
borrow0 = ( a1 < b1 );
z0 = a0 - b0;
- z0 -= ( z1 < borrow1 );
+ z0 -= ( z1 < (bits64)borrow1 );
z1 -= borrow1;
z0 -= borrow0;
*z2Ptr = z2;
diff --git a/lib/libc/softfloat/bits64/softfloat.c b/lib/libc/softfloat/bits64/softfloat.c
index 3d614f2..1065876 100644
--- a/lib/libc/softfloat/bits64/softfloat.c
+++ b/lib/libc/softfloat/bits64/softfloat.c
@@ -1,4 +1,4 @@
-/* $NetBSD: softfloat.c,v 1.2 2003/07/26 19:24:52 salo Exp $ */
+/* $NetBSD: softfloat.c,v 1.8 2011/07/10 04:52:23 matt Exp $ */
/*
* This version hacked for use with gcc -msoft-float by bjh21.
@@ -1126,6 +1126,15 @@ float32 int32_to_float32( int32 a )
}
+float32 uint32_to_float32( uint32 a )
+{
+ if ( a == 0 ) return 0;
+ if ( a & (bits32) 0x80000000 )
+ return normalizeRoundAndPackFloat32( 0, 0x9D, a >> 1 );
+ return normalizeRoundAndPackFloat32( 0, 0x9C, a );
+}
+
+
/*
-------------------------------------------------------------------------------
Returns the result of converting the 32-bit two's complement integer `a'
@@ -1149,6 +1158,17 @@ float64 int32_to_float64( int32 a )
}
+float64 uint32_to_float64( uint32 a )
+{
+ int8 shiftCount;
+ bits64 zSig = a;
+
+ if ( a == 0 ) return 0;
+ shiftCount = countLeadingZeros32( a ) + 21;
+ return packFloat64( 0, 0x432 - shiftCount, zSig<<shiftCount );
+
+}
+
#ifdef FLOATX80
/*
@@ -1175,6 +1195,17 @@ floatx80 int32_to_floatx80( int32 a )
}
+floatx80 uint32_to_floatx80( uint32 a )
+{
+ int8 shiftCount;
+ bits64 zSig = a;
+
+ if ( a == 0 ) return packFloatx80( 0, 0, 0 );
+ shiftCount = countLeadingZeros32( a ) + 32;
+ return packFloatx80( 0, 0x403E - shiftCount, zSig<<shiftCount );
+
+}
+
#endif
#ifdef FLOAT128
@@ -1202,6 +1233,17 @@ float128 int32_to_float128( int32 a )
}
+float128 uint32_to_float128( uint32 a )
+{
+ int8 shiftCount;
+ bits64 zSig0 = a;
+
+ if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
+ shiftCount = countLeadingZeros32( a ) + 17;
+ return packFloat128( 0, 0x402E - shiftCount, zSig0<<shiftCount, 0 );
+
+}
+
#endif
#ifndef SOFTFLOAT_FOR_GCC /* __floatdi?f is in libgcc2.c */
@@ -4438,6 +4480,59 @@ int64 float128_to_int64_round_to_zero( float128 a )
}
+#if (defined(SOFTFLOATSPARC64_FOR_GCC) || defined(SOFTFLOAT_FOR_GCC)) \
+ && defined(SOFTFLOAT_NEED_FIXUNS)
+/*
+ * just like above - but do not care for overflow of signed results
+ */
+uint64 float128_to_uint64_round_to_zero( float128 a )
+{
+ flag aSign;
+ int32 aExp, shiftCount;
+ bits64 aSig0, aSig1;
+ uint64 z;
+
+ aSig1 = extractFloat128Frac1( a );
+ aSig0 = extractFloat128Frac0( a );
+ aExp = extractFloat128Exp( a );
+ aSign = extractFloat128Sign( a );
+ if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
+ shiftCount = aExp - 0x402F;
+ if ( 0 < shiftCount ) {
+ if ( 0x403F <= aExp ) {
+ aSig0 &= LIT64( 0x0000FFFFFFFFFFFF );
+ if ( ( a.high == LIT64( 0xC03E000000000000 ) )
+ && ( aSig1 < LIT64( 0x0002000000000000 ) ) ) {
+ if ( aSig1 ) float_exception_flags |= float_flag_inexact;
+ }
+ else {
+ float_raise( float_flag_invalid );
+ }
+ return LIT64( 0xFFFFFFFFFFFFFFFF );
+ }
+ z = ( aSig0<<shiftCount ) | ( aSig1>>( ( - shiftCount ) & 63 ) );
+ if ( (bits64) ( aSig1<<shiftCount ) ) {
+ float_exception_flags |= float_flag_inexact;
+ }
+ }
+ else {
+ if ( aExp < 0x3FFF ) {
+ if ( aExp | aSig0 | aSig1 ) {
+ float_exception_flags |= float_flag_inexact;
+ }
+ return 0;
+ }
+ z = aSig0>>( - shiftCount );
+ if (aSig1 || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) {
+ float_exception_flags |= float_flag_inexact;
+ }
+ }
+ if ( aSign ) z = - z;
+ return z;
+
+}
+#endif /* (SOFTFLOATSPARC64_FOR_GCC || SOFTFLOAT_FOR_GCC) && SOFTFLOAT_NEED_FIXUNS */
+
/*
-------------------------------------------------------------------------------
Returns the result of converting the quadruple-precision floating-point
@@ -5110,7 +5205,7 @@ float128 float128_rem( float128 a, float128 b )
sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
} while ( 0 <= (sbits64) aSig0 );
add128(
- aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 );
+ aSig0, aSig1, alternateASig0, alternateASig1, (bits64 *)&sigMean0, &sigMean1 );
if ( ( sigMean0 < 0 )
|| ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
aSig0 = alternateASig0;
OpenPOWER on IntegriCloud