0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #ifndef __SOFTFLOAT_H__
0033 #define __SOFTFLOAT_H__
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 #ifdef CONFIG_FPE_NWFPE_XP
0045 #define FLOATX80
0046 #endif
0047
0048
0049
0050
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
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
0080
0081
0082
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
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
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
0117
0118
0119
0120 void float_raise( signed char );
0121
0122
0123
0124
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
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
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
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
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
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
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