| 139 | |
| 140 | template<bool gen_overflow=true, bool gen_underflow=true, bool round_even=true> |
| 141 | inline uint16_t FromDoubleBits(uint64_t d) |
| 142 | { |
| 143 | uint64_t d_exp, d_sig; |
| 144 | uint16_t h_sgn, h_exp, h_sig; |
| 145 | |
| 146 | h_sgn = (d&0x8000000000000000ULL) >> 48; |
| 147 | d_exp = (d&0x7ff0000000000000ULL); |
| 148 | |
| 149 | /* Exponent overflow/NaN converts to signed inf/NaN */ |
| 150 | if (d_exp >= 0x40f0000000000000ULL) { |
| 151 | if (d_exp == 0x7ff0000000000000ULL) { |
| 152 | /* Inf or NaN */ |
| 153 | d_sig = (d&0x000fffffffffffffULL); |
| 154 | if (d_sig != 0) { |
| 155 | /* NaN - propagate the flag in the significand... */ |
| 156 | uint16_t ret = (uint16_t) (0x7c00u + (d_sig >> 42)); |
| 157 | /* ...but make sure it stays a NaN */ |
| 158 | if (ret == 0x7c00u) { |
| 159 | ret++; |
| 160 | } |
| 161 | return h_sgn + ret; |
| 162 | } else { |
| 163 | /* signed inf */ |
| 164 | return h_sgn + 0x7c00u; |
| 165 | } |
| 166 | } else { |
| 167 | /* overflow to signed inf */ |
| 168 | if constexpr (gen_overflow) { |
| 169 | FloatStatus::RaiseOverflow(); |
| 170 | } |
| 171 | return h_sgn + 0x7c00u; |
| 172 | } |
| 173 | } |
| 174 | |
| 175 | /* Exponent underflow converts to subnormal half or signed zero */ |
| 176 | if (d_exp <= 0x3f00000000000000ULL) { |
| 177 | /* |
| 178 | * Signed zeros, subnormal floats, and floats with small |
| 179 | * exponents all convert to signed zero half-floats. |
| 180 | */ |
| 181 | if (d_exp < 0x3e60000000000000ULL) { |
| 182 | if constexpr (gen_underflow) { |
| 183 | /* If d != 0, it underflowed to 0 */ |
| 184 | if ((d&0x7fffffffffffffffULL) != 0) { |
| 185 | FloatStatus::RaiseUnderflow(); |
| 186 | } |
| 187 | } |
| 188 | return h_sgn; |
| 189 | } |
| 190 | /* Make the subnormal significand */ |
| 191 | d_exp >>= 52; |
| 192 | d_sig = (0x0010000000000000ULL + (d&0x000fffffffffffffULL)); |
| 193 | if constexpr (gen_underflow) { |
| 194 | /* If it's not exactly represented, it underflowed */ |
| 195 | if ((d_sig&(((uint64_t)1 << (1051 - d_exp)) - 1)) != 0) { |
| 196 | FloatStatus::RaiseUnderflow(); |
| 197 | } |
| 198 | } |
no outgoing calls
no test coverage detected