xref: /openbmc/linux/arch/arm/nwfpe/softfloat.h (revision 50a23e6e)
11da177e4SLinus Torvalds 
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds ===============================================================================
41da177e4SLinus Torvalds 
51da177e4SLinus Torvalds This C header file is part of the SoftFloat IEC/IEEE Floating-point
61da177e4SLinus Torvalds Arithmetic Package, Release 2.
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds Written by John R. Hauser.  This work was made possible in part by the
91da177e4SLinus Torvalds International Computer Science Institute, located at Suite 600, 1947 Center
101da177e4SLinus Torvalds Street, Berkeley, California 94704.  Funding was partially provided by the
111da177e4SLinus Torvalds National Science Foundation under grant MIP-9311980.  The original version
121da177e4SLinus Torvalds of this code was written as part of a project to build a fixed-point vector
131da177e4SLinus Torvalds processor in collaboration with the University of California at Berkeley,
141da177e4SLinus Torvalds overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
1550a23e6eSJustin P. Mattock is available through the Web page
1650a23e6eSJustin P. Mattock http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
191da177e4SLinus Torvalds has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
201da177e4SLinus Torvalds TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
211da177e4SLinus Torvalds PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
221da177e4SLinus Torvalds AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
231da177e4SLinus Torvalds 
241da177e4SLinus Torvalds Derivative works are acceptable, even for commercial purposes, so long as
251da177e4SLinus Torvalds (1) they include prominent notice that the work is derivative, and (2) they
261da177e4SLinus Torvalds include prominent notice akin to these three paragraphs for those parts of
271da177e4SLinus Torvalds this code that are retained.
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds ===============================================================================
301da177e4SLinus Torvalds */
311da177e4SLinus Torvalds 
321da177e4SLinus Torvalds #ifndef __SOFTFLOAT_H__
331da177e4SLinus Torvalds #define __SOFTFLOAT_H__
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds 
361da177e4SLinus Torvalds /*
371da177e4SLinus Torvalds -------------------------------------------------------------------------------
381da177e4SLinus Torvalds The macro `FLOATX80' must be defined to enable the extended double-precision
391da177e4SLinus Torvalds floating-point format `floatx80'.  If this macro is not defined, the
401da177e4SLinus Torvalds `floatx80' type will not be defined, and none of the functions that either
411da177e4SLinus Torvalds input or output the `floatx80' type will be defined.
421da177e4SLinus Torvalds -------------------------------------------------------------------------------
431da177e4SLinus Torvalds */
441da177e4SLinus Torvalds #ifdef CONFIG_FPE_NWFPE_XP
451da177e4SLinus Torvalds #define FLOATX80
461da177e4SLinus Torvalds #endif
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds /*
491da177e4SLinus Torvalds -------------------------------------------------------------------------------
501da177e4SLinus Torvalds Software IEC/IEEE floating-point types.
511da177e4SLinus Torvalds -------------------------------------------------------------------------------
521da177e4SLinus Torvalds */
53bedf142bSLennert Buytenhek typedef u32 float32;
54bedf142bSLennert Buytenhek typedef u64 float64;
551da177e4SLinus Torvalds typedef struct {
56bedf142bSLennert Buytenhek #ifdef __ARMEB__
57bedf142bSLennert Buytenhek     u16 __padding;
58bedf142bSLennert Buytenhek     u16 high;
59bedf142bSLennert Buytenhek #else
60bedf142bSLennert Buytenhek     u16 high;
61bedf142bSLennert Buytenhek     u16 __padding;
62bedf142bSLennert Buytenhek #endif
63bedf142bSLennert Buytenhek     u64 low;
64a9da396aSKoen Kooi }  __attribute__ ((packed,aligned(4))) floatx80;
651da177e4SLinus Torvalds 
661da177e4SLinus Torvalds /*
671da177e4SLinus Torvalds -------------------------------------------------------------------------------
681da177e4SLinus Torvalds Software IEC/IEEE floating-point underflow tininess-detection mode.
691da177e4SLinus Torvalds -------------------------------------------------------------------------------
701da177e4SLinus Torvalds */
711da177e4SLinus Torvalds extern signed char float_detect_tininess;
721da177e4SLinus Torvalds enum {
731da177e4SLinus Torvalds     float_tininess_after_rounding  = 0,
741da177e4SLinus Torvalds     float_tininess_before_rounding = 1
751da177e4SLinus Torvalds };
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds /*
781da177e4SLinus Torvalds -------------------------------------------------------------------------------
791da177e4SLinus Torvalds Software IEC/IEEE floating-point rounding mode.
801da177e4SLinus Torvalds -------------------------------------------------------------------------------
811da177e4SLinus Torvalds */
82f148af25SRichard Purdie //extern int8 float_rounding_mode;
831da177e4SLinus Torvalds enum {
841da177e4SLinus Torvalds     float_round_nearest_even = 0,
851da177e4SLinus Torvalds     float_round_to_zero      = 1,
861da177e4SLinus Torvalds     float_round_down         = 2,
871da177e4SLinus Torvalds     float_round_up           = 3
881da177e4SLinus Torvalds };
891da177e4SLinus Torvalds 
901da177e4SLinus Torvalds /*
911da177e4SLinus Torvalds -------------------------------------------------------------------------------
921da177e4SLinus Torvalds Software IEC/IEEE floating-point exception flags.
931da177e4SLinus Torvalds -------------------------------------------------------------------------------
941da177e4SLinus Torvalds enum {
951da177e4SLinus Torvalds     float_flag_inexact   =  1,
961da177e4SLinus Torvalds     float_flag_underflow =  2,
971da177e4SLinus Torvalds     float_flag_overflow  =  4,
981da177e4SLinus Torvalds     float_flag_divbyzero =  8,
991da177e4SLinus Torvalds     float_flag_invalid   = 16
1001da177e4SLinus Torvalds };
1011da177e4SLinus Torvalds 
1021da177e4SLinus Torvalds ScottB: November 4, 1998
1031da177e4SLinus Torvalds Changed the enumeration to match the bit order in the FPA11.
1041da177e4SLinus Torvalds */
1051da177e4SLinus Torvalds 
1061da177e4SLinus Torvalds enum {
1071da177e4SLinus Torvalds     float_flag_invalid   =  1,
1081da177e4SLinus Torvalds     float_flag_divbyzero =  2,
1091da177e4SLinus Torvalds     float_flag_overflow  =  4,
1101da177e4SLinus Torvalds     float_flag_underflow =  8,
1111da177e4SLinus Torvalds     float_flag_inexact   = 16
1121da177e4SLinus Torvalds };
1131da177e4SLinus Torvalds 
1141da177e4SLinus Torvalds /*
1151da177e4SLinus Torvalds -------------------------------------------------------------------------------
1161da177e4SLinus Torvalds Routine to raise any or all of the software IEC/IEEE floating-point
1171da177e4SLinus Torvalds exception flags.
1181da177e4SLinus Torvalds -------------------------------------------------------------------------------
1191da177e4SLinus Torvalds */
1201da177e4SLinus Torvalds void float_raise( signed char );
1211da177e4SLinus Torvalds 
1221da177e4SLinus Torvalds /*
1231da177e4SLinus Torvalds -------------------------------------------------------------------------------
1241da177e4SLinus Torvalds Software IEC/IEEE integer-to-floating-point conversion routines.
1251da177e4SLinus Torvalds -------------------------------------------------------------------------------
1261da177e4SLinus Torvalds */
127f148af25SRichard Purdie float32 int32_to_float32( struct roundingData *, signed int );
1281da177e4SLinus Torvalds float64 int32_to_float64( signed int );
1291da177e4SLinus Torvalds #ifdef FLOATX80
1301da177e4SLinus Torvalds floatx80 int32_to_floatx80( signed int );
1311da177e4SLinus Torvalds #endif
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds /*
1341da177e4SLinus Torvalds -------------------------------------------------------------------------------
1351da177e4SLinus Torvalds Software IEC/IEEE single-precision conversion routines.
1361da177e4SLinus Torvalds -------------------------------------------------------------------------------
1371da177e4SLinus Torvalds */
138f148af25SRichard Purdie signed int float32_to_int32( struct roundingData *, float32 );
1391da177e4SLinus Torvalds signed int float32_to_int32_round_to_zero( float32 );
1401da177e4SLinus Torvalds float64 float32_to_float64( float32 );
1411da177e4SLinus Torvalds #ifdef FLOATX80
1421da177e4SLinus Torvalds floatx80 float32_to_floatx80( float32 );
1431da177e4SLinus Torvalds #endif
1441da177e4SLinus Torvalds 
1451da177e4SLinus Torvalds /*
1461da177e4SLinus Torvalds -------------------------------------------------------------------------------
1471da177e4SLinus Torvalds Software IEC/IEEE single-precision operations.
1481da177e4SLinus Torvalds -------------------------------------------------------------------------------
1491da177e4SLinus Torvalds */
150f148af25SRichard Purdie float32 float32_round_to_int( struct roundingData*, float32 );
151f148af25SRichard Purdie float32 float32_add( struct roundingData *, float32, float32 );
152f148af25SRichard Purdie float32 float32_sub( struct roundingData *, float32, float32 );
153f148af25SRichard Purdie float32 float32_mul( struct roundingData *, float32, float32 );
154f148af25SRichard Purdie float32 float32_div( struct roundingData *, float32, float32 );
155f148af25SRichard Purdie float32 float32_rem( struct roundingData *, float32, float32 );
156f148af25SRichard Purdie float32 float32_sqrt( struct roundingData*, float32 );
1571da177e4SLinus Torvalds char float32_eq( float32, float32 );
1581da177e4SLinus Torvalds char float32_le( float32, float32 );
1591da177e4SLinus Torvalds char float32_lt( float32, float32 );
1601da177e4SLinus Torvalds char float32_eq_signaling( float32, float32 );
1611da177e4SLinus Torvalds char float32_le_quiet( float32, float32 );
1621da177e4SLinus Torvalds char float32_lt_quiet( float32, float32 );
1631da177e4SLinus Torvalds char float32_is_signaling_nan( float32 );
1641da177e4SLinus Torvalds 
1651da177e4SLinus Torvalds /*
1661da177e4SLinus Torvalds -------------------------------------------------------------------------------
1671da177e4SLinus Torvalds Software IEC/IEEE double-precision conversion routines.
1681da177e4SLinus Torvalds -------------------------------------------------------------------------------
1691da177e4SLinus Torvalds */
170f148af25SRichard Purdie signed int float64_to_int32( struct roundingData *, float64 );
1711da177e4SLinus Torvalds signed int float64_to_int32_round_to_zero( float64 );
172f148af25SRichard Purdie float32 float64_to_float32( struct roundingData *, float64 );
1731da177e4SLinus Torvalds #ifdef FLOATX80
1741da177e4SLinus Torvalds floatx80 float64_to_floatx80( float64 );
1751da177e4SLinus Torvalds #endif
1761da177e4SLinus Torvalds 
1771da177e4SLinus Torvalds /*
1781da177e4SLinus Torvalds -------------------------------------------------------------------------------
1791da177e4SLinus Torvalds Software IEC/IEEE double-precision operations.
1801da177e4SLinus Torvalds -------------------------------------------------------------------------------
1811da177e4SLinus Torvalds */
182f148af25SRichard Purdie float64 float64_round_to_int( struct roundingData *, float64 );
183f148af25SRichard Purdie float64 float64_add( struct roundingData *, float64, float64 );
184f148af25SRichard Purdie float64 float64_sub( struct roundingData *, float64, float64 );
185f148af25SRichard Purdie float64 float64_mul( struct roundingData *, float64, float64 );
186f148af25SRichard Purdie float64 float64_div( struct roundingData *, float64, float64 );
187f148af25SRichard Purdie float64 float64_rem( struct roundingData *, float64, float64 );
188f148af25SRichard Purdie float64 float64_sqrt( struct roundingData *, float64 );
1891da177e4SLinus Torvalds char float64_eq( float64, float64 );
1901da177e4SLinus Torvalds char float64_le( float64, float64 );
1911da177e4SLinus Torvalds char float64_lt( float64, float64 );
1921da177e4SLinus Torvalds char float64_eq_signaling( float64, float64 );
1931da177e4SLinus Torvalds char float64_le_quiet( float64, float64 );
1941da177e4SLinus Torvalds char float64_lt_quiet( float64, float64 );
1951da177e4SLinus Torvalds char float64_is_signaling_nan( float64 );
1961da177e4SLinus Torvalds 
1971da177e4SLinus Torvalds #ifdef FLOATX80
1981da177e4SLinus Torvalds 
1991da177e4SLinus Torvalds /*
2001da177e4SLinus Torvalds -------------------------------------------------------------------------------
2011da177e4SLinus Torvalds Software IEC/IEEE extended double-precision conversion routines.
2021da177e4SLinus Torvalds -------------------------------------------------------------------------------
2031da177e4SLinus Torvalds */
204f148af25SRichard Purdie signed int floatx80_to_int32( struct roundingData *, floatx80 );
2051da177e4SLinus Torvalds signed int floatx80_to_int32_round_to_zero( floatx80 );
206f148af25SRichard Purdie float32 floatx80_to_float32( struct roundingData *, floatx80 );
207f148af25SRichard Purdie float64 floatx80_to_float64( struct roundingData *, floatx80 );
2081da177e4SLinus Torvalds 
2091da177e4SLinus Torvalds /*
2101da177e4SLinus Torvalds -------------------------------------------------------------------------------
2111da177e4SLinus Torvalds Software IEC/IEEE extended double-precision operations.
2121da177e4SLinus Torvalds -------------------------------------------------------------------------------
2131da177e4SLinus Torvalds */
214f148af25SRichard Purdie floatx80 floatx80_round_to_int( struct roundingData *, floatx80 );
215f148af25SRichard Purdie floatx80 floatx80_add( struct roundingData *, floatx80, floatx80 );
216f148af25SRichard Purdie floatx80 floatx80_sub( struct roundingData *, floatx80, floatx80 );
217f148af25SRichard Purdie floatx80 floatx80_mul( struct roundingData *, floatx80, floatx80 );
218f148af25SRichard Purdie floatx80 floatx80_div( struct roundingData *, floatx80, floatx80 );
219f148af25SRichard Purdie floatx80 floatx80_rem( struct roundingData *, floatx80, floatx80 );
220f148af25SRichard Purdie floatx80 floatx80_sqrt( struct roundingData *, floatx80 );
2211da177e4SLinus Torvalds char floatx80_eq( floatx80, floatx80 );
2221da177e4SLinus Torvalds char floatx80_le( floatx80, floatx80 );
2231da177e4SLinus Torvalds char floatx80_lt( floatx80, floatx80 );
2241da177e4SLinus Torvalds char floatx80_eq_signaling( floatx80, floatx80 );
2251da177e4SLinus Torvalds char floatx80_le_quiet( floatx80, floatx80 );
2261da177e4SLinus Torvalds char floatx80_lt_quiet( floatx80, floatx80 );
2271da177e4SLinus Torvalds char floatx80_is_signaling_nan( floatx80 );
2281da177e4SLinus Torvalds 
2293ea385f0SBen Dooks extern flag floatx80_is_nan(floatx80);
2303ea385f0SBen Dooks 
2311da177e4SLinus Torvalds #endif
2321da177e4SLinus Torvalds 
extractFloat32Sign(float32 a)2331da177e4SLinus Torvalds static inline flag extractFloat32Sign(float32 a)
2341da177e4SLinus Torvalds {
2351da177e4SLinus Torvalds 	return a >> 31;
2361da177e4SLinus Torvalds }
2371da177e4SLinus Torvalds 
float32_eq_nocheck(float32 a,float32 b)2381da177e4SLinus Torvalds static inline flag float32_eq_nocheck(float32 a, float32 b)
2391da177e4SLinus Torvalds {
2401da177e4SLinus Torvalds 	return (a == b) || ((bits32) ((a | b) << 1) == 0);
2411da177e4SLinus Torvalds }
2421da177e4SLinus Torvalds 
float32_lt_nocheck(float32 a,float32 b)2431da177e4SLinus Torvalds static inline flag float32_lt_nocheck(float32 a, float32 b)
2441da177e4SLinus Torvalds {
2451da177e4SLinus Torvalds 	flag aSign, bSign;
2461da177e4SLinus Torvalds 
2471da177e4SLinus Torvalds 	aSign = extractFloat32Sign(a);
2481da177e4SLinus Torvalds 	bSign = extractFloat32Sign(b);
2491da177e4SLinus Torvalds 	if (aSign != bSign)
2501da177e4SLinus Torvalds 		return aSign && ((bits32) ((a | b) << 1) != 0);
2511da177e4SLinus Torvalds 	return (a != b) && (aSign ^ (a < b));
2521da177e4SLinus Torvalds }
2531da177e4SLinus Torvalds 
extractFloat64Sign(float64 a)2541da177e4SLinus Torvalds static inline flag extractFloat64Sign(float64 a)
2551da177e4SLinus Torvalds {
2561da177e4SLinus Torvalds 	return a >> 63;
2571da177e4SLinus Torvalds }
2581da177e4SLinus Torvalds 
float64_eq_nocheck(float64 a,float64 b)2591da177e4SLinus Torvalds static inline flag float64_eq_nocheck(float64 a, float64 b)
2601da177e4SLinus Torvalds {
2611da177e4SLinus Torvalds 	return (a == b) || ((bits64) ((a | b) << 1) == 0);
2621da177e4SLinus Torvalds }
2631da177e4SLinus Torvalds 
float64_lt_nocheck(float64 a,float64 b)2641da177e4SLinus Torvalds static inline flag float64_lt_nocheck(float64 a, float64 b)
2651da177e4SLinus Torvalds {
2661da177e4SLinus Torvalds 	flag aSign, bSign;
2671da177e4SLinus Torvalds 
2681da177e4SLinus Torvalds 	aSign = extractFloat64Sign(a);
2691da177e4SLinus Torvalds 	bSign = extractFloat64Sign(b);
2701da177e4SLinus Torvalds 	if (aSign != bSign)
2711da177e4SLinus Torvalds 		return aSign && ((bits64) ((a | b) << 1) != 0);
2721da177e4SLinus Torvalds 	return (a != b) && (aSign ^ (a < b));
2731da177e4SLinus Torvalds }
2741da177e4SLinus Torvalds 
2756ec5e7f3SBen Dooks extern flag float32_is_nan( float32 a );
2766ec5e7f3SBen Dooks extern flag float64_is_nan( float64 a );
2776ec5e7f3SBen Dooks 
2781ff08288SBen Dooks extern int32 float64_to_uint32( struct roundingData *roundData, float64 a );
2791ff08288SBen Dooks extern int32 float64_to_uint32_round_to_zero( float64 a );
2801ff08288SBen Dooks 
2811da177e4SLinus Torvalds #endif
282