Showing the changes to softfloat.c (1 of 5 files). Show all
Unified · Split
| @@ -40,12 +40,151 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. · 39 unmodified lines | |||
| 40 | #define UINT64_C(x) x##ULL | 40 | #define UINT64_C(x) x##ULL |
| 41 | #endif | 41 | #endif |
| 42 | 42 | ||
| 43 | #if BYTE_ORDER == LITTLE_ENDIAN | ||
| 44 | struct uint128 { u64int v0, v64; }; | ||
| 45 | struct uint64_extra { u64int extra, v; }; | ||
| 46 | #define wordIncr 1 | ||
| 47 | #define indexWord( total, n ) (n) | ||
| 48 | #define indexWordHi( total ) ((total) - 1) | ||
| 49 | #define indexWordLo( total ) 0 | ||
| 50 | #define indexMultiword( total, m, n ) (n) | ||
| 51 | #define indexMultiwordHi( total, n ) ((total) - (n)) | ||
| 52 | #define indexMultiwordLo( total, n ) 0 | ||
| 53 | #define indexMultiwordHiBut( total, n ) (n) | ||
| 54 | #define indexMultiwordLoBut( total, n ) 0 | ||
| 55 | #else | ||
| 56 | struct uint128 { u64int v64, v0; }; | ||
| 57 | struct uint64_extra { u64int v, extra; }; | ||
| 58 | #define wordIncr -1 | ||
| 59 | #define indexWord( total, n ) ((total) - 1 - (n)) | ||
| 60 | #define indexWordHi( total ) 0 | ||
| 61 | #define indexWordLo( total ) ((total) - 1) | ||
| 62 | #define indexMultiword( total, m, n ) ((total) - 1 - (m)) | ||
| 63 | #define indexMultiwordHi( total, n ) 0 | ||
| 64 | #define indexMultiwordLo( total, n ) ((total) - (n)) | ||
| 65 | #define indexMultiwordHiBut( total, n ) 0 | ||
| 66 | #define indexMultiwordLoBut( total, n ) (n) | ||
| 67 | #endif | ||
| 68 | |||
| 69 | /*---------------------------------------------------------------------------- | ||
| 70 | | Default value for 'softfloat_detectTininess'. | ||
| 71 | *----------------------------------------------------------------------------*/ | ||
| 72 | #define init_detectTininess softfloat_tininess_afterRounding | ||
| 73 | |||
| 74 | /*---------------------------------------------------------------------------- | ||
| 75 | | "Common NaN" structure, used to transfer NaN representations from one format | ||
| 76 | | to another. | ||
| 77 | *----------------------------------------------------------------------------*/ | ||
| 78 | struct commonNaN { | ||
| 79 | bool sign; | ||
| 80 | #if BYTE_ORDER == LITTLE_ENDIAN | ||
| 81 | u64int v0, v64; | ||
| 82 | #else | ||
| 83 | u64int v64, v0; | ||
| 84 | #endif | ||
| 85 | }; | ||
| 86 | |||
| 87 | union ui32_f32 { u32int ui; float32_t f; }; | ||
| 88 | |||
| 89 | enum { | ||
| 90 | softfloat_mulAdd_subC = 1, | ||
| 91 | softfloat_mulAdd_subProd = 2 | ||
| 92 | }; | ||
| 93 | |||
| 94 | |||
| 95 | /*---------------------------------------------------------------------------- | ||
| 96 | | Software floating-point underflow tininess-detection mode. | ||
| 97 | *----------------------------------------------------------------------------*/ | ||
| 98 | enum { | ||
| 99 | softfloat_tininess_beforeRounding = 0, | ||
| 100 | softfloat_tininess_afterRounding = 1 | ||
| 101 | }; | ||
| 102 | |||
| 103 | /*---------------------------------------------------------------------------- | ||
| 104 | | Software floating-point rounding mode. (Mode "odd" is supported only if | ||
| 105 | | SoftFloat is compiled with macro 'SOFTFLOAT_ROUND_ODD' defined.) | ||
| 106 | *----------------------------------------------------------------------------*/ | ||
| 107 | enum { | ||
| 108 | softfloat_round_near_even = 0, | ||
| 109 | softfloat_round_minMag = 1, | ||
| 110 | softfloat_round_min = 2, | ||
| 111 | softfloat_round_max = 3, | ||
| 112 | softfloat_round_near_maxMag = 4, | ||
| 113 | softfloat_round_odd = 6 | ||
| 114 | }; | ||
| 115 | |||
| 116 | /*---------------------------------------------------------------------------- | ||
| 117 | | Software floating-point exception flags. | ||
| 118 | *----------------------------------------------------------------------------*/ | ||
| 119 | typedef enum { | ||
| 120 | softfloat_flag_inexact = 1, | ||
| 121 | softfloat_flag_underflow = 2, | ||
| 122 | softfloat_flag_overflow = 4, | ||
| 123 | softfloat_flag_infinite = 8, | ||
| 124 | softfloat_flag_invalid = 16 | ||
| 125 | } exceptionFlag_t; | ||
| 126 | |||
| 127 | /*---------------------------------------------------------------------------- | ||
| 128 | | Returns true when 32-bit unsigned integer 'uiA' has the bit pattern of a | ||
| 129 | | 32-bit floating-point signaling NaN. | ||
| 130 | | Note: This macro evaluates its argument more than once. | ||
| 131 | *----------------------------------------------------------------------------*/ | ||
| 132 | #define softfloat_isSigNaNF32UI( uiA ) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF)) | ||
| 133 | |||
| 134 | /*---------------------------------------------------------------------------- | ||
| 135 | | The bit pattern for a default generated 80-bit extended floating-point NaN. | ||
| 136 | *----------------------------------------------------------------------------*/ | ||
| 137 | #define defaultNaNExtF80UI64 0xFFFF | ||
| 138 | #define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 ) | ||
| 139 | |||
| 140 | /*---------------------------------------------------------------------------- | ||
| 141 | | Returns true when the 80-bit unsigned integer formed from concatenating | ||
| 142 | | 16-bit 'uiA64' and 64-bit 'uiA0' has the bit pattern of an 80-bit extended | ||
| 143 | | floating-point signaling NaN. | ||
| 144 | | Note: This macro evaluates its arguments more than once. | ||
| 145 | *----------------------------------------------------------------------------*/ | ||
| 146 | #define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF ))) | ||
| 147 | |||
| 148 | #define signF32UI( a ) ((bool) ((u32int) (a)>>31)) | ||
| 149 | #define expF32UI( a ) ((s16int) ((a)>>23) & 0xFF) | ||
| 150 | #define fracF32UI( a ) ((a) & 0x007FFFFF) | ||
| 151 | #define packToF32UI( sign, exp, sig ) (((u32int) (sign)<<31) + ((u32int) (exp)<<23) + (sig)) | ||
| 152 | |||
| 153 | #define isNaNF32UI( a ) (((~(a) & 0x7F800000) == 0) && ((a) & 0x007FFFFF)) | ||
| 154 | |||
| 155 | struct exp16_sig32 { s16int exp; u32int sig; }; | ||
| 156 | |||
| 157 | static struct exp16_sig32 softfloat_normSubnormalF32Sig( u32int ); | ||
| 158 | static float32_t softfloat_roundPackToF32( bool, s16int, u32int ); | ||
| 159 | |||
| 160 | #define signExtF80UI64( a64 ) ((bool) ((u16int) (a64)>>15)) | ||
| 161 | #define expExtF80UI64( a64 ) ((a64) & 0x7FFF) | ||
| 162 | #define packToExtF80UI64( sign, exp ) ((u16int) (sign)<<15 | (exp)) | ||
| 163 | |||
| 164 | #define isNaNExtF80UI( a64, a0 ) ((((a64) & 0x7FFF) == 0x7FFF) && ((a0) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) | ||
| 165 | |||
| 166 | struct exp32_sig64 { s32int exp; u64int sig; }; | ||
| 167 | |||
| 168 | #define signF128UI64( a64 ) ((bool) ((u64int) (a64)>>63)) | ||
| 169 | #define expF128UI64( a64 ) ((s32int) ((a64)>>48) & 0x7FFF) | ||
| 170 | #define fracF128UI64( a64 ) ((a64) & UINT64_C( 0x0000FFFFFFFFFFFF )) | ||
| 171 | #define packToF128UI64( sign, exp, sig64 ) (((u64int) (sign)<<63) + ((u64int) (exp)<<48) + (sig64)) | ||
| 172 | |||
| 173 | #define isNaNF128UI( a64, a0 ) (((~(a64) & UINT64_C( 0x7FFF000000000000 )) == 0) && (a0 || ((a64) & UINT64_C( 0x0000FFFFFFFFFFFF )))) | ||
| 174 | |||
| 175 | struct exp32_sig128 { s32int exp; struct uint128 sig; }; | ||
| 176 | |||
| 177 | /*---------------------------------------------------------------------------- | ||
| 178 | | Routine to raise any or all of the software floating-point exception flags. | ||
| 179 | *----------------------------------------------------------------------------*/ | ||
| 180 | static void softfloat_raiseFlags( u8int ); | ||
| 181 | |||
| 43 | u8int softfloat_roundingMode = softfloat_round_near_even; | 182 | u8int softfloat_roundingMode = softfloat_round_near_even; |
| 44 | u8int softfloat_detectTininess = init_detectTininess; | 183 | u8int softfloat_detectTininess = init_detectTininess; |
| 45 | u8int softfloat_exceptionFlags = 0; | 184 | u8int softfloat_exceptionFlags = 0; |
| 46 | u8int extF80_roundingPrecision = 80; | 185 | u8int extF80_roundingPrecision = 80; |
| 47 | 186 | ||
| 48 | bool | 187 | static bool |
| 49 | extF80M_isSignalingNaN( const extFloat80_t *aPtr ) | 188 | extF80M_isSignalingNaN( const extFloat80_t *aPtr ) |
| 50 | { | 189 | { |
| 51 | const struct extFloat80M *aSPtr; | 190 | const struct extFloat80M *aSPtr; |
| @@ -65,7 +204,7 @@ extF80M_isSignalingNaN( const extFloat80_t *aPtr ) · 13 unmodified lines | |||
| 65 | | floating-point NaN, and stores this NaN at the location pointed to by | 204 | | floating-point NaN, and stores this NaN at the location pointed to by |
| 66 | | `zSPtr'. | 205 | | `zSPtr'. |
| 67 | *----------------------------------------------------------------------------*/ | 206 | *----------------------------------------------------------------------------*/ |
| 68 | void | 207 | static void |
| 69 | softfloat_commonNaNToExtF80M(const struct commonNaN *aPtr, struct extFloat80M *zSPtr ) | 208 | softfloat_commonNaNToExtF80M(const struct commonNaN *aPtr, struct extFloat80M *zSPtr ) |
| 70 | { | 209 | { |
| 71 | 210 | ||
| @@ -78,7 +217,7 @@ softfloat_commonNaNToExtF80M(const struct commonNaN *aPtr, struct extFloat80M *z · 6 unmodified lines | |||
| 78 | | Converts the common NaN pointed to by `aPtr' into a 32-bit floating-point | 217 | | Converts the common NaN pointed to by `aPtr' into a 32-bit floating-point |
| 79 | | NaN, and returns the bit pattern of this value as an unsigned integer. | 218 | | NaN, and returns the bit pattern of this value as an unsigned integer. |
| 80 | *----------------------------------------------------------------------------*/ | 219 | *----------------------------------------------------------------------------*/ |
| 81 | u32int | 220 | static u32int |
| 82 | softfloat_commonNaNToF32UI( const struct commonNaN *aPtr ) | 221 | softfloat_commonNaNToF32UI( const struct commonNaN *aPtr ) |
| 83 | { | 222 | { |
| 84 | 223 | ||
| @@ -92,7 +231,7 @@ softfloat_commonNaNToF32UI( const struct commonNaN *aPtr ) · 7 unmodified lines | |||
| 92 | | common NaN at the location pointed to by `zPtr'. If the NaN is a signaling | 231 | | common NaN at the location pointed to by `zPtr'. If the NaN is a signaling |
| 93 | | NaN, the invalid exception is raised. | 232 | | NaN, the invalid exception is raised. |
| 94 | *----------------------------------------------------------------------------*/ | 233 | *----------------------------------------------------------------------------*/ |
| 95 | void | 234 | static void |
| 96 | softfloat_extF80MToCommonNaN(const struct extFloat80M *aSPtr, struct commonNaN *zPtr ) | 235 | softfloat_extF80MToCommonNaN(const struct extFloat80M *aSPtr, struct commonNaN *zPtr ) |
| 97 | { | 236 | { |
| 98 | 237 | ||
| @@ -111,7 +250,7 @@ softfloat_extF80MToCommonNaN(const struct extFloat80M *aSPtr, struct commonNaN * · 12 unmodified lines | |||
| 111 | | location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid | 250 | | location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid |
| 112 | | exception is raised. | 251 | | exception is raised. |
| 113 | *----------------------------------------------------------------------------*/ | 252 | *----------------------------------------------------------------------------*/ |
| 114 | void | 253 | static void |
| 115 | softfloat_f32UIToCommonNaN( u32int uiA, struct commonNaN *zPtr ) | 254 | softfloat_f32UIToCommonNaN( u32int uiA, struct commonNaN *zPtr ) |
| 116 | { | 255 | { |
| 117 | 256 | ||
| @@ -130,7 +269,7 @@ softfloat_f32UIToCommonNaN( u32int uiA, struct commonNaN *zPtr ) · 12 unmodified lines | |||
| 130 | | at the location pointed to by `zSPtr'. If either original floating-point | 269 | | at the location pointed to by `zSPtr'. If either original floating-point |
| 131 | | value is a signaling NaN, the invalid exception is raised. | 270 | | value is a signaling NaN, the invalid exception is raised. |
| 132 | *----------------------------------------------------------------------------*/ | 271 | *----------------------------------------------------------------------------*/ |
| 133 | void | 272 | static void |
| 134 | softfloat_propagateNaNExtF80M( | 273 | softfloat_propagateNaNExtF80M( |
| 135 | const struct extFloat80M *aSPtr, | 274 | const struct extFloat80M *aSPtr, |
| 136 | const struct extFloat80M *bSPtr, | 275 | const struct extFloat80M *bSPtr, |
| @@ -197,7 +336,7 @@ softfloat_propagateNaNExtF80M( · 60 unmodified lines | |||
| 197 | | result. If either original floating-point value is a signaling NaN, the | 336 | | result. If either original floating-point value is a signaling NaN, the |
| 198 | | invalid exception is raised. | 337 | | invalid exception is raised. |
| 199 | *----------------------------------------------------------------------------*/ | 338 | *----------------------------------------------------------------------------*/ |
| 200 | struct uint128 | 339 | static struct uint128 |
| 201 | softfloat_propagateNaNExtF80UI( | 340 | softfloat_propagateNaNExtF80UI( |
| 202 | u16int uiA64, | 341 | u16int uiA64, |
| 203 | u64int uiA0, | 342 | u64int uiA0, |
| @@ -257,20 +396,16 @@ struct uint128 · 53 unmodified lines | |||
| 257 | | to substitute a result value. If traps are not implemented, this routine | 396 | | to substitute a result value. If traps are not implemented, this routine |
| 258 | | should be simply `softfloat_exceptionFlags |= flags;'. | 397 | | should be simply `softfloat_exceptionFlags |= flags;'. |
| 259 | *----------------------------------------------------------------------------*/ | 398 | *----------------------------------------------------------------------------*/ |
| 260 | void | 399 | static void |
| 261 | softfloat_raiseFlags( u8int flags ) | 400 | softfloat_raiseFlags( u8int flags ) |
| 262 | { | 401 | { |
| 263 | |||
| 264 | softfloat_exceptionFlags |= flags; | 402 | softfloat_exceptionFlags |= flags; |
| 265 | |||
| 266 | } | 403 | } |
| 267 | 404 | ||
| 268 | u64int | 405 | static u64int |
| 269 | softfloat_shortShiftRightJam64( u64int a, u8int dist ) | 406 | softfloat_shortShiftRightJam64( u64int a, u8int dist ) |
| 270 | { | 407 | { |
| 271 | |||
| 272 | return a>>dist | ((a & (((u64int) 1<<dist) - 1)) != 0); | 408 | return a>>dist | ((a & (((u64int) 1<<dist) - 1)) != 0); |
| 273 | |||
| 274 | } | 409 | } |
| 275 | 410 | ||
| 276 | /*---------------------------------------------------------------------------- | 411 | /*---------------------------------------------------------------------------- |
| @@ -297,7 +432,7 @@ static const u8int softfloat_countLeadingZeros8[256] = { · 20 unmodified lines | |||
| 297 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | 432 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
| 298 | }; | 433 | }; |
| 299 | 434 | ||
| 300 | u8int | 435 | static u8int |
| 301 | softfloat_countLeadingZeros64( u64int a ) | 436 | softfloat_countLeadingZeros64( u64int a ) |
| 302 | { | 437 | { |
| 303 | u8int count; | 438 | u8int count; |
| @@ -325,7 +460,7 @@ softfloat_countLeadingZeros64( u64int a ) · 21 unmodified lines | |||
| 325 | 460 | ||
| 326 | } | 461 | } |
| 327 | 462 | ||
| 328 | int | 463 | static int |
| 329 | softfloat_normExtF80SigM( u64int *sigPtr ) | 464 | softfloat_normExtF80SigM( u64int *sigPtr ) |
| 330 | { | 465 | { |
| 331 | u64int sig; | 466 | u64int sig; |
| @@ -338,7 +473,7 @@ softfloat_normExtF80SigM( u64int *sigPtr ) · 6 unmodified lines | |||
| 338 | 473 | ||
| 339 | } | 474 | } |
| 340 | 475 | ||
| 341 | u8int | 476 | static u8int |
| 342 | softfloat_countLeadingZeros32( u32int a ) | 477 | softfloat_countLeadingZeros32( u32int a ) |
| 343 | { | 478 | { |
| 344 | u8int count; | 479 | u8int count; |
| @@ -357,7 +492,7 @@ softfloat_countLeadingZeros32( u32int a ) · 12 unmodified lines | |||
| 357 | 492 | ||
| 358 | } | 493 | } |
| 359 | 494 | ||
| 360 | struct exp16_sig32 | 495 | static struct exp16_sig32 |
| 361 | softfloat_normSubnormalF32Sig( u32int sig ) | 496 | softfloat_normSubnormalF32Sig( u32int sig ) |
| 362 | { | 497 | { |
| 363 | s8int shiftDist; | 498 | s8int shiftDist; |
| @@ -370,7 +505,7 @@ softfloat_normSubnormalF32Sig( u32int sig ) · 6 unmodified lines | |||
| 370 | 505 | ||
| 371 | } | 506 | } |
| 372 | 507 | ||
| 373 | u32int | 508 | static u32int |
| 374 | softfloat_shiftRightJam32( u32int a, u16int dist ) | 509 | softfloat_shiftRightJam32( u32int a, u16int dist ) |
| 375 | { | 510 | { |
| 376 | 511 | ||
| @@ -379,7 +514,7 @@ softfloat_shiftRightJam32( u32int a, u16int dist ) · 2 unmodified lines | |||
| 379 | 514 | ||
| 380 | } | 515 | } |
| 381 | 516 | ||
| 382 | float32_t | 517 | static float32_t |
| 383 | softfloat_roundPackToF32( bool sign, s16int exp, u32int sig ) | 518 | softfloat_roundPackToF32( bool sign, s16int exp, u32int sig ) |
| 384 | { | 519 | { |
| 385 | u8int roundingMode; | 520 | u8int roundingMode; |
| @@ -431,18 +566,11 @@ float32_t · 45 unmodified lines | |||
| 431 | sig = (sig + roundIncrement)>>7; | 566 | sig = (sig + roundIncrement)>>7; |
| 432 | if ( roundBits ) { | 567 | if ( roundBits ) { |
| 433 | softfloat_exceptionFlags |= softfloat_flag_inexact; | 568 | softfloat_exceptionFlags |= softfloat_flag_inexact; |
| 434 | #ifdef SOFTFLOAT_ROUND_ODD | ||
| 435 | if ( roundingMode == softfloat_round_odd ) { | ||
| 436 | sig |= 1; | ||
| 437 | goto packReturn; | ||
| 438 | } | ||
| 439 | #endif | ||
| 440 | } | 569 | } |
| 441 | sig &= ~(u32int) (! (roundBits ^ 0x40) & roundNearEven); | 570 | sig &= ~(u32int) (! (roundBits ^ 0x40) & roundNearEven); |
| 442 | if ( ! sig ) exp = 0; | 571 | if ( ! sig ) exp = 0; |
| 443 | /*------------------------------------------------------------------------ | 572 | /*------------------------------------------------------------------------ |
| 444 | *------------------------------------------------------------------------*/ | 573 | *------------------------------------------------------------------------*/ |
| 445 | packReturn: | ||
| 446 | uiZ = packToF32UI( sign, exp, sig ); | 574 | uiZ = packToF32UI( sign, exp, sig ); |
| 447 | uiZ: | 575 | uiZ: |
| 448 | uZ.ui = uiZ; | 576 | uZ.ui = uiZ; |
| @@ -450,120 +578,7 @@ float32_t · 1 unmodified line | |||
| 450 | 578 | ||
| 451 | } | 579 | } |
| 452 | 580 | ||
| 453 | void | 581 | static struct uint64_extra |
| 454 | f32_to_extF80M( float32_t a, extFloat80_t *zPtr ) | ||
| 455 | { | ||
| 456 | struct extFloat80M *zSPtr; | ||
| 457 | union ui32_f32 uA; | ||
| 458 | u32int uiA; | ||
| 459 | bool sign; | ||
| 460 | s16int exp; | ||
| 461 | u32int frac; | ||
| 462 | struct commonNaN commonNaN; | ||
| 463 | u16int uiZ64; | ||
| 464 | u32int uiZ32; | ||
| 465 | struct exp16_sig32 normExpSig; | ||
| 466 | |||
| 467 | /*------------------------------------------------------------------------ | ||
| 468 | *------------------------------------------------------------------------*/ | ||
| 469 | zSPtr = (struct extFloat80M *) zPtr; | ||
| 470 | uA.f = a; | ||
| 471 | uiA = uA.ui; | ||
| 472 | sign = signF32UI( uiA ); | ||
| 473 | exp = expF32UI( uiA ); | ||
| 474 | frac = fracF32UI( uiA ); | ||
| 475 | /*------------------------------------------------------------------------ | ||
| 476 | *------------------------------------------------------------------------*/ | ||
| 477 | if ( exp == 0xFF ) { | ||
| 478 | if ( frac ) { | ||
| 479 | softfloat_f32UIToCommonNaN( uiA, &commonNaN ); | ||
| 480 | softfloat_commonNaNToExtF80M( &commonNaN, zSPtr ); | ||
| 481 | return; | ||
| 482 | } | ||
| 483 | uiZ64 = packToExtF80UI64( sign, 0x7FFF ); | ||
| 484 | uiZ32 = 0x80000000; | ||
| 485 | goto uiZ; | ||
| 486 | } | ||
| 487 | /*------------------------------------------------------------------------ | ||
| 488 | *------------------------------------------------------------------------*/ | ||
| 489 | if ( ! exp ) { | ||
| 490 | if ( ! frac ) { | ||
| 491 | uiZ64 = packToExtF80UI64( sign, 0 ); | ||
| 492 | uiZ32 = 0; | ||
| 493 | goto uiZ; | ||
| 494 | } | ||
| 495 | normExpSig = softfloat_normSubnormalF32Sig( frac ); | ||
| 496 | exp = normExpSig.exp; | ||
| 497 | frac = normExpSig.sig; | ||
| 498 | } | ||
| 499 | /*------------------------------------------------------------------------ | ||
| 500 | *------------------------------------------------------------------------*/ | ||
| 501 | uiZ64 = packToExtF80UI64( sign, exp + 0x3F80 ); | ||
| 502 | uiZ32 = 0x80000000 | (u32int) frac<<8; | ||
| 503 | uiZ: | ||
| 504 | zSPtr->signExp = uiZ64; | ||
| 505 | zSPtr->signif = (u64int) uiZ32<<32; | ||
| 506 | |||
| 507 | } | ||
| 508 | |||
| 509 | float32_t | ||
| 510 | extF80M_to_f32( const extFloat80_t *aPtr ) | ||
| 511 | { | ||
| 512 | const struct extFloat80M *aSPtr; | ||
| 513 | u16int uiA64; | ||
| 514 | bool sign; | ||
| 515 | s32int exp; | ||
| 516 | u64int sig; | ||
| 517 | struct commonNaN commonNaN; | ||
| 518 | u32int uiZ, sig32; | ||
| 519 | union ui32_f32 uZ; | ||
| 520 | |||
| 521 | /*------------------------------------------------------------------------ | ||
| 522 | *------------------------------------------------------------------------*/ | ||
| 523 | aSPtr = (const struct extFloat80M *) aPtr; | ||
| 524 | /*------------------------------------------------------------------------ | ||
| 525 | *------------------------------------------------------------------------*/ | ||
| 526 | uiA64 = aSPtr->signExp; | ||
| 527 | sign = signExtF80UI64( uiA64 ); | ||
| 528 | exp = expExtF80UI64( uiA64 ); | ||
| 529 | sig = aSPtr->signif; | ||
| 530 | /*------------------------------------------------------------------------ | ||
| 531 | *------------------------------------------------------------------------*/ | ||
| 532 | if ( exp == 0x7FFF ) { | ||
| 533 | if ( sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { | ||
| 534 | softfloat_extF80MToCommonNaN( aSPtr, &commonNaN ); | ||
| 535 | uiZ = softfloat_commonNaNToF32UI( &commonNaN ); | ||
| 536 | } else { | ||
| 537 | uiZ = packToF32UI( sign, 0xFF, 0 ); | ||
| 538 | } | ||
| 539 | goto uiZ; | ||
| 540 | } | ||
| 541 | /*------------------------------------------------------------------------ | ||
| 542 | *------------------------------------------------------------------------*/ | ||
| 543 | if ( ! (sig & UINT64_C( 0x8000000000000000 )) ) { | ||
| 544 | if ( ! sig ) { | ||
| 545 | uiZ = packToF32UI( sign, 0, 0 ); | ||
| 546 | goto uiZ; | ||
| 547 | } | ||
| 548 | exp += softfloat_normExtF80SigM( &sig ); | ||
| 549 | } | ||
| 550 | /*------------------------------------------------------------------------ | ||
| 551 | *------------------------------------------------------------------------*/ | ||
| 552 | sig32 = softfloat_shortShiftRightJam64( sig, 33 ); | ||
| 553 | exp -= 0x3F81; | ||
| 554 | if ( sizeof (s16int) < sizeof (s32int) ) { | ||
| 555 | if ( exp < -0x1000 ) exp = -0x1000; | ||
| 556 | } | ||
| 557 | return softfloat_roundPackToF32( sign, exp, sig32 ); | ||
| 558 | /*------------------------------------------------------------------------ | ||
| 559 | *------------------------------------------------------------------------*/ | ||
| 560 | uiZ: | ||
| 561 | uZ.ui = uiZ; | ||
| 562 | return uZ.f; | ||
| 563 | |||
| 564 | } | ||
| 565 | |||
| 566 | struct uint64_extra | ||
| 567 | softfloat_shiftRightJam64Extra( | 582 | softfloat_shiftRightJam64Extra( |
| 568 | u64int a, u64int extra, u32int dist ) | 583 | u64int a, u64int extra, u32int dist ) |
| 569 | { | 584 | { |
| @@ -581,7 +596,7 @@ struct uint64_extra · 11 unmodified lines | |||
| 581 | 596 | ||
| 582 | } | 597 | } |
| 583 | 598 | ||
| 584 | struct uint128 | 599 | static struct uint128 |
| 585 | softfloat_shiftRightJam128( u64int a64, u64int a0, u32int dist ) | 600 | softfloat_shiftRightJam128( u64int a64, u64int a0, u32int dist ) |
| 586 | { | 601 | { |
| 587 | u8int u8NegDist; | 602 | u8int u8NegDist; |
| @@ -606,7 +621,7 @@ struct uint128 · 18 unmodified lines | |||
| 606 | 621 | ||
| 607 | } | 622 | } |
| 608 | 623 | ||
| 609 | struct uint64_extra | 624 | static struct uint64_extra |
| 610 | softfloat_shortShiftRightJam64Extra( | 625 | softfloat_shortShiftRightJam64Extra( |
| 611 | u64int a, u64int extra, u8int dist ) | 626 | u64int a, u64int extra, u8int dist ) |
| 612 | { | 627 | { |
| @@ -618,7 +633,7 @@ struct uint64_extra · 5 unmodified lines | |||
| 618 | 633 | ||
| 619 | } | 634 | } |
| 620 | 635 | ||
| 621 | struct exp32_sig64 | 636 | static struct exp32_sig64 |
| 622 | softfloat_normSubnormalExtF80Sig( u64int sig ) | 637 | softfloat_normSubnormalExtF80Sig( u64int sig ) |
| 623 | { | 638 | { |
| 624 | s8int shiftDist; | 639 | s8int shiftDist; |
| @@ -631,7 +646,7 @@ softfloat_normSubnormalExtF80Sig( u64int sig ) · 6 unmodified lines | |||
| 631 | 646 | ||
| 632 | } | 647 | } |
| 633 | 648 | ||
| 634 | struct uint128 | 649 | static struct uint128 |
| 635 | softfloat_sub128( u64int a64, u64int a0, u64int b64, u64int b0 ) | 650 | softfloat_sub128( u64int a64, u64int a0, u64int b64, u64int b0 ) |
| 636 | { | 651 | { |
| 637 | struct uint128 z; | 652 | struct uint128 z; |
| @@ -642,7 +657,7 @@ struct uint128 · 4 unmodified lines | |||
| 642 | 657 | ||
| 643 | } | 658 | } |
| 644 | 659 | ||
| 645 | u64int | 660 | static u64int |
| 646 | softfloat_shiftRightJam64( u64int a, u32int dist ) | 661 | softfloat_shiftRightJam64( u64int a, u32int dist ) |
| 647 | { | 662 | { |
| 648 | return | 663 | return |
| @@ -650,7 +665,7 @@ softfloat_shiftRightJam64( u64int a, u32int dist ) · 1 unmodified line | |||
| 650 | 665 | ||
| 651 | } | 666 | } |
| 652 | 667 | ||
| 653 | struct uint128 | 668 | static struct uint128 |
| 654 | softfloat_shortShiftLeft128( u64int a64, u64int a0, u8int dist ) | 669 | softfloat_shortShiftLeft128( u64int a64, u64int a0, u8int dist ) |
| 655 | { | 670 | { |
| 656 | struct uint128 z; | 671 | struct uint128 z; |
| @@ -661,37 +676,7 @@ struct uint128 · 4 unmodified lines | |||
| 661 | 676 | ||
| 662 | } | 677 | } |
| 663 | 678 | ||
| 664 | extFloat80_t | 679 | static extFloat80_t |
| 665 | softfloat_normRoundPackToExtF80( | ||
| 666 | bool sign, | ||
| 667 | s32int exp, | ||
| 668 | u64int sig, | ||
| 669 | u64int sigExtra, | ||
| 670 | u8int roundingPrecision | ||
| 671 | ) | ||
| 672 | { | ||
| 673 | s8int shiftDist; | ||
| 674 | struct uint128 sig128; | ||
| 675 | |||
| 676 | if ( ! sig ) { | ||
| 677 | exp -= 64; | ||
| 678 | sig = sigExtra; | ||
| 679 | sigExtra = 0; | ||
| 680 | } | ||
| 681 | shiftDist = softfloat_countLeadingZeros64( sig ); | ||
| 682 | exp -= shiftDist; | ||
| 683 | if ( shiftDist ) { | ||
| 684 | sig128 = softfloat_shortShiftLeft128( sig, sigExtra, shiftDist ); | ||
| 685 | sig = sig128.v64; | ||
| 686 | sigExtra = sig128.v0; | ||
| 687 | } | ||
| 688 | return | ||
| 689 | softfloat_roundPackToExtF80( | ||
| 690 | sign, exp, sig, sigExtra, roundingPrecision ); | ||
| 691 | |||
| 692 | } | ||
| 693 | |||
| 694 | extFloat80_t | ||
| 695 | softfloat_roundPackToExtF80( | 680 | softfloat_roundPackToExtF80( |
| 696 | bool sign, | 681 | bool sign, |
| 697 | s32int exp, | 682 | s32int exp, |
| @@ -746,11 +731,6 @@ extFloat80_t · 48 unmodified lines | |||
| 746 | if ( roundBits ) { | 731 | if ( roundBits ) { |
| 747 | if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow ); | 732 | if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow ); |
| 748 | softfloat_exceptionFlags |= softfloat_flag_inexact; | 733 | softfloat_exceptionFlags |= softfloat_flag_inexact; |
| 749 | #ifdef SOFTFLOAT_ROUND_ODD | ||
| 750 | if ( roundingMode == softfloat_round_odd ) { | ||
| 751 | sig |= roundMask + 1; | ||
| 752 | } | ||
| 753 | #endif | ||
| 754 | } | 734 | } |
| 755 | sig += roundIncrement; | 735 | sig += roundIncrement; |
| 756 | exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0); | 736 | exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0); |
| @@ -772,12 +752,6 @@ extFloat80_t · 15 unmodified lines | |||
| 772 | *------------------------------------------------------------------------*/ | 752 | *------------------------------------------------------------------------*/ |
| 773 | if ( roundBits ) { | 753 | if ( roundBits ) { |
| 774 | softfloat_exceptionFlags |= softfloat_flag_inexact; | 754 | softfloat_exceptionFlags |= softfloat_flag_inexact; |
| 775 | #ifdef SOFTFLOAT_ROUND_ODD | ||
| 776 | if ( roundingMode == softfloat_round_odd ) { | ||
| 777 | sig = (sig & ~roundMask) | (roundMask + 1); | ||
| 778 | goto packReturn; | ||
| 779 | } | ||
| 780 | #endif | ||
| 781 | } | 755 | } |
| 782 | sig = (u64int) (sig + roundIncrement); | 756 | sig = (u64int) (sig + roundIncrement); |
| 783 | if ( sig < roundIncrement ) { | 757 | if ( sig < roundIncrement ) { |
| @@ -820,12 +794,6 @@ extFloat80_t · 36 unmodified lines | |||
| 820 | if ( sigExtra ) { | 794 | if ( sigExtra ) { |
| 821 | if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow ); | 795 | if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow ); |
| 822 | softfloat_exceptionFlags |= softfloat_flag_inexact; | 796 | softfloat_exceptionFlags |= softfloat_flag_inexact; |
| 823 | #ifdef SOFTFLOAT_ROUND_ODD | ||
| 824 | if ( roundingMode == softfloat_round_odd ) { | ||
| 825 | sig |= 1; | ||
| 826 | goto packReturn; | ||
| 827 | } | ||
| 828 | #endif | ||
| 829 | } | 797 | } |
| 830 | doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra); | 798 | doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra); |
| 831 | if ( | 799 | if ( |
| @@ -877,12 +845,6 @@ extFloat80_t · 45 unmodified lines | |||
| 877 | *------------------------------------------------------------------------*/ | 845 | *------------------------------------------------------------------------*/ |
| 878 | if ( sigExtra ) { | 846 | if ( sigExtra ) { |
| 879 | softfloat_exceptionFlags |= softfloat_flag_inexact; | 847 | softfloat_exceptionFlags |= softfloat_flag_inexact; |
| 880 | #ifdef SOFTFLOAT_ROUND_ODD | ||
| 881 | if ( roundingMode == softfloat_round_odd ) { | ||
| 882 | sig |= 1; | ||
| 883 | goto packReturn; | ||
| 884 | } | ||
| 885 | #endif | ||
| 886 | } | 848 | } |
| 887 | if ( doIncrement ) { | 849 | if ( doIncrement ) { |
| 888 | ++sig; | 850 | ++sig; |
| @@ -905,7 +867,37 @@ extFloat80_t · 16 unmodified lines | |||
| 905 | 867 | ||
| 906 | } | 868 | } |
| 907 | 869 | ||
| 908 | extFloat80_t | 870 | static extFloat80_t |
| 871 | softfloat_normRoundPackToExtF80( | ||
| 872 | bool sign, | ||
| 873 | s32int exp, | ||
| 874 | u64int sig, | ||
| 875 | u64int sigExtra, | ||
| 876 | u8int roundingPrecision | ||
| 877 | ) | ||
| 878 | { | ||
| 879 | s8int shiftDist; | ||
| 880 | struct uint128 sig128; | ||
| 881 | |||
| 882 | if ( ! sig ) { | ||
| 883 | exp -= 64; | ||
| 884 | sig = sigExtra; | ||
| 885 | sigExtra = 0; | ||
| 886 | } | ||
| 887 | shiftDist = softfloat_countLeadingZeros64( sig ); | ||
| 888 | exp -= shiftDist; | ||
| 889 | if ( shiftDist ) { | ||
| 890 | sig128 = softfloat_shortShiftLeft128( sig, sigExtra, shiftDist ); | ||
| 891 | sig = sig128.v64; | ||
| 892 | sigExtra = sig128.v0; | ||
| 893 | } | ||
| 894 | return | ||
| 895 | softfloat_roundPackToExtF80( | ||
| 896 | sign, exp, sig, sigExtra, roundingPrecision ); | ||
| 897 | |||
| 898 | } | ||
| 899 | |||
| 900 | static extFloat80_t | ||
| 909 | softfloat_subMagsExtF80( | 901 | softfloat_subMagsExtF80( |
| 910 | u16int uiA64, | 902 | u16int uiA64, |
| 911 | u64int uiA0, | 903 | u64int uiA0, |
| @@ -1020,7 +1012,7 @@ extFloat80_t · 108 unmodified lines | |||
| 1020 | 1012 | ||
| 1021 | } | 1013 | } |
| 1022 | 1014 | ||
| 1023 | extFloat80_t | 1015 | static extFloat80_t |
| 1024 | softfloat_addMagsExtF80( | 1016 | softfloat_addMagsExtF80( |
| 1025 | u16int uiA64, | 1017 | u16int uiA64, |
| 1026 | u64int uiA0, | 1018 | u64int uiA0, |
| @@ -1133,46 +1125,7 @@ extFloat80_t · 106 unmodified lines | |||
| 1133 | 1125 | ||
| 1134 | } | 1126 | } |
| 1135 | 1127 | ||
| 1136 | void | 1128 | static void |
| 1137 | extF80M_add( | ||
| 1138 | const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) | ||
| 1139 | { | ||
| 1140 | const struct extFloat80M *aSPtr, *bSPtr; | ||
| 1141 | u16int uiA64; | ||
| 1142 | u64int uiA0; | ||
| 1143 | bool signA; | ||
| 1144 | u16int uiB64; | ||
| 1145 | u64int uiB0; | ||
| 1146 | bool signB; | ||
| 1147 | #if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) | ||
| 1148 | extFloat80_t | ||
| 1149 | (*magsFuncPtr)( | ||
| 1150 | u16int, u64int, u16int, u64int, bool ); | ||
| 1151 | #endif | ||
| 1152 | |||
| 1153 | aSPtr = (const struct extFloat80M *) aPtr; | ||
| 1154 | bSPtr = (const struct extFloat80M *) bPtr; | ||
| 1155 | uiA64 = aSPtr->signExp; | ||
| 1156 | uiA0 = aSPtr->signif; | ||
| 1157 | signA = signExtF80UI64( uiA64 ); | ||
| 1158 | uiB64 = bSPtr->signExp; | ||
| 1159 | uiB0 = bSPtr->signif; | ||
| 1160 | signB = signExtF80UI64( uiB64 ); | ||
| 1161 | #if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) | ||
| 1162 | if ( signA == signB ) { | ||
| 1163 | *zPtr = softfloat_addMagsExtF80( uiA64, uiA0, uiB64, uiB0, signA ); | ||
| 1164 | } else { | ||
| 1165 | *zPtr = softfloat_subMagsExtF80( uiA64, uiA0, uiB64, uiB0, signA ); | ||
| 1166 | } | ||
| 1167 | #else | ||
| 1168 | magsFuncPtr = | ||
| 1169 | (signA == signB) ? softfloat_addMagsExtF80 : softfloat_subMagsExtF80; | ||
| 1170 | *zPtr = (*magsFuncPtr)( uiA64, uiA0, uiB64, uiB0, signA ); | ||
| 1171 | #endif | ||
| 1172 | |||
| 1173 | } | ||
| 1174 | |||
| 1175 | void | ||
| 1176 | softfloat_addM( | 1129 | softfloat_addM( |
| 1177 | u8int size_words, | 1130 | u8int size_words, |
| 1178 | const u32int *aPtr, | 1131 | const u32int *aPtr, |
| @@ -1204,7 +1157,7 @@ void · 25 unmodified lines | |||
| 1204 | *----------------------------------------------------------------------------*/ | 1157 | *----------------------------------------------------------------------------*/ |
| 1205 | #define softfloat_add96M( aPtr, bPtr, zPtr ) softfloat_addM( 3, aPtr, bPtr, zPtr ) | 1158 | #define softfloat_add96M( aPtr, bPtr, zPtr ) softfloat_addM( 3, aPtr, bPtr, zPtr ) |
| 1206 | 1159 | ||
| 1207 | void | 1160 | static void |
| 1208 | softfloat_mul64To128M( u64int a, u64int b, u32int *zPtr ) | 1161 | softfloat_mul64To128M( u64int a, u64int b, u32int *zPtr ) |
| 1209 | { | 1162 | { |
| 1210 | u32int a32, a0, b32, b0; | 1163 | u32int a32, a0, b32, b0; |
| @@ -1229,7 +1182,7 @@ softfloat_mul64To128M( u64int a, u64int b, u32int *zPtr ) · 18 unmodified lines | |||
| 1229 | 1182 | ||
| 1230 | } | 1183 | } |
| 1231 | 1184 | ||
| 1232 | void | 1185 | static void |
| 1233 | softfloat_invalidExtF80M( struct extFloat80M *zSPtr ) | 1186 | softfloat_invalidExtF80M( struct extFloat80M *zSPtr ) |
| 1234 | { | 1187 | { |
| 1235 | 1188 | ||
| @@ -1239,7 +1192,7 @@ softfloat_invalidExtF80M( struct extFloat80M *zSPtr ) · 3 unmodified lines | |||
| 1239 | 1192 | ||
| 1240 | } | 1193 | } |
| 1241 | 1194 | ||
| 1242 | bool | 1195 | static bool |
| 1243 | softfloat_tryPropagateNaNExtF80M( | 1196 | softfloat_tryPropagateNaNExtF80M( |
| 1244 | const struct extFloat80M *aSPtr, | 1197 | const struct extFloat80M *aSPtr, |
| 1245 | const struct extFloat80M *bSPtr, | 1198 | const struct extFloat80M *bSPtr, |
| @@ -1262,7 +1215,7 @@ bool · 16 unmodified lines | |||
| 1262 | 1215 | ||
| 1263 | } | 1216 | } |
| 1264 | 1217 | ||
| 1265 | void | 1218 | static void |
| 1266 | softfloat_shortShiftRightJamM( | 1219 | softfloat_shortShiftRightJamM( |
| 1267 | u8int size_words, | 1220 | u8int size_words, |
| 1268 | const u32int *aPtr, | 1221 | const u32int *aPtr, |
| @@ -1296,7 +1249,7 @@ void · 27 unmodified lines | |||
| 1296 | *----------------------------------------------------------------------------*/ | 1249 | *----------------------------------------------------------------------------*/ |
| 1297 | #define softfloat_shiftRightJam96M( aPtr, dist, zPtr ) softfloat_shiftRightJamM( 3, aPtr, dist, zPtr ) | 1250 | #define softfloat_shiftRightJam96M( aPtr, dist, zPtr ) softfloat_shiftRightJamM( 3, aPtr, dist, zPtr ) |
| 1298 | 1251 | ||
| 1299 | void | 1252 | static void |
| 1300 | softfloat_shiftRightJamM( | 1253 | softfloat_shiftRightJamM( |
| 1301 | u8int size_words, | 1254 | u8int size_words, |
| 1302 | const u32int *aPtr, | 1255 | const u32int *aPtr, |
| @@ -1352,7 +1305,7 @@ void · 49 unmodified lines | |||
| 1352 | 1305 | ||
| 1353 | } | 1306 | } |
| 1354 | 1307 | ||
| 1355 | void | 1308 | static void |
| 1356 | softfloat_roundPackMToExtF80M( | 1309 | softfloat_roundPackMToExtF80M( |
| 1357 | bool sign, | 1310 | bool sign, |
| 1358 | s32int exp, | 1311 | s32int exp, |
| @@ -1412,11 +1365,6 @@ void · 53 unmodified lines | |||
| 1412 | if ( roundBits ) { | 1365 | if ( roundBits ) { |
| 1413 | if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow ); | 1366 | if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow ); |
| 1414 | softfloat_exceptionFlags |= softfloat_flag_inexact; | 1367 | softfloat_exceptionFlags |= softfloat_flag_inexact; |
| 1415 | #ifdef SOFTFLOAT_ROUND_ODD | ||
| 1416 | if ( roundingMode == softfloat_round_odd ) { | ||
| 1417 | sig |= roundMask + 1; | ||
| 1418 | } | ||
| 1419 | #endif | ||
| 1420 | } | 1368 | } |
| 1421 | sig += roundIncrement; | 1369 | sig += roundIncrement; |
| 1422 | exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0); | 1370 | exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0); |
| @@ -1438,12 +1386,6 @@ void · 15 unmodified lines | |||
| 1438 | *------------------------------------------------------------------------*/ | 1386 | *------------------------------------------------------------------------*/ |
| 1439 | if ( roundBits ) { | 1387 | if ( roundBits ) { |
| 1440 | softfloat_exceptionFlags |= softfloat_flag_inexact; | 1388 | softfloat_exceptionFlags |= softfloat_flag_inexact; |
| 1441 | #ifdef SOFTFLOAT_ROUND_ODD | ||
| 1442 | if ( roundingMode == softfloat_round_odd ) { | ||
| 1443 | sig = (sig & ~roundMask) | (roundMask + 1); | ||
| 1444 | goto packReturn; | ||
| 1445 | } | ||
| 1446 | #endif | ||
| 1447 | } | 1389 | } |
| 1448 | sig += roundIncrement; | 1390 | sig += roundIncrement; |
| 1449 | if ( sig < roundIncrement ) { | 1391 | if ( sig < roundIncrement ) { |
| @@ -1488,12 +1430,6 @@ void · 38 unmodified lines | |||
| 1488 | if ( sigExtra ) { | 1430 | if ( sigExtra ) { |
| 1489 | if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow ); | 1431 | if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow ); |
| 1490 | softfloat_exceptionFlags |= softfloat_flag_inexact; | 1432 | softfloat_exceptionFlags |= softfloat_flag_inexact; |
| 1491 | #ifdef SOFTFLOAT_ROUND_ODD | ||
| 1492 | if ( roundingMode == softfloat_round_odd ) { | ||
| 1493 | sig |= 1; | ||
| 1494 | goto packReturn; | ||
| 1495 | } | ||
| 1496 | #endif | ||
| 1497 | } | 1433 | } |
| 1498 | doIncrement = (0x80000000 <= sigExtra); | 1434 | doIncrement = (0x80000000 <= sigExtra); |
| 1499 | if ( | 1435 | if ( |
| @@ -1542,12 +1478,6 @@ void · 42 unmodified lines | |||
| 1542 | *------------------------------------------------------------------------*/ | 1478 | *------------------------------------------------------------------------*/ |
| 1543 | if ( sigExtra ) { | 1479 | if ( sigExtra ) { |
| 1544 | softfloat_exceptionFlags |= softfloat_flag_inexact; | 1480 | softfloat_exceptionFlags |= softfloat_flag_inexact; |
| 1545 | #ifdef SOFTFLOAT_ROUND_ODD | ||
| 1546 | if ( roundingMode == softfloat_round_odd ) { | ||
| 1547 | sig |= 1; | ||
| 1548 | goto packReturn; | ||
| 1549 | } | ||
| 1550 | #endif | ||
| 1551 | } | 1481 | } |
| 1552 | if ( doIncrement ) { | 1482 | if ( doIncrement ) { |
| 1553 | ++sig; | 1483 | ++sig; |
| @@ -1566,6 +1496,146 @@ void · 12 unmodified lines | |||
| 1566 | 1496 | ||
| 1567 | } | 1497 | } |
| 1568 | 1498 | ||
| 1499 | void | ||
| 1500 | f32_to_extF80M( float32_t a, extFloat80_t *zPtr ) | ||
| 1501 | { | ||
| 1502 | struct extFloat80M *zSPtr; | ||
| 1503 | union ui32_f32 uA; | ||
| 1504 | u32int uiA; | ||
| 1505 | bool sign; | ||
| 1506 | s16int exp; | ||
| 1507 | u32int frac; | ||
| 1508 | struct commonNaN commonNaN; | ||
| 1509 | u16int uiZ64; | ||
| 1510 | u32int uiZ32; | ||
| 1511 | struct exp16_sig32 normExpSig; | ||
| 1512 | |||
| 1513 | /*------------------------------------------------------------------------ | ||
| 1514 | *------------------------------------------------------------------------*/ | ||
| 1515 | zSPtr = (struct extFloat80M *) zPtr; | ||
| 1516 | uA.f = a; | ||
| 1517 | uiA = uA.ui; | ||
| 1518 | sign = signF32UI( uiA ); | ||
| 1519 | exp = expF32UI( uiA ); | ||
| 1520 | frac = fracF32UI( uiA ); | ||
| 1521 | /*------------------------------------------------------------------------ | ||
| 1522 | *------------------------------------------------------------------------*/ | ||
| 1523 | if ( exp == 0xFF ) { | ||
| 1524 | if ( frac ) { | ||
| 1525 | softfloat_f32UIToCommonNaN( uiA, &commonNaN ); | ||
| 1526 | softfloat_commonNaNToExtF80M( &commonNaN, zSPtr ); | ||
| 1527 | return; | ||
| 1528 | } | ||
| 1529 | uiZ64 = packToExtF80UI64( sign, 0x7FFF ); | ||
| 1530 | uiZ32 = 0x80000000; | ||
| 1531 | goto uiZ; | ||
| 1532 | } | ||
| 1533 | /*------------------------------------------------------------------------ | ||
| 1534 | *------------------------------------------------------------------------*/ | ||
| 1535 | if ( ! exp ) { | ||
| 1536 | if ( ! frac ) { | ||
| 1537 | uiZ64 = packToExtF80UI64( sign, 0 ); | ||
| 1538 | uiZ32 = 0; | ||
| 1539 | goto uiZ; | ||
| 1540 | } | ||
| 1541 | normExpSig = softfloat_normSubnormalF32Sig( frac ); | ||
| 1542 | exp = normExpSig.exp; | ||
| 1543 | frac = normExpSig.sig; | ||
| 1544 | } | ||
| 1545 | /*------------------------------------------------------------------------ | ||
| 1546 | *------------------------------------------------------------------------*/ | ||
| 1547 | uiZ64 = packToExtF80UI64( sign, exp + 0x3F80 ); | ||
| 1548 | uiZ32 = 0x80000000 | (u32int) frac<<8; | ||
| 1549 | uiZ: | ||
| 1550 | zSPtr->signExp = uiZ64; | ||
| 1551 | zSPtr->signif = (u64int) uiZ32<<32; | ||
| 1552 | |||
| 1553 | } | ||
| 1554 | |||
| 1555 | float32_t | ||
| 1556 | extF80M_to_f32( const extFloat80_t *aPtr ) | ||
| 1557 | { | ||
| 1558 | const struct extFloat80M *aSPtr; | ||
| 1559 | u16int uiA64; | ||
| 1560 | bool sign; | ||
| 1561 | s32int exp; | ||
| 1562 | u64int sig; | ||
| 1563 | struct commonNaN commonNaN; | ||
| 1564 | u32int uiZ, sig32; | ||
| 1565 | union ui32_f32 uZ; | ||
| 1566 | |||
| 1567 | /*------------------------------------------------------------------------ | ||
| 1568 | *------------------------------------------------------------------------*/ | ||
| 1569 | aSPtr = (const struct extFloat80M *) aPtr; | ||
| 1570 | /*------------------------------------------------------------------------ | ||
| 1571 | *------------------------------------------------------------------------*/ | ||
| 1572 | uiA64 = aSPtr->signExp; | ||
| 1573 | sign = signExtF80UI64( uiA64 ); | ||
| 1574 | exp = expExtF80UI64( uiA64 ); | ||
| 1575 | sig = aSPtr->signif; | ||
| 1576 | /*------------------------------------------------------------------------ | ||
| 1577 | *------------------------------------------------------------------------*/ | ||
| 1578 | if ( exp == 0x7FFF ) { | ||
| 1579 | if ( sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { | ||
| 1580 | softfloat_extF80MToCommonNaN( aSPtr, &commonNaN ); | ||
| 1581 | uiZ = softfloat_commonNaNToF32UI( &commonNaN ); | ||
| 1582 | } else { | ||
| 1583 | uiZ = packToF32UI( sign, 0xFF, 0 ); | ||
| 1584 | } | ||
| 1585 | goto uiZ; | ||
| 1586 | } | ||
| 1587 | /*------------------------------------------------------------------------ | ||
| 1588 | *------------------------------------------------------------------------*/ | ||
| 1589 | if ( ! (sig & UINT64_C( 0x8000000000000000 )) ) { | ||
| 1590 | if ( ! sig ) { | ||
| 1591 | uiZ = packToF32UI( sign, 0, 0 ); | ||
| 1592 | goto uiZ; | ||
| 1593 | } | ||
| 1594 | exp += softfloat_normExtF80SigM( &sig ); | ||
| 1595 | } | ||
| 1596 | /*------------------------------------------------------------------------ | ||
| 1597 | *------------------------------------------------------------------------*/ | ||
| 1598 | sig32 = softfloat_shortShiftRightJam64( sig, 33 ); | ||
| 1599 | exp -= 0x3F81; | ||
| 1600 | if ( sizeof (s16int) < sizeof (s32int) ) { | ||
| 1601 | if ( exp < -0x1000 ) exp = -0x1000; | ||
| 1602 | } | ||
| 1603 | return softfloat_roundPackToF32( sign, exp, sig32 ); | ||
| 1604 | /*------------------------------------------------------------------------ | ||
| 1605 | *------------------------------------------------------------------------*/ | ||
| 1606 | uiZ: | ||
| 1607 | uZ.ui = uiZ; | ||
| 1608 | return uZ.f; | ||
| 1609 | |||
| 1610 | } | ||
| 1611 | |||
| 1612 | void | ||
| 1613 | extF80M_add( | ||
| 1614 | const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) | ||
| 1615 | { | ||
| 1616 | const struct extFloat80M *aSPtr, *bSPtr; | ||
| 1617 | u16int uiA64; | ||
| 1618 | u64int uiA0; | ||
| 1619 | bool signA; | ||
| 1620 | u16int uiB64; | ||
| 1621 | u64int uiB0; | ||
| 1622 | bool signB; | ||
| 1623 | |||
| 1624 | aSPtr = (const struct extFloat80M *) aPtr; | ||
| 1625 | bSPtr = (const struct extFloat80M *) bPtr; | ||
| 1626 | uiA64 = aSPtr->signExp; | ||
| 1627 | uiA0 = aSPtr->signif; | ||
| 1628 | signA = signExtF80UI64( uiA64 ); | ||
| 1629 | uiB64 = bSPtr->signExp; | ||
| 1630 | uiB0 = bSPtr->signif; | ||
| 1631 | signB = signExtF80UI64( uiB64 ); | ||
| 1632 | if ( signA == signB ) { | ||
| 1633 | *zPtr = softfloat_addMagsExtF80( uiA64, uiA0, uiB64, uiB0, signA ); | ||
| 1634 | } else { | ||
| 1635 | *zPtr = softfloat_subMagsExtF80( uiA64, uiA0, uiB64, uiB0, signA ); | ||
| 1636 | } | ||
| 1637 | } | ||
| 1638 | |||
| 1569 | void | 1639 | void |
| 1570 | extF80M_mul( | 1640 | extF80M_mul( |
| 1571 | const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) | 1641 | const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) |