| 42 | #include "softfloat.h" |
| 43 | |
| 44 | extFloat80_t |
| 45 | extF80_roundToInt( extFloat80_t a, uint_fast8_t roundingMode, bool exact ) |
| 46 | { |
| 47 | union { struct extFloat80M s; extFloat80_t f; } uA; |
| 48 | uint_fast16_t uiA64, signUI64; |
| 49 | int_fast32_t exp; |
| 50 | uint_fast64_t sigA; |
| 51 | uint_fast16_t uiZ64; |
| 52 | uint_fast64_t sigZ; |
| 53 | struct exp32_sig64 normExpSig; |
| 54 | struct uint128 uiZ; |
| 55 | uint_fast64_t lastBitMask, roundBitsMask; |
| 56 | union { struct extFloat80M s; extFloat80_t f; } uZ; |
| 57 | |
| 58 | /*------------------------------------------------------------------------ |
| 59 | *------------------------------------------------------------------------*/ |
| 60 | uA.f = a; |
| 61 | uiA64 = uA.s.signExp; |
| 62 | signUI64 = uiA64 & packToExtF80UI64( 1, 0 ); |
| 63 | exp = expExtF80UI64( uiA64 ); |
| 64 | sigA = uA.s.signif; |
| 65 | /*------------------------------------------------------------------------ |
| 66 | *------------------------------------------------------------------------*/ |
| 67 | if ( !(sigA & UINT64_C( 0x8000000000000000 )) && (exp != 0x7FFF) ) { |
| 68 | if ( !sigA ) { |
| 69 | uiZ64 = signUI64; |
| 70 | sigZ = 0; |
| 71 | goto uiZ; |
| 72 | } |
| 73 | normExpSig = softfloat_normSubnormalExtF80Sig( sigA ); |
| 74 | exp += normExpSig.exp; |
| 75 | sigA = normExpSig.sig; |
| 76 | } |
| 77 | /*------------------------------------------------------------------------ |
| 78 | *------------------------------------------------------------------------*/ |
| 79 | if ( 0x403E <= exp ) { |
| 80 | if ( exp == 0x7FFF ) { |
| 81 | if ( sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { |
| 82 | uiZ = softfloat_propagateNaNExtF80UI( uiA64, sigA, 0, 0 ); |
| 83 | uiZ64 = (uint_fast16_t)uiZ.v64; |
| 84 | sigZ = uiZ.v0; |
| 85 | goto uiZ; |
| 86 | } |
| 87 | sigZ = UINT64_C( 0x8000000000000000 ); |
| 88 | } else { |
| 89 | sigZ = sigA; |
| 90 | } |
| 91 | uiZ64 = signUI64 | exp; |
| 92 | goto uiZ; |
| 93 | } |
| 94 | if ( exp <= 0x3FFE ) { |
| 95 | if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; |
| 96 | switch ( roundingMode ) { |
| 97 | case softfloat_round_near_even: |
| 98 | if ( !(sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) break; |
| 99 | case softfloat_round_near_maxMag: |
| 100 | if ( exp == 0x3FFE ) goto mag1; |
| 101 | break; |
no test coverage detected