summaryrefslogtreecommitdiff
path: root/fpu
diff options
context:
space:
mode:
Diffstat (limited to 'fpu')
-rw-r--r--fpu/softfloat-native.h16
-rw-r--r--fpu/softfloat.c75
-rw-r--r--fpu/softfloat.h4
3 files changed, 95 insertions, 0 deletions
diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index 29777178b3..53bf68192f 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 6db6cf1321..8ebb692648 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 f344d2ea50..f0261fb6a7 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)
{