---------------------------------------------------------------------------- | Functions for storing sign, exponent and significand of extended | double-precision floating-point intermediate result for external use. *----------------------------------------------------------------------------*/
| 114 | | double-precision floating-point intermediate result for external use. |
| 115 | *----------------------------------------------------------------------------*/ |
| 116 | floatx80 roundSaveFloatx80Internal( int8_t roundingPrecision, flag zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status ) |
| 117 | { |
| 118 | uint64_t roundMask, roundBits; |
| 119 | uint64_t roundIncrement; |
| 120 | flag increment; |
| 121 | |
| 122 | if ( roundingPrecision == 80 ) { |
| 123 | goto precision80; |
| 124 | } else if ( roundingPrecision == 64 ) { |
| 125 | roundIncrement = LIT64( 0x0000000000000400 ); |
| 126 | roundMask = LIT64( 0x00000000000007FF ); |
| 127 | } else if ( roundingPrecision == 32 ) { |
| 128 | roundIncrement = LIT64( 0x0000008000000000 ); |
| 129 | roundMask = LIT64( 0x000000FFFFFFFFFF ); |
| 130 | } else { |
| 131 | goto precision80; |
| 132 | } |
| 133 | |
| 134 | zSig0 |= ( zSig1 != 0 ); |
| 135 | if ( status->float_rounding_mode != float_round_nearest_even ) { |
| 136 | if ( status->float_rounding_mode == float_round_to_zero ) { |
| 137 | roundIncrement = 0; |
| 138 | } else { |
| 139 | roundIncrement = roundMask; |
| 140 | if ( zSign ) { |
| 141 | if ( status->float_rounding_mode == float_round_up ) roundIncrement = 0; |
| 142 | } else { |
| 143 | if ( status->float_rounding_mode == float_round_down ) roundIncrement = 0; |
| 144 | } |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | roundBits = zSig0 & roundMask; |
| 149 | |
| 150 | zSig0 += roundIncrement; |
| 151 | if ( zSig0 < roundIncrement ) { |
| 152 | ++zExp; |
| 153 | zSig0 = LIT64( 0x8000000000000000 ); |
| 154 | } |
| 155 | roundIncrement = roundMask + 1; |
| 156 | if ( status->float_rounding_mode == float_round_nearest_even && ( roundBits<<1 == roundIncrement ) ) { |
| 157 | roundMask |= roundIncrement; |
| 158 | } |
| 159 | zSig0 &= ~ roundMask; |
| 160 | if ( zSig0 == 0 ) zExp = 0; |
| 161 | return packFloatx80( zSign, zExp, zSig0 ); |
| 162 | |
| 163 | precision80: |
| 164 | increment = ( (int64_t) zSig1 < 0 ); |
| 165 | if ( status->float_rounding_mode != float_round_nearest_even ) { |
| 166 | if ( status->float_rounding_mode == float_round_to_zero ) { |
| 167 | increment = 0; |
| 168 | } else { |
| 169 | if ( zSign ) { |
| 170 | increment = ( status->float_rounding_mode == float_round_down ) && zSig1; |
| 171 | } else { |
| 172 | increment = ( status->float_rounding_mode == float_round_up ) && zSig1; |
| 173 | } |
no test coverage detected