Back to home page

OSCL-LXR

 
 

    


0001 
0002 /*
0003 ===============================================================================
0004 
0005 This C header file is part of the SoftFloat IEC/IEEE Floating-point
0006 Arithmetic Package, Release 2.
0007 
0008 Written by John R. Hauser.  This work was made possible in part by the
0009 International Computer Science Institute, located at Suite 600, 1947 Center
0010 Street, Berkeley, California 94704.  Funding was partially provided by the
0011 National Science Foundation under grant MIP-9311980.  The original version
0012 of this code was written as part of a project to build a fixed-point vector
0013 processor in collaboration with the University of California at Berkeley,
0014 overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
0015 is available through the Web page
0016 http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
0017 
0018 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
0019 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
0020 TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
0021 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
0022 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
0023 
0024 Derivative works are acceptable, even for commercial purposes, so long as
0025 (1) they include prominent notice that the work is derivative, and (2) they
0026 include prominent notice akin to these three paragraphs for those parts of
0027 this code that are retained.
0028 
0029 ===============================================================================
0030 */
0031 
0032 #ifndef __SOFTFLOAT_H__
0033 #define __SOFTFLOAT_H__
0034 
0035 
0036 /*
0037 -------------------------------------------------------------------------------
0038 The macro `FLOATX80' must be defined to enable the extended double-precision
0039 floating-point format `floatx80'.  If this macro is not defined, the
0040 `floatx80' type will not be defined, and none of the functions that either
0041 input or output the `floatx80' type will be defined.
0042 -------------------------------------------------------------------------------
0043 */
0044 #ifdef CONFIG_FPE_NWFPE_XP
0045 #define FLOATX80
0046 #endif
0047 
0048 /*
0049 -------------------------------------------------------------------------------
0050 Software IEC/IEEE floating-point types.
0051 -------------------------------------------------------------------------------
0052 */
0053 typedef u32 float32;
0054 typedef u64 float64;
0055 typedef struct {
0056 #ifdef __ARMEB__
0057     u16 __padding;
0058     u16 high;
0059 #else
0060     u16 high;
0061     u16 __padding;
0062 #endif
0063     u64 low;
0064 }  __attribute__ ((packed,aligned(4))) floatx80;
0065 
0066 /*
0067 -------------------------------------------------------------------------------
0068 Software IEC/IEEE floating-point underflow tininess-detection mode.
0069 -------------------------------------------------------------------------------
0070 */
0071 extern signed char float_detect_tininess;
0072 enum {
0073     float_tininess_after_rounding  = 0,
0074     float_tininess_before_rounding = 1
0075 };
0076 
0077 /*
0078 -------------------------------------------------------------------------------
0079 Software IEC/IEEE floating-point rounding mode.
0080 -------------------------------------------------------------------------------
0081 */
0082 //extern int8 float_rounding_mode;
0083 enum {
0084     float_round_nearest_even = 0,
0085     float_round_to_zero      = 1,
0086     float_round_down         = 2,
0087     float_round_up           = 3
0088 };
0089 
0090 /*
0091 -------------------------------------------------------------------------------
0092 Software IEC/IEEE floating-point exception flags.
0093 -------------------------------------------------------------------------------
0094 enum {
0095     float_flag_inexact   =  1,
0096     float_flag_underflow =  2,
0097     float_flag_overflow  =  4,
0098     float_flag_divbyzero =  8,
0099     float_flag_invalid   = 16
0100 };
0101 
0102 ScottB: November 4, 1998
0103 Changed the enumeration to match the bit order in the FPA11.
0104 */
0105 
0106 enum {
0107     float_flag_invalid   =  1,
0108     float_flag_divbyzero =  2,
0109     float_flag_overflow  =  4,
0110     float_flag_underflow =  8,
0111     float_flag_inexact   = 16
0112 };
0113 
0114 /*
0115 -------------------------------------------------------------------------------
0116 Routine to raise any or all of the software IEC/IEEE floating-point
0117 exception flags.
0118 -------------------------------------------------------------------------------
0119 */
0120 void float_raise( signed char );
0121 
0122 /*
0123 -------------------------------------------------------------------------------
0124 Software IEC/IEEE integer-to-floating-point conversion routines.
0125 -------------------------------------------------------------------------------
0126 */
0127 float32 int32_to_float32( struct roundingData *, signed int );
0128 float64 int32_to_float64( signed int );
0129 #ifdef FLOATX80
0130 floatx80 int32_to_floatx80( signed int );
0131 #endif
0132 
0133 /*
0134 -------------------------------------------------------------------------------
0135 Software IEC/IEEE single-precision conversion routines.
0136 -------------------------------------------------------------------------------
0137 */
0138 signed int float32_to_int32( struct roundingData *, float32 );
0139 signed int float32_to_int32_round_to_zero( float32 );
0140 float64 float32_to_float64( float32 );
0141 #ifdef FLOATX80
0142 floatx80 float32_to_floatx80( float32 );
0143 #endif
0144 
0145 /*
0146 -------------------------------------------------------------------------------
0147 Software IEC/IEEE single-precision operations.
0148 -------------------------------------------------------------------------------
0149 */
0150 float32 float32_round_to_int( struct roundingData*, float32 );
0151 float32 float32_add( struct roundingData *, float32, float32 );
0152 float32 float32_sub( struct roundingData *, float32, float32 );
0153 float32 float32_mul( struct roundingData *, float32, float32 );
0154 float32 float32_div( struct roundingData *, float32, float32 );
0155 float32 float32_rem( struct roundingData *, float32, float32 );
0156 float32 float32_sqrt( struct roundingData*, float32 );
0157 char float32_eq( float32, float32 );
0158 char float32_le( float32, float32 );
0159 char float32_lt( float32, float32 );
0160 char float32_eq_signaling( float32, float32 );
0161 char float32_le_quiet( float32, float32 );
0162 char float32_lt_quiet( float32, float32 );
0163 char float32_is_signaling_nan( float32 );
0164 
0165 /*
0166 -------------------------------------------------------------------------------
0167 Software IEC/IEEE double-precision conversion routines.
0168 -------------------------------------------------------------------------------
0169 */
0170 signed int float64_to_int32( struct roundingData *, float64 );
0171 signed int float64_to_int32_round_to_zero( float64 );
0172 float32 float64_to_float32( struct roundingData *, float64 );
0173 #ifdef FLOATX80
0174 floatx80 float64_to_floatx80( float64 );
0175 #endif
0176 
0177 /*
0178 -------------------------------------------------------------------------------
0179 Software IEC/IEEE double-precision operations.
0180 -------------------------------------------------------------------------------
0181 */
0182 float64 float64_round_to_int( struct roundingData *, float64 );
0183 float64 float64_add( struct roundingData *, float64, float64 );
0184 float64 float64_sub( struct roundingData *, float64, float64 );
0185 float64 float64_mul( struct roundingData *, float64, float64 );
0186 float64 float64_div( struct roundingData *, float64, float64 );
0187 float64 float64_rem( struct roundingData *, float64, float64 );
0188 float64 float64_sqrt( struct roundingData *, float64 );
0189 char float64_eq( float64, float64 );
0190 char float64_le( float64, float64 );
0191 char float64_lt( float64, float64 );
0192 char float64_eq_signaling( float64, float64 );
0193 char float64_le_quiet( float64, float64 );
0194 char float64_lt_quiet( float64, float64 );
0195 char float64_is_signaling_nan( float64 );
0196 
0197 #ifdef FLOATX80
0198 
0199 /*
0200 -------------------------------------------------------------------------------
0201 Software IEC/IEEE extended double-precision conversion routines.
0202 -------------------------------------------------------------------------------
0203 */
0204 signed int floatx80_to_int32( struct roundingData *, floatx80 );
0205 signed int floatx80_to_int32_round_to_zero( floatx80 );
0206 float32 floatx80_to_float32( struct roundingData *, floatx80 );
0207 float64 floatx80_to_float64( struct roundingData *, floatx80 );
0208 
0209 /*
0210 -------------------------------------------------------------------------------
0211 Software IEC/IEEE extended double-precision operations.
0212 -------------------------------------------------------------------------------
0213 */
0214 floatx80 floatx80_round_to_int( struct roundingData *, floatx80 );
0215 floatx80 floatx80_add( struct roundingData *, floatx80, floatx80 );
0216 floatx80 floatx80_sub( struct roundingData *, floatx80, floatx80 );
0217 floatx80 floatx80_mul( struct roundingData *, floatx80, floatx80 );
0218 floatx80 floatx80_div( struct roundingData *, floatx80, floatx80 );
0219 floatx80 floatx80_rem( struct roundingData *, floatx80, floatx80 );
0220 floatx80 floatx80_sqrt( struct roundingData *, floatx80 );
0221 char floatx80_eq( floatx80, floatx80 );
0222 char floatx80_le( floatx80, floatx80 );
0223 char floatx80_lt( floatx80, floatx80 );
0224 char floatx80_eq_signaling( floatx80, floatx80 );
0225 char floatx80_le_quiet( floatx80, floatx80 );
0226 char floatx80_lt_quiet( floatx80, floatx80 );
0227 char floatx80_is_signaling_nan( floatx80 );
0228 
0229 extern flag floatx80_is_nan(floatx80);
0230 
0231 #endif
0232 
0233 static inline flag extractFloat32Sign(float32 a)
0234 {
0235     return a >> 31;
0236 }
0237 
0238 static inline flag float32_eq_nocheck(float32 a, float32 b)
0239 {
0240     return (a == b) || ((bits32) ((a | b) << 1) == 0);
0241 }
0242 
0243 static inline flag float32_lt_nocheck(float32 a, float32 b)
0244 {
0245     flag aSign, bSign;
0246 
0247     aSign = extractFloat32Sign(a);
0248     bSign = extractFloat32Sign(b);
0249     if (aSign != bSign)
0250         return aSign && ((bits32) ((a | b) << 1) != 0);
0251     return (a != b) && (aSign ^ (a < b));
0252 }
0253 
0254 static inline flag extractFloat64Sign(float64 a)
0255 {
0256     return a >> 63;
0257 }
0258 
0259 static inline flag float64_eq_nocheck(float64 a, float64 b)
0260 {
0261     return (a == b) || ((bits64) ((a | b) << 1) == 0);
0262 }
0263 
0264 static inline flag float64_lt_nocheck(float64 a, float64 b)
0265 {
0266     flag aSign, bSign;
0267 
0268     aSign = extractFloat64Sign(a);
0269     bSign = extractFloat64Sign(b);
0270     if (aSign != bSign)
0271         return aSign && ((bits64) ((a | b) << 1) != 0);
0272     return (a != b) && (aSign ^ (a < b));
0273 }
0274 
0275 extern flag float32_is_nan( float32 a );
0276 extern flag float64_is_nan( float64 a );
0277 
0278 extern int32 float64_to_uint32( struct roundingData *roundData, float64 a );
0279 extern int32 float64_to_uint32_round_to_zero( float64 a );
0280 
0281 #endif