[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 10/11] softfloat: add floatx80_log2() function
From: |
Aurelien Jarno |
Subject: |
[Qemu-devel] [PATCH 10/11] softfloat: add floatx80_log2() function |
Date: |
Sun, 15 May 2011 16:13:20 +0200 |
Based on the same algorithm as float32_log2() and float64_log2().
Signed-off-by: Aurelien Jarno <address@hidden>
---
fpu/softfloat.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
fpu/softfloat.h | 1 +
2 files changed, 59 insertions(+), 0 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index b11e6dd..87e3645 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -4543,6 +4543,64 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
}
/*----------------------------------------------------------------------------
+| Returns the binary log of the extended-precision floating-point value `a'.
+| The operation is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+floatx80 floatx80_log2( floatx80 a STATUS_PARAM )
+{
+ flag aSign, zSign;
+ int32_t aExp;
+ uint64_t aSig0, aSig1, zSig0, zSig1, i;
+ floatx80 z;
+
+ aSig0 = 0;
+ aSig1 = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+
+ if ( aExp == 0 ) {
+ if ( (aSig1 << 1) == 0 ) {
+ return packFloatx80( 1, 0x7FFF, 0 );
+ }
+ normalizeFloatx80Subnormal( aSig1, &aExp, &aSig1 );
+ }
+ if ( aSign ) {
+ float_raise( float_flag_invalid STATUS_VAR);
+ z.low = floatx80_default_nan_low;
+ z.high = floatx80_default_nan_high;
+ return z;
+ }
+ if ( aExp == 0x7FFF ) {
+ if ( aSig1 ) {
+ return propagateFloatx80NaN( a, a STATUS_VAR );
+ }
+ return a;
+ }
+
+ aExp -= 0x3FFF;
+ zSign = aExp < 0;
+ zSig0 = (int64_t)aExp >> 1;
+ zSig1 = (int64_t)aExp << 63;
+ for (i = 1LL << 62; i > 0; i >>= 1) {
+ mul64To128( aSig1, aSig1, &aSig0, &aSig1 );
+ if ( aSig0 & LIT64 ( 0x8000000000000000 ) ) {
+ aSig1 = aSig0;
+ zSig1 |= i;
+ } else {
+ aSig1 = (aSig0 << 1) | (aSig1 >> 63);
+ }
+ }
+
+ if ( zSign ) {
+ zSig1 = -zSig1;
+ zSig0 = ~zSig0 + (zSig1 ? 0 : 1);
+ }
+ return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision),
+ zSign, 0x403f, zSig0, zSig1
STATUS_VAR );
+}
+
+/*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is equal
| to the corresponding value `b', and 0 otherwise. The invalid exception is
| raised if either operand is a NaN. Otherwise, the comparison is performed
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 8fa4af6..03ce60d 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -500,6 +500,7 @@ floatx80 floatx80_mul( floatx80, floatx80 STATUS_PARAM );
floatx80 floatx80_div( floatx80, floatx80 STATUS_PARAM );
floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
+floatx80 floatx80_log2( floatx80 STATUS_PARAM );
int floatx80_eq( floatx80, floatx80 STATUS_PARAM );
int floatx80_le( floatx80, floatx80 STATUS_PARAM );
int floatx80_lt( floatx80, floatx80 STATUS_PARAM );
--
1.7.2.3
- Re: [Qemu-devel] [PATCH 04/11] softfloat: always enable floatx80 and float128 support, (continued)
- [Qemu-devel] [PATCH 02/11] target-mips/gdbstub: remove old CONFIG_SOFTFLOAT #ifdef, Aurelien Jarno, 2011/05/15
- [Qemu-devel] [PATCH 10/11] softfloat: add floatx80_log2() function,
Aurelien Jarno <=
- [Qemu-devel] [PATCH 05/11] target-i386: remove old code handling float64, Aurelien Jarno, 2011/05/15
- [Qemu-devel] [PATCH 09/11] target-i386: add support for FPU exceptions, Aurelien Jarno, 2011/05/15
- [Qemu-devel] [PATCH 03/11] softfloat-native: remove, Aurelien Jarno, 2011/05/15