162306a36Sopenharmony_ci
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci===============================================================================
462306a36Sopenharmony_ci
562306a36Sopenharmony_ciThis C header file is part of the SoftFloat IEC/IEEE Floating-point
662306a36Sopenharmony_ciArithmetic Package, Release 2.
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciWritten by John R. Hauser.  This work was made possible in part by the
962306a36Sopenharmony_ciInternational Computer Science Institute, located at Suite 600, 1947 Center
1062306a36Sopenharmony_ciStreet, Berkeley, California 94704.  Funding was partially provided by the
1162306a36Sopenharmony_ciNational Science Foundation under grant MIP-9311980.  The original version
1262306a36Sopenharmony_ciof this code was written as part of a project to build a fixed-point vector
1362306a36Sopenharmony_ciprocessor in collaboration with the University of California at Berkeley,
1462306a36Sopenharmony_cioverseen by Profs. Nelson Morgan and John Wawrzynek.  More information
1562306a36Sopenharmony_ciis available through the Web page
1662306a36Sopenharmony_cihttp://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ciTHIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
1962306a36Sopenharmony_cihas been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
2062306a36Sopenharmony_ciTIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
2162306a36Sopenharmony_ciPERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
2262306a36Sopenharmony_ciAND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciDerivative works are acceptable, even for commercial purposes, so long as
2562306a36Sopenharmony_ci(1) they include prominent notice that the work is derivative, and (2) they
2662306a36Sopenharmony_ciinclude prominent notice akin to these three paragraphs for those parts of
2762306a36Sopenharmony_cithis code that are retained.
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci===============================================================================
3062306a36Sopenharmony_ci*/
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci#ifndef __SOFTFLOAT_H__
3362306a36Sopenharmony_ci#define __SOFTFLOAT_H__
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci/*
3762306a36Sopenharmony_ci-------------------------------------------------------------------------------
3862306a36Sopenharmony_ciThe macro `FLOATX80' must be defined to enable the extended double-precision
3962306a36Sopenharmony_cifloating-point format `floatx80'.  If this macro is not defined, the
4062306a36Sopenharmony_ci`floatx80' type will not be defined, and none of the functions that either
4162306a36Sopenharmony_ciinput or output the `floatx80' type will be defined.
4262306a36Sopenharmony_ci-------------------------------------------------------------------------------
4362306a36Sopenharmony_ci*/
4462306a36Sopenharmony_ci#ifdef CONFIG_FPE_NWFPE_XP
4562306a36Sopenharmony_ci#define FLOATX80
4662306a36Sopenharmony_ci#endif
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci/*
4962306a36Sopenharmony_ci-------------------------------------------------------------------------------
5062306a36Sopenharmony_ciSoftware IEC/IEEE floating-point types.
5162306a36Sopenharmony_ci-------------------------------------------------------------------------------
5262306a36Sopenharmony_ci*/
5362306a36Sopenharmony_citypedef u32 float32;
5462306a36Sopenharmony_citypedef u64 float64;
5562306a36Sopenharmony_citypedef struct {
5662306a36Sopenharmony_ci#ifdef __ARMEB__
5762306a36Sopenharmony_ci    u16 __padding;
5862306a36Sopenharmony_ci    u16 high;
5962306a36Sopenharmony_ci#else
6062306a36Sopenharmony_ci    u16 high;
6162306a36Sopenharmony_ci    u16 __padding;
6262306a36Sopenharmony_ci#endif
6362306a36Sopenharmony_ci    u64 low;
6462306a36Sopenharmony_ci}  __attribute__ ((packed,aligned(4))) floatx80;
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/*
6762306a36Sopenharmony_ci-------------------------------------------------------------------------------
6862306a36Sopenharmony_ciSoftware IEC/IEEE floating-point underflow tininess-detection mode.
6962306a36Sopenharmony_ci-------------------------------------------------------------------------------
7062306a36Sopenharmony_ci*/
7162306a36Sopenharmony_ciextern signed char float_detect_tininess;
7262306a36Sopenharmony_cienum {
7362306a36Sopenharmony_ci    float_tininess_after_rounding  = 0,
7462306a36Sopenharmony_ci    float_tininess_before_rounding = 1
7562306a36Sopenharmony_ci};
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci/*
7862306a36Sopenharmony_ci-------------------------------------------------------------------------------
7962306a36Sopenharmony_ciSoftware IEC/IEEE floating-point rounding mode.
8062306a36Sopenharmony_ci-------------------------------------------------------------------------------
8162306a36Sopenharmony_ci*/
8262306a36Sopenharmony_ci//extern int8 float_rounding_mode;
8362306a36Sopenharmony_cienum {
8462306a36Sopenharmony_ci    float_round_nearest_even = 0,
8562306a36Sopenharmony_ci    float_round_to_zero      = 1,
8662306a36Sopenharmony_ci    float_round_down         = 2,
8762306a36Sopenharmony_ci    float_round_up           = 3
8862306a36Sopenharmony_ci};
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci/*
9162306a36Sopenharmony_ci-------------------------------------------------------------------------------
9262306a36Sopenharmony_ciSoftware IEC/IEEE floating-point exception flags.
9362306a36Sopenharmony_ci-------------------------------------------------------------------------------
9462306a36Sopenharmony_cienum {
9562306a36Sopenharmony_ci    float_flag_inexact   =  1,
9662306a36Sopenharmony_ci    float_flag_underflow =  2,
9762306a36Sopenharmony_ci    float_flag_overflow  =  4,
9862306a36Sopenharmony_ci    float_flag_divbyzero =  8,
9962306a36Sopenharmony_ci    float_flag_invalid   = 16
10062306a36Sopenharmony_ci};
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ciScottB: November 4, 1998
10362306a36Sopenharmony_ciChanged the enumeration to match the bit order in the FPA11.
10462306a36Sopenharmony_ci*/
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_cienum {
10762306a36Sopenharmony_ci    float_flag_invalid   =  1,
10862306a36Sopenharmony_ci    float_flag_divbyzero =  2,
10962306a36Sopenharmony_ci    float_flag_overflow  =  4,
11062306a36Sopenharmony_ci    float_flag_underflow =  8,
11162306a36Sopenharmony_ci    float_flag_inexact   = 16
11262306a36Sopenharmony_ci};
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci/*
11562306a36Sopenharmony_ci-------------------------------------------------------------------------------
11662306a36Sopenharmony_ciRoutine to raise any or all of the software IEC/IEEE floating-point
11762306a36Sopenharmony_ciexception flags.
11862306a36Sopenharmony_ci-------------------------------------------------------------------------------
11962306a36Sopenharmony_ci*/
12062306a36Sopenharmony_civoid float_raise( signed char );
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci/*
12362306a36Sopenharmony_ci-------------------------------------------------------------------------------
12462306a36Sopenharmony_ciSoftware IEC/IEEE integer-to-floating-point conversion routines.
12562306a36Sopenharmony_ci-------------------------------------------------------------------------------
12662306a36Sopenharmony_ci*/
12762306a36Sopenharmony_cifloat32 int32_to_float32( struct roundingData *, signed int );
12862306a36Sopenharmony_cifloat64 int32_to_float64( signed int );
12962306a36Sopenharmony_ci#ifdef FLOATX80
13062306a36Sopenharmony_cifloatx80 int32_to_floatx80( signed int );
13162306a36Sopenharmony_ci#endif
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci/*
13462306a36Sopenharmony_ci-------------------------------------------------------------------------------
13562306a36Sopenharmony_ciSoftware IEC/IEEE single-precision conversion routines.
13662306a36Sopenharmony_ci-------------------------------------------------------------------------------
13762306a36Sopenharmony_ci*/
13862306a36Sopenharmony_cisigned int float32_to_int32( struct roundingData *, float32 );
13962306a36Sopenharmony_cisigned int float32_to_int32_round_to_zero( float32 );
14062306a36Sopenharmony_cifloat64 float32_to_float64( float32 );
14162306a36Sopenharmony_ci#ifdef FLOATX80
14262306a36Sopenharmony_cifloatx80 float32_to_floatx80( float32 );
14362306a36Sopenharmony_ci#endif
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci/*
14662306a36Sopenharmony_ci-------------------------------------------------------------------------------
14762306a36Sopenharmony_ciSoftware IEC/IEEE single-precision operations.
14862306a36Sopenharmony_ci-------------------------------------------------------------------------------
14962306a36Sopenharmony_ci*/
15062306a36Sopenharmony_cifloat32 float32_round_to_int( struct roundingData*, float32 );
15162306a36Sopenharmony_cifloat32 float32_add( struct roundingData *, float32, float32 );
15262306a36Sopenharmony_cifloat32 float32_sub( struct roundingData *, float32, float32 );
15362306a36Sopenharmony_cifloat32 float32_mul( struct roundingData *, float32, float32 );
15462306a36Sopenharmony_cifloat32 float32_div( struct roundingData *, float32, float32 );
15562306a36Sopenharmony_cifloat32 float32_rem( struct roundingData *, float32, float32 );
15662306a36Sopenharmony_cifloat32 float32_sqrt( struct roundingData*, float32 );
15762306a36Sopenharmony_cichar float32_eq( float32, float32 );
15862306a36Sopenharmony_cichar float32_le( float32, float32 );
15962306a36Sopenharmony_cichar float32_lt( float32, float32 );
16062306a36Sopenharmony_cichar float32_eq_signaling( float32, float32 );
16162306a36Sopenharmony_cichar float32_le_quiet( float32, float32 );
16262306a36Sopenharmony_cichar float32_lt_quiet( float32, float32 );
16362306a36Sopenharmony_cichar float32_is_signaling_nan( float32 );
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci/*
16662306a36Sopenharmony_ci-------------------------------------------------------------------------------
16762306a36Sopenharmony_ciSoftware IEC/IEEE double-precision conversion routines.
16862306a36Sopenharmony_ci-------------------------------------------------------------------------------
16962306a36Sopenharmony_ci*/
17062306a36Sopenharmony_cisigned int float64_to_int32( struct roundingData *, float64 );
17162306a36Sopenharmony_cisigned int float64_to_int32_round_to_zero( float64 );
17262306a36Sopenharmony_cifloat32 float64_to_float32( struct roundingData *, float64 );
17362306a36Sopenharmony_ci#ifdef FLOATX80
17462306a36Sopenharmony_cifloatx80 float64_to_floatx80( float64 );
17562306a36Sopenharmony_ci#endif
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci/*
17862306a36Sopenharmony_ci-------------------------------------------------------------------------------
17962306a36Sopenharmony_ciSoftware IEC/IEEE double-precision operations.
18062306a36Sopenharmony_ci-------------------------------------------------------------------------------
18162306a36Sopenharmony_ci*/
18262306a36Sopenharmony_cifloat64 float64_round_to_int( struct roundingData *, float64 );
18362306a36Sopenharmony_cifloat64 float64_add( struct roundingData *, float64, float64 );
18462306a36Sopenharmony_cifloat64 float64_sub( struct roundingData *, float64, float64 );
18562306a36Sopenharmony_cifloat64 float64_mul( struct roundingData *, float64, float64 );
18662306a36Sopenharmony_cifloat64 float64_div( struct roundingData *, float64, float64 );
18762306a36Sopenharmony_cifloat64 float64_rem( struct roundingData *, float64, float64 );
18862306a36Sopenharmony_cifloat64 float64_sqrt( struct roundingData *, float64 );
18962306a36Sopenharmony_cichar float64_eq( float64, float64 );
19062306a36Sopenharmony_cichar float64_le( float64, float64 );
19162306a36Sopenharmony_cichar float64_lt( float64, float64 );
19262306a36Sopenharmony_cichar float64_eq_signaling( float64, float64 );
19362306a36Sopenharmony_cichar float64_le_quiet( float64, float64 );
19462306a36Sopenharmony_cichar float64_lt_quiet( float64, float64 );
19562306a36Sopenharmony_cichar float64_is_signaling_nan( float64 );
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci#ifdef FLOATX80
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci/*
20062306a36Sopenharmony_ci-------------------------------------------------------------------------------
20162306a36Sopenharmony_ciSoftware IEC/IEEE extended double-precision conversion routines.
20262306a36Sopenharmony_ci-------------------------------------------------------------------------------
20362306a36Sopenharmony_ci*/
20462306a36Sopenharmony_cisigned int floatx80_to_int32( struct roundingData *, floatx80 );
20562306a36Sopenharmony_cisigned int floatx80_to_int32_round_to_zero( floatx80 );
20662306a36Sopenharmony_cifloat32 floatx80_to_float32( struct roundingData *, floatx80 );
20762306a36Sopenharmony_cifloat64 floatx80_to_float64( struct roundingData *, floatx80 );
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci/*
21062306a36Sopenharmony_ci-------------------------------------------------------------------------------
21162306a36Sopenharmony_ciSoftware IEC/IEEE extended double-precision operations.
21262306a36Sopenharmony_ci-------------------------------------------------------------------------------
21362306a36Sopenharmony_ci*/
21462306a36Sopenharmony_cifloatx80 floatx80_round_to_int( struct roundingData *, floatx80 );
21562306a36Sopenharmony_cifloatx80 floatx80_add( struct roundingData *, floatx80, floatx80 );
21662306a36Sopenharmony_cifloatx80 floatx80_sub( struct roundingData *, floatx80, floatx80 );
21762306a36Sopenharmony_cifloatx80 floatx80_mul( struct roundingData *, floatx80, floatx80 );
21862306a36Sopenharmony_cifloatx80 floatx80_div( struct roundingData *, floatx80, floatx80 );
21962306a36Sopenharmony_cifloatx80 floatx80_rem( struct roundingData *, floatx80, floatx80 );
22062306a36Sopenharmony_cifloatx80 floatx80_sqrt( struct roundingData *, floatx80 );
22162306a36Sopenharmony_cichar floatx80_eq( floatx80, floatx80 );
22262306a36Sopenharmony_cichar floatx80_le( floatx80, floatx80 );
22362306a36Sopenharmony_cichar floatx80_lt( floatx80, floatx80 );
22462306a36Sopenharmony_cichar floatx80_eq_signaling( floatx80, floatx80 );
22562306a36Sopenharmony_cichar floatx80_le_quiet( floatx80, floatx80 );
22662306a36Sopenharmony_cichar floatx80_lt_quiet( floatx80, floatx80 );
22762306a36Sopenharmony_cichar floatx80_is_signaling_nan( floatx80 );
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ciextern flag floatx80_is_nan(floatx80);
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci#endif
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_cistatic inline flag extractFloat32Sign(float32 a)
23462306a36Sopenharmony_ci{
23562306a36Sopenharmony_ci	return a >> 31;
23662306a36Sopenharmony_ci}
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_cistatic inline flag float32_eq_nocheck(float32 a, float32 b)
23962306a36Sopenharmony_ci{
24062306a36Sopenharmony_ci	return (a == b) || ((bits32) ((a | b) << 1) == 0);
24162306a36Sopenharmony_ci}
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_cistatic inline flag float32_lt_nocheck(float32 a, float32 b)
24462306a36Sopenharmony_ci{
24562306a36Sopenharmony_ci	flag aSign, bSign;
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci	aSign = extractFloat32Sign(a);
24862306a36Sopenharmony_ci	bSign = extractFloat32Sign(b);
24962306a36Sopenharmony_ci	if (aSign != bSign)
25062306a36Sopenharmony_ci		return aSign && ((bits32) ((a | b) << 1) != 0);
25162306a36Sopenharmony_ci	return (a != b) && (aSign ^ (a < b));
25262306a36Sopenharmony_ci}
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_cistatic inline flag extractFloat64Sign(float64 a)
25562306a36Sopenharmony_ci{
25662306a36Sopenharmony_ci	return a >> 63;
25762306a36Sopenharmony_ci}
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_cistatic inline flag float64_eq_nocheck(float64 a, float64 b)
26062306a36Sopenharmony_ci{
26162306a36Sopenharmony_ci	return (a == b) || ((bits64) ((a | b) << 1) == 0);
26262306a36Sopenharmony_ci}
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_cistatic inline flag float64_lt_nocheck(float64 a, float64 b)
26562306a36Sopenharmony_ci{
26662306a36Sopenharmony_ci	flag aSign, bSign;
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci	aSign = extractFloat64Sign(a);
26962306a36Sopenharmony_ci	bSign = extractFloat64Sign(b);
27062306a36Sopenharmony_ci	if (aSign != bSign)
27162306a36Sopenharmony_ci		return aSign && ((bits64) ((a | b) << 1) != 0);
27262306a36Sopenharmony_ci	return (a != b) && (aSign ^ (a < b));
27362306a36Sopenharmony_ci}
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ciextern flag float32_is_nan( float32 a );
27662306a36Sopenharmony_ciextern flag float64_is_nan( float64 a );
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ciextern int32 float64_to_uint32( struct roundingData *roundData, float64 a );
27962306a36Sopenharmony_ciextern int32 float64_to_uint32_round_to_zero( float64 a );
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci#endif
282