aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Brunie <nibrunie@gmail.com>2023-08-12 10:34:58 +0200
committerNicolas Brunie <nibrunie@gmail.com>2023-08-12 10:34:58 +0200
commit54da0e1be7a9c90b4225ac29cf5b5c8b4ec8304c (patch)
tree0e2ee10eb9f8f336f6812dcd4bea3b96f39746c4
parentfab20258f0ba207b30753031a33d84f6c2e7d724 (diff)
downloadberkeley-softfloat-3-54da0e1be7a9c90b4225ac29cf5b5c8b4ec8304c.zip
berkeley-softfloat-3-54da0e1be7a9c90b4225ac29cf5b5c8b4ec8304c.tar.gz
berkeley-softfloat-3-54da0e1be7a9c90b4225ac29cf5b5c8b4ec8304c.tar.bz2
Fixing dummy bf16_to_f32 conversion
-rw-r--r--source/RISCV/specialize.h8
-rw-r--r--source/bf16_to_f32.c42
-rw-r--r--source/include/internals.h3
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 );
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/