Skip to content

Commit 6326388

Browse files
committed
Implement F8 multiply
Implements several helper macros as well. Convert to f16, then multiply rounding-to-odd, then convert back to f8 using specified rounding mode.
1 parent 422234b commit 6326388

File tree

8 files changed

+211
-0
lines changed

8 files changed

+211
-0
lines changed

softfloat/f8_mul.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*============================================================================
2+
3+
Created via modification of f16_mul.c
4+
5+
=============================================================================*/
6+
7+
#include <stdbool.h>
8+
#include <stdint.h>
9+
#include "platform.h"
10+
#include "internals.h"
11+
#include "specialize.h"
12+
#include "softfloat.h"
13+
14+
float8_t f8_mul( float8_t a, float8_t b )
15+
{
16+
uint_fast8_t roundingMode = softfloat_roundingMode;
17+
softfloat_roundingMode = softfloat_round_odd;
18+
float16_t a16 = f8_to_f16(a);
19+
float16_t b16 = f8_to_f16(b);
20+
float16_t z16 = f16_mul(a16, b16);
21+
softfloat_roundingMode = roundingMode;
22+
float8_t z = f16_to_f8(z16);
23+
return z;
24+
}

softfloat/internals.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4646
extern "C" {
4747
#endif
4848

49+
union ui8_f8 { uint8_t ui; float8_t f; };
4950
union ui16_f16 { uint16_t ui; float16_t f; };
5051
union ui32_f32 { uint32_t ui; float32_t f; };
5152
union ui64_f64 { uint64_t ui; float64_t f; };
@@ -84,6 +85,15 @@ int_fast64_t softfloat_roundMToI64( bool, uint32_t *, uint_fast8_t, bool );
8485

8586
/*----------------------------------------------------------------------------
8687
*----------------------------------------------------------------------------*/
88+
#define isNaNF8UI( a ) ((bool) (((uint8_t) a) == defaultNaNF8UI))
89+
#define isInfF8UI( a ) ((bool) ((((uint8_t) a) & 0x7F) == 0x7F))
90+
#define signF8UI( a ) ((bool) ((uint16_t) (a)>>7))
91+
#define expF8UI( a ) ((int_fast8_t) ((a)>>4) & 0x7)
92+
#define fracF8UI( a ) ((a) & 0xF)
93+
#define defaultInfF8UI 0x7F
94+
#define signInfF8UI( sign ) (((uint8_t) (sign)<<7) | defaultInfF8UI)
95+
#define packToF8UI( sign, exp, sig ) (((uint8_t) (sign)<<7) + ((uint8_t) (exp)<<4) + (sig))
96+
8797
#define signF16UI( a ) ((bool) ((uint16_t) (a)>>15))
8898
#define expF16UI( a ) ((int_fast8_t) ((a)>>10) & 0x1F)
8999
#define fracF16UI( a ) ((a) & 0x03FF)
@@ -96,9 +106,14 @@ int_fast64_t softfloat_roundMToI64( bool, uint32_t *, uint_fast8_t, bool );
96106

97107
#define isNaNF16UI( a ) (((~(a) & 0x7C00) == 0) && ((a) & 0x03FF))
98108

109+
struct exp8_sig8 { int_fast8_t exp; uint_fast8_t sig; };
110+
struct exp8_sig8 softfloat_normSubnormalF8Sig( uint_fast8_t );
111+
99112
struct exp8_sig16 { int_fast8_t exp; uint_fast16_t sig; };
100113
struct exp8_sig16 softfloat_normSubnormalF16Sig( uint_fast16_t );
101114

115+
float8_t softfloat_roundPackToF8( bool, int_fast8_t, uint_fast16_t );
116+
102117
float16_t softfloat_roundPackToF16( bool, int_fast16_t, uint_fast16_t );
103118
float16_t softfloat_normRoundPackToF16( bool, int_fast16_t, uint_fast16_t );
104119

softfloat/s_normSubnormalF8Sig.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
2+
/*============================================================================
3+
4+
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
5+
Package, Release 3d, by John R. Hauser.
6+
7+
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
8+
California. All rights reserved.
9+
10+
Redistribution and use in source and binary forms, with or without
11+
modification, are permitted provided that the following conditions are met:
12+
13+
1. Redistributions of source code must retain the above copyright notice,
14+
this list of conditions, and the following disclaimer.
15+
16+
2. Redistributions in binary form must reproduce the above copyright notice,
17+
this list of conditions, and the following disclaimer in the documentation
18+
and/or other materials provided with the distribution.
19+
20+
3. Neither the name of the University nor the names of its contributors may
21+
be used to endorse or promote products derived from this software without
22+
specific prior written permission.
23+
24+
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
25+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
27+
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
28+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34+
35+
=============================================================================*/
36+
37+
#include <stdint.h>
38+
#include "platform.h"
39+
#include "internals.h"
40+
41+
struct exp8_sig8 softfloat_normSubnormalF8Sig( uint_fast8_t sig )
42+
{
43+
int_fast8_t shiftDist;
44+
struct exp8_sig8 z;
45+
46+
shiftDist = softfloat_countLeadingZeros8[sig] - 3;
47+
z.exp = 1 - shiftDist;
48+
z.sig = sig<<shiftDist;
49+
return z;
50+
51+
}

softfloat/s_roundPackToF8.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*============================================================================
2+
3+
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
4+
Package, Release 3d, by John R. Hauser.
5+
6+
Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of
7+
California. All rights reserved.
8+
9+
Redistribution and use in source and binary forms, with or without
10+
modification, are permitted provided that the following conditions are met:
11+
12+
1. Redistributions of source code must retain the above copyright notice,
13+
this list of conditions, and the following disclaimer.
14+
15+
2. Redistributions in binary form must reproduce the above copyright notice,
16+
this list of conditions, and the following disclaimer in the documentation
17+
and/or other materials provided with the distribution.
18+
19+
3. Neither the name of the University nor the names of its contributors may
20+
be used to endorse or promote products derived from this software without
21+
specific prior written permission.
22+
23+
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
24+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
26+
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
27+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33+
34+
=============================================================================*/
35+
36+
#include <stdbool.h>
37+
#include <stdint.h>
38+
#include "platform.h"
39+
#include "internals.h"
40+
#include "softfloat.h"
41+
42+
float8_t
43+
softfloat_roundPackToF8( bool sign, int_fast8_t exp, uint_fast16_t sig )
44+
{
45+
uint_fast8_t roundingMode;
46+
bool roundNearEven;
47+
uint_fast8_t roundIncrement, roundBits;
48+
bool isTiny;
49+
uint_fast8_t uiZ;
50+
union ui8_f8 uZ;
51+
52+
/*------------------------------------------------------------------------
53+
*------------------------------------------------------------------------*/
54+
roundingMode = softfloat_roundingMode;
55+
roundNearEven = (roundingMode == softfloat_round_near_even);
56+
roundIncrement = 0x8; // How much to add to round, in this case 0x4 since we only need to round if gaurd bit it set
57+
if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {
58+
roundIncrement =
59+
(roundingMode
60+
== (sign ? softfloat_round_min : softfloat_round_max))
61+
? 0xF // Always round up
62+
: 0; // Always round down
63+
}
64+
roundBits = sig & 0xF;
65+
/*------------------------------------------------------------------------
66+
*------------------------------------------------------------------------*/
67+
if ( exp < 0 ) {
68+
isTiny =
69+
(softfloat_detectTininess == softfloat_tininess_beforeRounding)
70+
|| (exp < -1)// If exp == -2 rounding doesn't matter, will be tiny regardless
71+
|| (sig + roundIncrement < 0x200); // make rounding won't increment exp
72+
sig = softfloat_shiftRightJam32( sig, -exp ); // shift right and update sticky bit
73+
exp = 0; // Set exponent to 0 for subnormal
74+
roundBits = sig & 0xF; // GRS
75+
if ( isTiny && roundBits ) {
76+
softfloat_raiseFlags( softfloat_flag_underflow );
77+
}
78+
/*----------------------------------------------------------------
79+
*----------------------------------------------------------------*/
80+
} else if ( (0x7 < exp) // Already too large
81+
|| ((0x200 <= sig + roundIncrement) && exp == 0x7)) { // At max exp but round up
82+
softfloat_raiseFlags(
83+
softfloat_flag_overflow | softfloat_flag_inexact );
84+
uiZ = signInfF8UI(sign) - ! roundIncrement; // TODO: confused
85+
goto uiZ;
86+
}
87+
/*------------------------------------------------------------------------
88+
*------------------------------------------------------------------------*/
89+
sig = (sig + roundIncrement)>>4; // Round and delete GSR bits
90+
if ( roundBits ) {
91+
softfloat_exceptionFlags |= softfloat_flag_inexact;
92+
#ifdef SOFTFLOAT_ROUND_ODD
93+
if ( roundingMode == softfloat_round_odd ) {
94+
sig |= 1;
95+
goto packReturn;
96+
}
97+
#endif
98+
}
99+
sig &= ~(uint_fast16_t) (! (roundBits ^ 8) & roundNearEven);
100+
if ( ! sig ) {
101+
exp = 0;
102+
sign = 0; // Encode as zero
103+
}
104+
/*------------------------------------------------------------------------
105+
*------------------------------------------------------------------------*/
106+
packReturn:
107+
uiZ = packToF8UI( sign, exp, (uint_fast8_t) sig);
108+
uiZ:
109+
uZ.ui = uiZ;
110+
return uZ.f;
111+
}

softfloat/softfloat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ void i64_to_f128M( int64_t, float128_t * );
143143
/*----------------------------------------------------------------------------
144144
| 8-bit (half-precision) floating-point operations.
145145
*----------------------------------------------------------------------------*/
146+
float8_t f8_mul( float8_t, float8_t );
146147
float16_t f8_to_f16( float8_t );
147148

148149
/*----------------------------------------------------------------------------

softfloat/softfloat.mk.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ softfloat_c_srcs = \
4848
f16_lt_quiet.c \
4949
f16_mulAdd.c \
5050
f16_mul.c \
51+
f8_mul.c \
5152
f16_rem.c \
5253
f16_roundToInt.c \
5354
f16_sqrt.c \
@@ -175,10 +176,12 @@ softfloat_c_srcs = \
175176
s_mulAddF64.c \
176177
s_negXM.c \
177178
s_normRoundPackToF128.c \
179+
s_roundPackToF8.c \
178180
s_normRoundPackToF16.c \
179181
s_normRoundPackToF32.c \
180182
s_normRoundPackToF64.c \
181183
s_normSubnormalF128Sig.c \
184+
s_normSubnormalF8Sig.c \
182185
s_normSubnormalF16Sig.c \
183186
s_normSubnormalF32Sig.c \
184187
s_normSubnormalF64Sig.c \

softfloat/softfloat_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4747
| the types below may, if desired, be defined as aliases for the native types
4848
| (typically 'float' and 'double', and possibly 'long double').
4949
*----------------------------------------------------------------------------*/
50+
typedef struct { uint8_t v; } float8_t;
5051
typedef struct { uint16_t v; } float16_t;
5152
typedef float16_t bfloat16_t;
5253
typedef struct { uint32_t v; } float32_t;

softfloat/specialize.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ extern "C" {
9393
*----------------------------------------------------------------------------*/
9494
struct commonNaN { char _unused; };
9595

96+
/*----------------------------------------------------------------------------
97+
| The bit pattern for a default generated 8-bit floating-point NaN.
98+
*----------------------------------------------------------------------------*/
99+
#define defaultNaNF8UI 0x80
100+
96101
/*----------------------------------------------------------------------------
97102
| The bit pattern for a default generated 16-bit floating-point NaN.
98103
*----------------------------------------------------------------------------*/

0 commit comments

Comments
 (0)