mirror of https://gitee.com/openkylin/qemu.git
soft-float: add float32_log2() and float64_log2()
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6518 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
7344da06e8
commit
374dfc33e2
|
@ -2056,6 +2056,53 @@ float32 float32_sqrt( float32 a STATUS_PARAM )
|
|||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the binary log of the single-precision floating-point value `a'.
|
||||
| The operation is performed according to the IEC/IEEE Standard for Binary
|
||||
| Floating-Point Arithmetic.
|
||||
*----------------------------------------------------------------------------*/
|
||||
float32 float32_log2( float32 a STATUS_PARAM )
|
||||
{
|
||||
flag aSign, zSign;
|
||||
int16 aExp;
|
||||
bits32 aSig, zSig, i;
|
||||
|
||||
aSig = extractFloat32Frac( a );
|
||||
aExp = extractFloat32Exp( a );
|
||||
aSign = extractFloat32Sign( a );
|
||||
|
||||
if ( aExp == 0 ) {
|
||||
if ( aSig == 0 ) return packFloat32( 1, 0xFF, 0 );
|
||||
normalizeFloat32Subnormal( aSig, &aExp, &aSig );
|
||||
}
|
||||
if ( aSign ) {
|
||||
float_raise( float_flag_invalid STATUS_VAR);
|
||||
return float32_default_nan;
|
||||
}
|
||||
if ( aExp == 0xFF ) {
|
||||
if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
|
||||
return a;
|
||||
}
|
||||
|
||||
aExp -= 0x7F;
|
||||
aSig |= 0x00800000;
|
||||
zSign = aExp < 0;
|
||||
zSig = aExp << 23;
|
||||
|
||||
for (i = 1 << 22; i > 0; i >>= 1) {
|
||||
aSig = ( (bits64)aSig * aSig ) >> 23;
|
||||
if ( aSig & 0x01000000 ) {
|
||||
aSig >>= 1;
|
||||
zSig |= i;
|
||||
}
|
||||
}
|
||||
|
||||
if ( zSign )
|
||||
zSig = -zSig;
|
||||
|
||||
return normalizeRoundAndPackFloat32( zSign, 0x85, zSig STATUS_VAR );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the single-precision floating-point value `a' is equal to
|
||||
| the corresponding value `b', and 0 otherwise. The comparison is performed
|
||||
|
@ -3005,6 +3052,52 @@ float64 float64_sqrt( float64 a STATUS_PARAM )
|
|||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the binary log of the double-precision floating-point value `a'.
|
||||
| The operation is performed according to the IEC/IEEE Standard for Binary
|
||||
| Floating-Point Arithmetic.
|
||||
*----------------------------------------------------------------------------*/
|
||||
float64 float64_log2( float64 a STATUS_PARAM )
|
||||
{
|
||||
flag aSign, zSign;
|
||||
int16 aExp;
|
||||
bits64 aSig, aSig0, aSig1, zSig, i;
|
||||
|
||||
aSig = extractFloat64Frac( a );
|
||||
aExp = extractFloat64Exp( a );
|
||||
aSign = extractFloat64Sign( a );
|
||||
|
||||
if ( aExp == 0 ) {
|
||||
if ( aSig == 0 ) return packFloat64( 1, 0x7FF, 0 );
|
||||
normalizeFloat64Subnormal( aSig, &aExp, &aSig );
|
||||
}
|
||||
if ( aSign ) {
|
||||
float_raise( float_flag_invalid STATUS_VAR);
|
||||
return float64_default_nan;
|
||||
}
|
||||
if ( aExp == 0x7FF ) {
|
||||
if ( aSig ) return propagateFloat64NaN( a, float64_zero STATUS_VAR );
|
||||
return a;
|
||||
}
|
||||
|
||||
aExp -= 0x3FF;
|
||||
aSig |= LIT64( 0x0010000000000000 );
|
||||
zSign = aExp < 0;
|
||||
zSig = (bits64)aExp << 52;
|
||||
for (i = 1LL << 51; i > 0; i >>= 1) {
|
||||
mul64To128( aSig, aSig, &aSig0, &aSig1 );
|
||||
aSig = ( aSig0 << 12 ) | ( aSig1 >> 52 );
|
||||
if ( aSig & LIT64( 0x0020000000000000 ) ) {
|
||||
aSig >>= 1;
|
||||
zSig |= i;
|
||||
}
|
||||
}
|
||||
|
||||
if ( zSign )
|
||||
zSig = -zSig;
|
||||
return normalizeRoundAndPackFloat64( zSign, 0x408, zSig STATUS_VAR );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the double-precision floating-point value `a' is equal to the
|
||||
| corresponding value `b', and 0 otherwise. The comparison is performed
|
||||
|
|
|
@ -269,6 +269,7 @@ float32 float32_mul( float32, float32 STATUS_PARAM );
|
|||
float32 float32_div( float32, float32 STATUS_PARAM );
|
||||
float32 float32_rem( float32, float32 STATUS_PARAM );
|
||||
float32 float32_sqrt( float32 STATUS_PARAM );
|
||||
float32 float32_log2( float32 STATUS_PARAM );
|
||||
int float32_eq( float32, float32 STATUS_PARAM );
|
||||
int float32_le( float32, float32 STATUS_PARAM );
|
||||
int float32_lt( float32, float32 STATUS_PARAM );
|
||||
|
@ -339,6 +340,7 @@ float64 float64_mul( float64, float64 STATUS_PARAM );
|
|||
float64 float64_div( float64, float64 STATUS_PARAM );
|
||||
float64 float64_rem( float64, float64 STATUS_PARAM );
|
||||
float64 float64_sqrt( float64 STATUS_PARAM );
|
||||
float64 float64_log2( float64 STATUS_PARAM );
|
||||
int float64_eq( float64, float64 STATUS_PARAM );
|
||||
int float64_le( float64, float64 STATUS_PARAM );
|
||||
int float64_lt( float64, float64 STATUS_PARAM );
|
||||
|
|
Loading…
Reference in New Issue