From 9ee6e8bb853bdea7ef6c645a1a07aa55fd206aba Mon Sep 17 00:00:00 2001 From: pbrook Date: Sun, 11 Nov 2007 00:04:49 +0000 Subject: ARMv7 support. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3572 c046a42c-6fe2-441c-8c8c-71466251a162 --- fpu/softfloat-native.h | 16 +++++++++++ fpu/softfloat.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ fpu/softfloat.h | 4 +++ 3 files changed, 95 insertions(+) (limited to 'fpu') diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h index 2977717..53bf681 100644 --- a/fpu/softfloat-native.h +++ b/fpu/softfloat-native.h @@ -224,6 +224,11 @@ INLINE float32 float32_chs(float32 a) return -a; } +INLINE float32 float32_scalbn(float32 a, int n) +{ + return scalbnf(a, n); +} + /*---------------------------------------------------------------------------- | Software IEC/IEEE double-precision conversion routines. *----------------------------------------------------------------------------*/ @@ -311,6 +316,11 @@ INLINE float64 float64_chs(float64 a) return -a; } +INLINE float64 float64_scalbn(float64 a, int n) +{ + return scalbn(a, n); +} + #ifdef FLOATX80 /*---------------------------------------------------------------------------- @@ -391,4 +401,10 @@ INLINE floatx80 floatx80_chs(floatx80 a) { return -a; } + +INLINE floatx80 floatx80_scalbn(floatx80 a, int n) +{ + return scalbnl(a, n); +} + #endif diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 6db6cf1..8ebb692 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -5377,3 +5377,78 @@ int float ## s ## _compare_quiet( float ## s a, float ## s b STATUS_PARAM ) \ COMPARE(32, 0xff) COMPARE(64, 0x7ff) + +/* Multiply A by 2 raised to the power N. */ +float32 float32_scalbn( float32 a, int n STATUS_PARAM ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + + if ( aExp == 0xFF ) { + return a; + } + aExp += n; + return roundAndPackFloat32( aSign, aExp, aSig STATUS_VAR ); +} + +float64 float64_scalbn( float64 a, int n STATUS_PARAM ) +{ + flag aSign; + int16 aExp; + bits64 aSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + + if ( aExp == 0x7FF ) { + return a; + } + aExp += n; + return roundAndPackFloat64( aSign, aExp, aSig STATUS_VAR ); +} + +#ifdef FLOATX80 +floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM ) +{ + flag aSign; + int16 aExp; + bits64 aSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + + if ( aExp == 0x7FF ) { + return a; + } + aExp += n; + return roundAndPackFloatx80( STATUS(floatx80_rounding_precision), + aSign, aExp, aSig, 0 STATUS_VAR ); +} +#endif + +#ifdef FLOAT128 +float128 float128_scalbn( float128 a, int n STATUS_PARAM ) +{ + flag aSign; + int32 aExp; + bits64 aSig0, aSig1; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + return a; + } + aExp += n; + return roundAndPackFloat128( aSign, aExp, aSig0, aSig1, 0 STATUS_VAR ); + +} +#endif diff --git a/fpu/softfloat.h b/fpu/softfloat.h index f344d2e..f0261fb 100644 --- a/fpu/softfloat.h +++ b/fpu/softfloat.h @@ -244,6 +244,7 @@ int float32_compare( float32, float32 STATUS_PARAM ); int float32_compare_quiet( float32, float32 STATUS_PARAM ); int float32_is_nan( float32 ); int float32_is_signaling_nan( float32 ); +float32 float32_scalbn( float32, int STATUS_PARAM ); INLINE float32 float32_abs(float32 a) { @@ -295,6 +296,7 @@ int float64_compare( float64, float64 STATUS_PARAM ); int float64_compare_quiet( float64, float64 STATUS_PARAM ); int float64_is_nan( float64 a ); int float64_is_signaling_nan( float64 ); +float64 float64_scalbn( float64, int STATUS_PARAM ); INLINE float64 float64_abs(float64 a) { @@ -339,6 +341,7 @@ int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM ); int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM ); int floatx80_is_nan( floatx80 ); int floatx80_is_signaling_nan( floatx80 ); +floatx80 floatx80_scalbn( floatx80, int STATUS_PARAM ); INLINE floatx80 floatx80_abs(floatx80 a) { @@ -387,6 +390,7 @@ int float128_le_quiet( float128, float128 STATUS_PARAM ); int float128_lt_quiet( float128, float128 STATUS_PARAM ); int float128_is_nan( float128 ); int float128_is_signaling_nan( float128 ); +float128 float128_scalbn( float128, int STATUS_PARAM ); INLINE float128 float128_abs(float128 a) { -- cgit v1.1