Fixing dummy bf16_to_f32 conversion

This commit is contained in:
Nicolas Brunie 2023-08-12 10:34:58 +02:00
parent fab20258f0
commit 54da0e1be7
3 changed files with 51 additions and 2 deletions

View File

@ -102,6 +102,14 @@ struct commonNaN { char _unused; };
*----------------------------------------------------------------------------*/
#define softfloat_f16UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x0200) ) softfloat_raiseFlags( softfloat_flag_invalid )
/*----------------------------------------------------------------------------
| Assuming 'uiA' has the bit pattern of a 16-bit BF16 floating-point NaN, converts
| this NaN to the common NaN form, and stores the resulting common NaN at the
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/
#define softfloat_bf16UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x0040) ) softfloat_raiseFlags( softfloat_flag_invalid )
/*----------------------------------------------------------------------------
| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point
| NaN, and returns the bit pattern of this value as an unsigned integer.

View File

@ -44,13 +44,53 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
float32_t bf16_to_f32( bfloat16_t a )
{
union ui16_bf16 uA;
uint_fast16_t uiA;
bool sign;
int_fast16_t exp;
uint_fast16_t frac;
struct commonNaN commonNaN;
uint_fast32_t uiZ;
struct exp8_sig16 normExpSig;
union ui32_f32 uZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uA.f = a;
uZ.ui = (uint32_t) uA.ui << 16;
uiA = uA.ui;
sign = signBF16UI( uiA );
exp = expBF16UI( uiA );
frac = fracBF16UI( uiA );
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
// NaN or Inf
if ( exp == 0xFF ) {
if ( frac ) {
softfloat_bf16UIToCommonNaN( uiA, &commonNaN );
uiZ = softfloat_commonNaNToF32UI( &commonNaN );
} else {
uiZ = packToF32UI( sign, 0xFF, 0 );
}
goto uiZ;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if ( ! exp ) {
if ( ! frac ) {
uiZ = packToF32UI( sign, 0, 0 );
goto uiZ;
}
normExpSig = softfloat_normSubnormalBF16Sig( frac );
exp = normExpSig.exp - 1;
frac = normExpSig.sig;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
uiZ = packToF32UI( sign, exp, (uint_fast32_t) frac<<16 );
uiZ:
uZ.ui = uiZ;
return uZ.f;
}

View File

@ -103,13 +103,14 @@ float16_t
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
#define signBF16UI( a ) ((bool) ((uint16_t) (a)>>15))
#define expBF16UI( a ) ((int_fast8_t) ((a)>>7) & 0xFF)
#define expBF16UI( a ) ((int_fast16_t) ((a)>>7) & 0xFF)
#define fracBF16UI( a ) ((a) & 0x07F)
#define packToBF16UI( sign, exp, sig ) (((uint16_t) (sign)<<15) + ((uint16_t) (exp)<<7) + (sig))
#define isNaNBF16UI( a ) (((~(a) & 0x7FC0) == 0) && ((a) & 0x07F))
bfloat16_t softfloat_roundPackToBF16( bool, int_fast16_t, uint_fast16_t );
struct exp8_sig16 softfloat_normSubnormalBF16Sig( uint_fast16_t );
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/