From 54da0e1be7a9c90b4225ac29cf5b5c8b4ec8304c Mon Sep 17 00:00:00 2001 From: Nicolas Brunie Date: Sat, 12 Aug 2023 10:34:58 +0200 Subject: Fixing dummy bf16_to_f32 conversion --- source/RISCV/specialize.h | 8 ++++++++ source/bf16_to_f32.c | 42 +++++++++++++++++++++++++++++++++++++++++- source/include/internals.h | 3 ++- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/source/RISCV/specialize.h b/source/RISCV/specialize.h index ec9eda2..cb95900 100644 --- a/source/RISCV/specialize.h +++ b/source/RISCV/specialize.h @@ -103,6 +103,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. *----------------------------------------------------------------------------*/ diff --git a/source/bf16_to_f32.c b/source/bf16_to_f32.c index 175d0d4..a30006a 100644 --- a/source/bf16_to_f32.c +++ b/source/bf16_to_f32.c @@ -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; } + + diff --git a/source/include/internals.h b/source/include/internals.h index ea14a7d..5e6d4bd 100644 --- a/source/include/internals.h +++ b/source/include/internals.h @@ -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 ); /*---------------------------------------------------------------------------- *----------------------------------------------------------------------------*/ -- cgit v1.1