|
|
1.1 ! root 1: ! 2: /*============================================================================ ! 3: ! 4: This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic ! 5: Package, Release 2b. ! 6: ! 7: Written by John R. Hauser. This work was made possible in part by the ! 8: International Computer Science Institute, located at Suite 600, 1947 Center ! 9: Street, Berkeley, California 94704. Funding was partially provided by the ! 10: National Science Foundation under grant MIP-9311980. The original version ! 11: of this code was written as part of a project to build a fixed-point vector ! 12: processor in collaboration with the University of California at Berkeley, ! 13: overseen by Profs. Nelson Morgan and John Wawrzynek. More information ! 14: is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ ! 15: arithmetic/SoftFloat.html'. ! 16: ! 17: THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has ! 18: been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES ! 19: RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS ! 20: AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, ! 21: COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE ! 22: EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE ! 23: INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR ! 24: OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. ! 25: ! 26: Derivative works are acceptable, even for commercial purposes, so long as ! 27: (1) the source code for the derivative work includes prominent notice that ! 28: the work is derivative, and (2) the source code includes prominent notice with ! 29: these four paragraphs for those parts of this code that are retained. ! 30: ! 31: =============================================================================*/ ! 32: ! 33: #ifndef SOFTFLOAT_H ! 34: #define SOFTFLOAT_H ! 35: /*---------------------------------------------------------------------------- ! 36: | The macro `FLOATX80' must be defined to enable the extended double-precision ! 37: | floating-point format `floatx80'. If this macro is not defined, the ! 38: | `floatx80' type will not be defined, and none of the functions that either ! 39: | input or output the `floatx80' type will be defined. The same applies to ! 40: | the `FLOAT128' macro and the quadruple-precision format `float128'. ! 41: *----------------------------------------------------------------------------*/ ! 42: #define FLOATX80 ! 43: #define FLOAT128 ! 44: ! 45: /*---------------------------------------------------------------------------- ! 46: | Software IEC/IEEE floating-point types. ! 47: *----------------------------------------------------------------------------*/ ! 48: ! 49: #include "mamesf.h" ! 50: ! 51: typedef bits32 float32; ! 52: typedef bits64 float64; ! 53: #ifdef FLOATX80 ! 54: typedef struct { ! 55: bits16 high; ! 56: bits64 low; ! 57: } floatx80; ! 58: #endif ! 59: #ifdef FLOAT128 ! 60: typedef struct { ! 61: bits64 high, low; ! 62: } float128; ! 63: #endif ! 64: ! 65: /*---------------------------------------------------------------------------- ! 66: | Primitive arithmetic functions, including multi-word arithmetic, and ! 67: | division and square root approximations. (Can be specialized to target if ! 68: | desired.) ! 69: *----------------------------------------------------------------------------*/ ! 70: #include "softfloat-macros.h" ! 71: ! 72: /*---------------------------------------------------------------------------- ! 73: | Software IEC/IEEE floating-point underflow tininess-detection mode. ! 74: *----------------------------------------------------------------------------*/ ! 75: extern int8 float_detect_tininess; ! 76: enum { ! 77: float_tininess_after_rounding = 0, ! 78: float_tininess_before_rounding = 1 ! 79: }; ! 80: ! 81: /*---------------------------------------------------------------------------- ! 82: | Software IEC/IEEE floating-point rounding mode. ! 83: *----------------------------------------------------------------------------*/ ! 84: extern int8 float_rounding_mode; ! 85: #ifdef SOFTFLOAT_I860 ! 86: extern int8 float_rounding_mode2; ! 87: #endif ! 88: enum { ! 89: float_round_nearest_even = 0, ! 90: float_round_to_zero = 1, ! 91: float_round_down = 2, ! 92: float_round_up = 3 ! 93: }; ! 94: ! 95: /*---------------------------------------------------------------------------- ! 96: | Software IEC/IEEE floating-point exception flags. ! 97: *----------------------------------------------------------------------------*/ ! 98: extern int8 float_exception_flags; ! 99: #ifdef SOFTFLOAT_I860 ! 100: extern int8 float_exception_flags2; ! 101: #endif ! 102: enum { ! 103: float_flag_invalid = 0x01, float_flag_denormal = 0x02, float_flag_divbyzero = 0x04, float_flag_overflow = 0x08, ! 104: float_flag_underflow = 0x10, float_flag_inexact = 0x20, float_flag_signaling = 0x40, float_flag_decimal = 0x80 ! 105: }; ! 106: ! 107: /*---------------------------------------------------------------------------- ! 108: | Variables for storing sign, exponent and significand of internal extended ! 109: | double-precision floating-point value for external use. ! 110: *----------------------------------------------------------------------------*/ ! 111: extern flag floatx80_internal_sign; ! 112: extern int32 floatx80_internal_exp; ! 113: extern bits64 floatx80_internal_sig0; ! 114: extern bits64 floatx80_internal_sig1; ! 115: extern int8 floatx80_internal_precision; ! 116: extern int8 floatx80_internal_mode; ! 117: ! 118: /*---------------------------------------------------------------------------- ! 119: | Function for getting sign, exponent and significand of extended ! 120: | double-precision floating-point intermediate result for external use. ! 121: *----------------------------------------------------------------------------*/ ! 122: floatx80 getFloatInternalOverflow( void ); ! 123: floatx80 getFloatInternalUnderflow( void ); ! 124: floatx80 getFloatInternalRoundedAll( void ); ! 125: floatx80 getFloatInternalRoundedSome( void ); ! 126: floatx80 getFloatInternalUnrounded( void ); ! 127: floatx80 getFloatInternalFloatx80( void ); ! 128: bits64 getFloatInternalGRS( void ); ! 129: ! 130: /*---------------------------------------------------------------------------- ! 131: | Routine to raise any or all of the software IEC/IEEE floating-point ! 132: | exception flags. ! 133: *----------------------------------------------------------------------------*/ ! 134: void float_raise( int8 ); ! 135: #ifdef SOFTFLOAT_I860 ! 136: void float_raise2( int8 ); ! 137: #endif ! 138: ! 139: /*---------------------------------------------------------------------------- ! 140: | The pattern for a default generated single-precision NaN. ! 141: *----------------------------------------------------------------------------*/ ! 142: #define float32_default_nan 0x7FFFFFFF ! 143: ! 144: /*---------------------------------------------------------------------------- ! 145: | The pattern for a default generated double-precision NaN. ! 146: *----------------------------------------------------------------------------*/ ! 147: #define float64_default_nan LIT64( 0x7FFFFFFFFFFFFFFF ) ! 148: ! 149: #ifdef FLOATX80 ! 150: /*---------------------------------------------------------------------------- ! 151: | The pattern for a default generated extended double-precision NaN. The ! 152: | `high' and `low' values hold the most- and least-significant bits, ! 153: | respectively. ! 154: *----------------------------------------------------------------------------*/ ! 155: #define floatx80_default_nan_high 0x7FFF ! 156: #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) ! 157: #endif ! 158: #ifdef FLOAT128 ! 159: /*---------------------------------------------------------------------------- ! 160: | The pattern for a default generated quadruple-precision NaN. The `high' and ! 161: | `low' values hold the most- and least-significant bits, respectively. ! 162: *----------------------------------------------------------------------------*/ ! 163: #define float128_default_nan_high LIT64( 0x7FFFFFFFFFFFFFFF ) ! 164: #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) ! 165: #endif ! 166: #ifdef FLOATX80 ! 167: /*---------------------------------------------------------------------------- ! 168: | The pattern for a default generated extended double-precision infinity. ! 169: *----------------------------------------------------------------------------*/ ! 170: #define floatx80_default_infinity_low LIT64( 0x0000000000000000 ) ! 171: #endif ! 172: ! 173: /*---------------------------------------------------------------------------- ! 174: | Software IEC/IEEE integer-to-floating-point conversion routines. ! 175: *----------------------------------------------------------------------------*/ ! 176: float32 int32_to_float32( int32 ); ! 177: float64 int32_to_float64( int32 ); ! 178: #ifdef FLOATX80 ! 179: floatx80 int32_to_floatx80( int32 ); ! 180: #endif ! 181: #ifdef FLOAT128 ! 182: float128 int32_to_float128( int32 ); ! 183: #endif ! 184: float32 int64_to_float32( int64 ); ! 185: float64 int64_to_float64( int64 ); ! 186: #ifdef FLOATX80 ! 187: floatx80 int64_to_floatx80( int64 ); ! 188: #endif ! 189: #ifdef FLOAT128 ! 190: float128 int64_to_float128( int64 ); ! 191: #endif ! 192: ! 193: /*---------------------------------------------------------------------------- ! 194: | Software IEC/IEEE single-precision conversion routines. ! 195: *----------------------------------------------------------------------------*/ ! 196: int32 float32_to_int32( float32 ); ! 197: int32 float32_to_int32_round_to_zero( float32 ); ! 198: int64 float32_to_int64( float32 ); ! 199: int64 float32_to_int64_round_to_zero( float32 ); ! 200: float64 float32_to_float64( float32 ); ! 201: #ifdef FLOATX80 ! 202: floatx80 float32_to_floatx80( float32 ); ! 203: floatx80 float32_to_floatx80_allowunnormal( float32 ); ! 204: #endif ! 205: #ifdef FLOAT128 ! 206: float128 float32_to_float128( float32 ); ! 207: #endif ! 208: ! 209: /*---------------------------------------------------------------------------- ! 210: | Software IEC/IEEE single-precision operations. ! 211: *----------------------------------------------------------------------------*/ ! 212: float32 float32_round_to_int( float32 ); ! 213: float32 float32_add( float32, float32 ); ! 214: float32 float32_sub( float32, float32 ); ! 215: float32 float32_mul( float32, float32 ); ! 216: float32 float32_div( float32, float32 ); ! 217: float32 float32_rem( float32, float32 ); ! 218: float32 float32_sqrt( float32 ); ! 219: flag float32_eq( float32, float32 ); ! 220: flag float32_le( float32, float32 ); ! 221: flag float32_lt( float32, float32 ); ! 222: #ifdef SOFTFLOAT_I860 ! 223: flag float32_gt( float32, float32 ); ! 224: #endif ! 225: flag float32_eq_signaling( float32, float32 ); ! 226: flag float32_le_quiet( float32, float32 ); ! 227: flag float32_lt_quiet( float32, float32 ); ! 228: flag float32_is_signaling_nan( float32 ); ! 229: ! 230: /*---------------------------------------------------------------------------- ! 231: | Software IEC/IEEE double-precision conversion routines. ! 232: *----------------------------------------------------------------------------*/ ! 233: int32 float64_to_int32( float64 ); ! 234: int32 float64_to_int32_round_to_zero( float64 ); ! 235: int64 float64_to_int64( float64 ); ! 236: int64 float64_to_int64_round_to_zero( float64 ); ! 237: float32 float64_to_float32( float64 ); ! 238: #ifdef FLOATX80 ! 239: floatx80 float64_to_floatx80( float64 ); ! 240: floatx80 float64_to_floatx80_allowunnormal( float64 ); ! 241: #endif ! 242: #ifdef FLOAT128 ! 243: float128 float64_to_float128( float64 ); ! 244: #endif ! 245: ! 246: /*---------------------------------------------------------------------------- ! 247: | Software IEC/IEEE double-precision operations. ! 248: *----------------------------------------------------------------------------*/ ! 249: float64 float64_round_to_int( float64 ); ! 250: float64 float64_add( float64, float64 ); ! 251: float64 float64_sub( float64, float64 ); ! 252: float64 float64_mul( float64, float64 ); ! 253: float64 float64_div( float64, float64 ); ! 254: float64 float64_rem( float64, float64 ); ! 255: float64 float64_sqrt( float64 ); ! 256: flag float64_eq( float64, float64 ); ! 257: flag float64_le( float64, float64 ); ! 258: flag float64_lt( float64, float64 ); ! 259: #ifdef SOFTFLOAT_I860 ! 260: flag float64_gt( float64, float64 ); ! 261: #endif ! 262: flag float64_eq_signaling( float64, float64 ); ! 263: flag float64_le_quiet( float64, float64 ); ! 264: flag float64_lt_quiet( float64, float64 ); ! 265: flag float64_is_signaling_nan( float64 ); ! 266: ! 267: #ifdef FLOATX80 ! 268: ! 269: /*---------------------------------------------------------------------------- ! 270: | Software IEC/IEEE extended double-precision conversion routines. ! 271: *----------------------------------------------------------------------------*/ ! 272: int32 floatx80_to_int32( floatx80 ); ! 273: #ifdef SOFTFLOAT_68K ! 274: int16 floatx80_to_int16( floatx80 ); ! 275: int8 floatx80_to_int8( floatx80 ); ! 276: #endif ! 277: int32 floatx80_to_int32_round_to_zero( floatx80 ); ! 278: int64 floatx80_to_int64( floatx80 ); ! 279: int64 floatx80_to_int64_round_to_zero( floatx80 ); ! 280: float32 floatx80_to_float32( floatx80 ); ! 281: float64 floatx80_to_float64( floatx80 ); ! 282: #ifdef SOFTFLOAT_68K ! 283: floatx80 floatx80_to_floatx80( floatx80 ); ! 284: floatx80 floatdecimal_to_floatx80( floatx80 ); ! 285: floatx80 floatx80_to_floatdecimal(floatx80, int32*); ! 286: #endif ! 287: #ifdef FLOAT128 ! 288: float128 floatx80_to_float128( floatx80 ); ! 289: #endif ! 290: bits64 extractFloatx80Frac( floatx80 a ); ! 291: int32 extractFloatx80Exp( floatx80 a ); ! 292: flag extractFloatx80Sign( floatx80 a ); ! 293: ! 294: /*---------------------------------------------------------------------------- ! 295: | Software IEC/IEEE extended double-precision rounding precision. Valid ! 296: | values are 32, 64, and 80. ! 297: *----------------------------------------------------------------------------*/ ! 298: extern int8 floatx80_rounding_precision; ! 299: ! 300: /*---------------------------------------------------------------------------- ! 301: | Software IEC/IEEE extended double-precision operations. ! 302: *----------------------------------------------------------------------------*/ ! 303: floatx80 floatx80_round_to_int( floatx80 ); ! 304: #ifdef SOFTFLOAT_68K ! 305: floatx80 floatx80_round_to_int_toward_zero( floatx80 ); ! 306: floatx80 floatx80_round_to_float32( floatx80 ); ! 307: floatx80 floatx80_round_to_float64( floatx80 ); ! 308: floatx80 floatx80_round32( floatx80 ); ! 309: floatx80 floatx80_round64( floatx80 ); ! 310: floatx80 floatx80_normalize( floatx80 ); ! 311: floatx80 floatx80_denormalize( floatx80, flag ); ! 312: #endif ! 313: floatx80 floatx80_add( floatx80, floatx80 ); ! 314: floatx80 floatx80_sub( floatx80, floatx80 ); ! 315: floatx80 floatx80_mul( floatx80, floatx80 ); ! 316: floatx80 floatx80_div( floatx80, floatx80 ); ! 317: #ifndef SOFTFLOAT_68K ! 318: floatx80 floatx80_rem( floatx80, floatx80 ); ! 319: #endif ! 320: floatx80 floatx80_sqrt( floatx80 ); ! 321: ! 322: flag floatx80_eq( floatx80, floatx80 ); ! 323: flag floatx80_le( floatx80, floatx80 ); ! 324: flag floatx80_lt( floatx80, floatx80 ); ! 325: flag floatx80_eq_signaling( floatx80, floatx80 ); ! 326: flag floatx80_le_quiet( floatx80, floatx80 ); ! 327: flag floatx80_lt_quiet( floatx80, floatx80 ); ! 328: ! 329: flag floatx80_is_signaling_nan( floatx80 ); ! 330: flag floatx80_is_nan( floatx80 ); ! 331: #ifdef SOFTFLOAT_68K ! 332: flag floatx80_is_zero( floatx80 ); ! 333: flag floatx80_is_infinity( floatx80 ); ! 334: flag floatx80_is_negative( floatx80 ); ! 335: flag floatx80_is_denormal( floatx80 ); ! 336: flag floatx80_is_unnormal( floatx80 ); ! 337: flag floatx80_is_normal( floatx80 ); ! 338: ! 339: // functions are in softfloat.c ! 340: floatx80 floatx80_move( floatx80 a ); ! 341: floatx80 floatx80_abs( floatx80 a ); ! 342: floatx80 floatx80_neg( floatx80 a ); ! 343: floatx80 floatx80_getexp( floatx80 a ); ! 344: floatx80 floatx80_getman( floatx80 a ); ! 345: floatx80 floatx80_scale(floatx80 a, floatx80 b); ! 346: floatx80 floatx80_rem( floatx80 a, floatx80 b, bits64 *q, flag *s ); ! 347: floatx80 floatx80_mod( floatx80 a, floatx80 b, bits64 *q, flag *s ); ! 348: floatx80 floatx80_sglmul( floatx80 a, floatx80 b ); ! 349: floatx80 floatx80_sgldiv( floatx80 a, floatx80 b ); ! 350: floatx80 floatx80_cmp( floatx80 a, floatx80 b ); ! 351: floatx80 floatx80_tst( floatx80 a ); ! 352: ! 353: // functions are in softfloat_fpsp.c ! 354: floatx80 floatx80_acos(floatx80 a); ! 355: floatx80 floatx80_asin(floatx80 a); ! 356: floatx80 floatx80_atan(floatx80 a); ! 357: floatx80 floatx80_atanh(floatx80 a); ! 358: floatx80 floatx80_cos(floatx80 a); ! 359: floatx80 floatx80_cosh(floatx80 a); ! 360: floatx80 floatx80_etox(floatx80 a); ! 361: floatx80 floatx80_etoxm1(floatx80 a); ! 362: floatx80 floatx80_log10(floatx80 a); ! 363: floatx80 floatx80_log2(floatx80 a); ! 364: floatx80 floatx80_logn(floatx80 a); ! 365: floatx80 floatx80_lognp1(floatx80 a); ! 366: floatx80 floatx80_sin(floatx80 a); ! 367: floatx80 floatx80_sinh(floatx80 a); ! 368: floatx80 floatx80_tan(floatx80 a); ! 369: floatx80 floatx80_tanh(floatx80 a); ! 370: floatx80 floatx80_tentox(floatx80 a); ! 371: floatx80 floatx80_twotox(floatx80 a); ! 372: #endif ! 373: ! 374: // functions originally internal to softfloat.c ! 375: void normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr ); ! 376: floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig ); ! 377: floatx80 roundAndPackFloatx80(int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1); ! 378: ! 379: // functions are in softfloat-specialize.h ! 380: floatx80 propagateFloatx80NaNOneArg( floatx80 a ); ! 381: floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ); ! 382: ! 383: #endif ! 384: ! 385: #ifdef FLOAT128 ! 386: ! 387: /*---------------------------------------------------------------------------- ! 388: | Software IEC/IEEE quadruple-precision conversion routines. ! 389: *----------------------------------------------------------------------------*/ ! 390: int32 float128_to_int32( float128 ); ! 391: int32 float128_to_int32_round_to_zero( float128 ); ! 392: int64 float128_to_int64( float128 ); ! 393: int64 float128_to_int64_round_to_zero( float128 ); ! 394: float32 float128_to_float32( float128 ); ! 395: float64 float128_to_float64( float128 ); ! 396: #ifdef FLOATX80 ! 397: floatx80 float128_to_floatx80( float128 ); ! 398: #endif ! 399: ! 400: /*---------------------------------------------------------------------------- ! 401: | Software IEC/IEEE quadruple-precision operations. ! 402: *----------------------------------------------------------------------------*/ ! 403: float128 float128_round_to_int( float128 ); ! 404: float128 float128_add( float128, float128 ); ! 405: float128 float128_sub( float128, float128 ); ! 406: float128 float128_mul( float128, float128 ); ! 407: float128 float128_div( float128, float128 ); ! 408: float128 float128_rem( float128, float128 ); ! 409: float128 float128_sqrt( float128 ); ! 410: flag float128_eq( float128, float128 ); ! 411: flag float128_le( float128, float128 ); ! 412: flag float128_lt( float128, float128 ); ! 413: flag float128_eq_signaling( float128, float128 ); ! 414: flag float128_le_quiet( float128, float128 ); ! 415: flag float128_lt_quiet( float128, float128 ); ! 416: flag float128_is_signaling_nan( float128 ); ! 417: ! 418: // functions originally internal to softfloat.c ! 419: float128 packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ); ! 420: float128 roundAndPackFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 ); ! 421: float128 normalizeRoundAndPackFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ); ! 422: ! 423: #endif ! 424: ! 425: #endif //SOFTFLOAT_H
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.