00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef SOFTFLOAT_H
00033 #define SOFTFLOAT_H
00034
00035 #if defined(HOST_SOLARIS) && defined(NEEDS_LIBSUNMATH)
00036 #include <sunmath.h>
00037 #endif
00038
00039 #include <inttypes.h>
00040 #include "config.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 typedef uint8_t flag;
00051 typedef uint8_t uint8;
00052 typedef int8_t int8;
00053 #ifndef _AIX
00054 typedef int uint16;
00055 typedef int int16;
00056 #endif
00057 typedef unsigned int uint32;
00058 typedef signed int int32;
00059 typedef uint64_t uint64;
00060 typedef int64_t int64;
00061
00062
00063
00064
00065
00066
00067
00068 typedef uint8_t bits8;
00069 typedef int8_t sbits8;
00070 typedef uint16_t bits16;
00071 typedef int16_t sbits16;
00072 typedef uint32_t bits32;
00073 typedef int32_t sbits32;
00074 typedef uint64_t bits64;
00075 typedef int64_t sbits64;
00076
00077 #define LIT64( a ) a##LL
00078 #define INLINE static inline
00079
00080
00081
00082
00083
00084
00085
00086
00087 #ifdef CONFIG_SOFTFLOAT
00088
00089 #define FLOATX80
00090 #define FLOAT128
00091 #else
00092
00093 #if (defined(__i386__) || defined(__x86_64__)) && !defined(_BSD)
00094 #define FLOATX80
00095 #endif
00096 #endif
00097
00098 #define STATUS_PARAM , float_status *status
00099 #define STATUS(field) status->field
00100 #define STATUS_VAR , status
00101
00102
00103
00104
00105 enum {
00106 float_relation_less = -1,
00107 float_relation_equal = 0,
00108 float_relation_greater = 1,
00109 float_relation_unordered = 2
00110 };
00111
00112 #ifdef CONFIG_SOFTFLOAT
00113
00114
00115
00116
00117
00118
00119
00120
00121 #ifdef USE_SOFTFLOAT_STRUCT_TYPES
00122 typedef struct {
00123 uint32_t v;
00124 } float32;
00125
00126 #define float32_val(x) (((float32)(x)).v)
00127 #define make_float32(x) __extension__ ({ float32 f32_val = {x}; f32_val; })
00128 typedef struct {
00129 uint64_t v;
00130 } float64;
00131 #define float64_val(x) (((float64)(x)).v)
00132 #define make_float64(x) __extension__ ({ float64 f64_val = {x}; f64_val; })
00133 #else
00134 typedef uint32_t float32;
00135 typedef uint64_t float64;
00136 #define float32_val(x) (x)
00137 #define float64_val(x) (x)
00138 #define make_float32(x) (x)
00139 #define make_float64(x) (x)
00140 #endif
00141 #ifdef FLOATX80
00142 typedef struct {
00143 uint64_t low;
00144 uint16_t high;
00145 } floatx80;
00146 #endif
00147 #ifdef FLOAT128
00148 typedef struct {
00149 #ifdef WORDS_BIGENDIAN
00150 uint64_t high, low;
00151 #else
00152 uint64_t low, high;
00153 #endif
00154 } float128;
00155 #endif
00156
00157
00158
00159
00160 enum {
00161 float_tininess_after_rounding = 0,
00162 float_tininess_before_rounding = 1
00163 };
00164
00165
00166
00167
00168 enum {
00169 float_round_nearest_even = 0,
00170 float_round_down = 1,
00171 float_round_up = 2,
00172 float_round_to_zero = 3
00173 };
00174
00175
00176
00177
00178 enum {
00179 float_flag_invalid = 1,
00180 float_flag_divbyzero = 4,
00181 float_flag_overflow = 8,
00182 float_flag_underflow = 16,
00183 float_flag_inexact = 32
00184 };
00185
00186 typedef struct float_status {
00187 signed char float_detect_tininess;
00188 signed char float_rounding_mode;
00189 signed char float_exception_flags;
00190 #ifdef FLOATX80
00191 signed char floatx80_rounding_precision;
00192 #endif
00193 flag flush_to_zero;
00194 flag default_nan_mode;
00195 } float_status;
00196
00197 void set_float_rounding_mode(int val STATUS_PARAM);
00198 void set_float_exception_flags(int val STATUS_PARAM);
00199 INLINE void set_flush_to_zero(flag val STATUS_PARAM)
00200 {
00201 STATUS(flush_to_zero) = val;
00202 }
00203 INLINE void set_default_nan_mode(flag val STATUS_PARAM)
00204 {
00205 STATUS(default_nan_mode) = val;
00206 }
00207 INLINE int get_float_exception_flags(float_status *status)
00208 {
00209 return STATUS(float_exception_flags);
00210 }
00211 #ifdef FLOATX80
00212 void set_floatx80_rounding_precision(int val STATUS_PARAM);
00213 #endif
00214
00215
00216
00217
00218
00219 void float_raise( int8 flags STATUS_PARAM);
00220
00221
00222
00223
00224 float32 int32_to_float32( int STATUS_PARAM );
00225 float64 int32_to_float64( int STATUS_PARAM );
00226 float32 uint32_to_float32( unsigned int STATUS_PARAM );
00227 float64 uint32_to_float64( unsigned int STATUS_PARAM );
00228 #ifdef FLOATX80
00229 floatx80 int32_to_floatx80( int STATUS_PARAM );
00230 #endif
00231 #ifdef FLOAT128
00232 float128 int32_to_float128( int STATUS_PARAM );
00233 #endif
00234 float32 int64_to_float32( int64_t STATUS_PARAM );
00235 float32 uint64_to_float32( uint64_t STATUS_PARAM );
00236 float64 int64_to_float64( int64_t STATUS_PARAM );
00237 float64 uint64_to_float64( uint64_t STATUS_PARAM );
00238 #ifdef FLOATX80
00239 floatx80 int64_to_floatx80( int64_t STATUS_PARAM );
00240 #endif
00241 #ifdef FLOAT128
00242 float128 int64_to_float128( int64_t STATUS_PARAM );
00243 #endif
00244
00245
00246
00247
00248 int float32_to_int32( float32 STATUS_PARAM );
00249 int float32_to_int32_round_to_zero( float32 STATUS_PARAM );
00250 unsigned int float32_to_uint32( float32 STATUS_PARAM );
00251 unsigned int float32_to_uint32_round_to_zero( float32 STATUS_PARAM );
00252 int64_t float32_to_int64( float32 STATUS_PARAM );
00253 int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM );
00254 float64 float32_to_float64( float32 STATUS_PARAM );
00255 #ifdef FLOATX80
00256 floatx80 float32_to_floatx80( float32 STATUS_PARAM );
00257 #endif
00258 #ifdef FLOAT128
00259 float128 float32_to_float128( float32 STATUS_PARAM );
00260 #endif
00261
00262
00263
00264
00265 float32 float32_round_to_int( float32 STATUS_PARAM );
00266 float32 float32_add( float32, float32 STATUS_PARAM );
00267 float32 float32_sub( float32, float32 STATUS_PARAM );
00268 float32 float32_mul( float32, float32 STATUS_PARAM );
00269 float32 float32_div( float32, float32 STATUS_PARAM );
00270 float32 float32_rem( float32, float32 STATUS_PARAM );
00271 float32 float32_sqrt( float32 STATUS_PARAM );
00272 float32 float32_log2( float32 STATUS_PARAM );
00273 int float32_eq( float32, float32 STATUS_PARAM );
00274 int float32_le( float32, float32 STATUS_PARAM );
00275 int float32_lt( float32, float32 STATUS_PARAM );
00276 int float32_eq_signaling( float32, float32 STATUS_PARAM );
00277 int float32_le_quiet( float32, float32 STATUS_PARAM );
00278 int float32_lt_quiet( float32, float32 STATUS_PARAM );
00279 int float32_compare( float32, float32 STATUS_PARAM );
00280 int float32_compare_quiet( float32, float32 STATUS_PARAM );
00281 int float32_is_nan( float32 );
00282 int float32_is_signaling_nan( float32 );
00283 float32 float32_scalbn( float32, int STATUS_PARAM );
00284
00285 INLINE float32 float32_abs(float32 a)
00286 {
00287 return make_float32(float32_val(a) & 0x7fffffff);
00288 }
00289
00290 INLINE float32 float32_chs(float32 a)
00291 {
00292 return make_float32(float32_val(a) ^ 0x80000000);
00293 }
00294
00295 INLINE int float32_is_infinity(float32 a)
00296 {
00297 return (float32_val(a) & 0x7fffffff) == 0x7f800000;
00298 }
00299
00300 INLINE int float32_is_neg(float32 a)
00301 {
00302 return float32_val(a) >> 31;
00303 }
00304
00305 INLINE int float32_is_zero(float32 a)
00306 {
00307 return (float32_val(a) & 0x7fffffff) == 0;
00308 }
00309
00310 #define float32_zero make_float32(0)
00311 #define float32_one make_float32(0x3f800000)
00312
00313
00314
00315
00316 int float64_to_int32( float64 STATUS_PARAM );
00317 int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
00318 unsigned int float64_to_uint32( float64 STATUS_PARAM );
00319 unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
00320 int64_t float64_to_int64( float64 STATUS_PARAM );
00321 int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
00322 uint64_t float64_to_uint64 (float64 a STATUS_PARAM);
00323 uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM);
00324 float32 float64_to_float32( float64 STATUS_PARAM );
00325 #ifdef FLOATX80
00326 floatx80 float64_to_floatx80( float64 STATUS_PARAM );
00327 #endif
00328 #ifdef FLOAT128
00329 float128 float64_to_float128( float64 STATUS_PARAM );
00330 #endif
00331
00332
00333
00334
00335 float64 float64_round_to_int( float64 STATUS_PARAM );
00336 float64 float64_trunc_to_int( float64 STATUS_PARAM );
00337 float64 float64_add( float64, float64 STATUS_PARAM );
00338 float64 float64_sub( float64, float64 STATUS_PARAM );
00339 float64 float64_mul( float64, float64 STATUS_PARAM );
00340 float64 float64_div( float64, float64 STATUS_PARAM );
00341 float64 float64_rem( float64, float64 STATUS_PARAM );
00342 float64 float64_sqrt( float64 STATUS_PARAM );
00343 float64 float64_log2( float64 STATUS_PARAM );
00344 int float64_eq( float64, float64 STATUS_PARAM );
00345 int float64_le( float64, float64 STATUS_PARAM );
00346 int float64_lt( float64, float64 STATUS_PARAM );
00347 int float64_eq_signaling( float64, float64 STATUS_PARAM );
00348 int float64_le_quiet( float64, float64 STATUS_PARAM );
00349 int float64_lt_quiet( float64, float64 STATUS_PARAM );
00350 int float64_compare( float64, float64 STATUS_PARAM );
00351 int float64_compare_quiet( float64, float64 STATUS_PARAM );
00352 int float64_is_nan( float64 a );
00353 int float64_is_signaling_nan( float64 );
00354 float64 float64_scalbn( float64, int STATUS_PARAM );
00355
00356 INLINE float64 float64_abs(float64 a)
00357 {
00358 return make_float64(float64_val(a) & 0x7fffffffffffffffLL);
00359 }
00360
00361 INLINE float64 float64_chs(float64 a)
00362 {
00363 return make_float64(float64_val(a) ^ 0x8000000000000000LL);
00364 }
00365
00366 INLINE int float64_is_infinity(float64 a)
00367 {
00368 return (float64_val(a) & 0x7fffffffffffffffLL ) == 0x7ff0000000000000LL;
00369 }
00370
00371 INLINE int float64_is_neg(float64 a)
00372 {
00373 return float64_val(a) >> 63;
00374 }
00375
00376 INLINE int float64_is_zero(float64 a)
00377 {
00378 return (float64_val(a) & 0x7fffffffffffffffLL) == 0;
00379 }
00380
00381 #define float64_zero make_float64(0)
00382 #define float64_one make_float64(0x3ff0000000000000LL)
00383
00384 #ifdef FLOATX80
00385
00386
00387
00388
00389 int floatx80_to_int32( floatx80 STATUS_PARAM );
00390 int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
00391 int64_t floatx80_to_int64( floatx80 STATUS_PARAM );
00392 int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM );
00393 float32 floatx80_to_float32( floatx80 STATUS_PARAM );
00394 float64 floatx80_to_float64( floatx80 STATUS_PARAM );
00395 #ifdef FLOAT128
00396 float128 floatx80_to_float128( floatx80 STATUS_PARAM );
00397 #endif
00398
00399
00400
00401
00402 floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
00403 floatx80 floatx80_add( floatx80, floatx80 STATUS_PARAM );
00404 floatx80 floatx80_sub( floatx80, floatx80 STATUS_PARAM );
00405 floatx80 floatx80_mul( floatx80, floatx80 STATUS_PARAM );
00406 floatx80 floatx80_div( floatx80, floatx80 STATUS_PARAM );
00407 floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
00408 floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
00409 int floatx80_eq( floatx80, floatx80 STATUS_PARAM );
00410 int floatx80_le( floatx80, floatx80 STATUS_PARAM );
00411 int floatx80_lt( floatx80, floatx80 STATUS_PARAM );
00412 int floatx80_eq_signaling( floatx80, floatx80 STATUS_PARAM );
00413 int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
00414 int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
00415 int floatx80_is_nan( floatx80 );
00416 int floatx80_is_signaling_nan( floatx80 );
00417 floatx80 floatx80_scalbn( floatx80, int STATUS_PARAM );
00418
00419 INLINE floatx80 floatx80_abs(floatx80 a)
00420 {
00421 a.high &= 0x7fff;
00422 return a;
00423 }
00424
00425 INLINE floatx80 floatx80_chs(floatx80 a)
00426 {
00427 a.high ^= 0x8000;
00428 return a;
00429 }
00430
00431 INLINE int floatx80_is_infinity(floatx80 a)
00432 {
00433 return (a.high & 0x7fff) == 0x7fff && a.low == 0;
00434 }
00435
00436 INLINE int floatx80_is_neg(floatx80 a)
00437 {
00438 return a.high >> 15;
00439 }
00440
00441 INLINE int floatx80_is_zero(floatx80 a)
00442 {
00443 return (a.high & 0x7fff) == 0 && a.low == 0;
00444 }
00445
00446 #endif
00447
00448 #ifdef FLOAT128
00449
00450
00451
00452
00453 int float128_to_int32( float128 STATUS_PARAM );
00454 int float128_to_int32_round_to_zero( float128 STATUS_PARAM );
00455 int64_t float128_to_int64( float128 STATUS_PARAM );
00456 int64_t float128_to_int64_round_to_zero( float128 STATUS_PARAM );
00457 float32 float128_to_float32( float128 STATUS_PARAM );
00458 float64 float128_to_float64( float128 STATUS_PARAM );
00459 #ifdef FLOATX80
00460 floatx80 float128_to_floatx80( float128 STATUS_PARAM );
00461 #endif
00462
00463
00464
00465
00466 float128 float128_round_to_int( float128 STATUS_PARAM );
00467 float128 float128_add( float128, float128 STATUS_PARAM );
00468 float128 float128_sub( float128, float128 STATUS_PARAM );
00469 float128 float128_mul( float128, float128 STATUS_PARAM );
00470 float128 float128_div( float128, float128 STATUS_PARAM );
00471 float128 float128_rem( float128, float128 STATUS_PARAM );
00472 float128 float128_sqrt( float128 STATUS_PARAM );
00473 int float128_eq( float128, float128 STATUS_PARAM );
00474 int float128_le( float128, float128 STATUS_PARAM );
00475 int float128_lt( float128, float128 STATUS_PARAM );
00476 int float128_eq_signaling( float128, float128 STATUS_PARAM );
00477 int float128_le_quiet( float128, float128 STATUS_PARAM );
00478 int float128_lt_quiet( float128, float128 STATUS_PARAM );
00479 int float128_compare( float128, float128 STATUS_PARAM );
00480 int float128_compare_quiet( float128, float128 STATUS_PARAM );
00481 int float128_is_nan( float128 );
00482 int float128_is_signaling_nan( float128 );
00483 float128 float128_scalbn( float128, int STATUS_PARAM );
00484
00485 INLINE float128 float128_abs(float128 a)
00486 {
00487 a.high &= 0x7fffffffffffffffLL;
00488 return a;
00489 }
00490
00491 INLINE float128 float128_chs(float128 a)
00492 {
00493 a.high ^= 0x8000000000000000LL;
00494 return a;
00495 }
00496
00497 INLINE int float128_is_infinity(float128 a)
00498 {
00499 return (a.high & 0x7fffffffffffffffLL) == 0x7fff000000000000LL && a.low == 0;
00500 }
00501
00502 INLINE int float128_is_neg(float128 a)
00503 {
00504 return a.high >> 63;
00505 }
00506
00507 INLINE int float128_is_zero(float128 a)
00508 {
00509 return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0;
00510 }
00511
00512 #endif
00513
00514 #else
00515
00516 #include "softfloat-native.h"
00517
00518 #endif
00519
00520 #endif