| ... | ... | @@ -303,7 +303,7 @@ static void end_float_token(Tokenize *t) { |
| 303 | 303 | return; |
| 304 | 304 | } |
| 305 | 305 | |
| 306 | | if (!bigint_fits_in_bits(&t->specified_exponent, 64, true)) { |
| 306 | if (!bigint_fits_in_bits(&t->specified_exponent, 128, true)) { |
| 307 | 307 | t->cur_tok->data.float_lit.overflow = true; |
| 308 | 308 | return; |
| 309 | 309 | } |
| ... | ... | @@ -314,39 +314,52 @@ static void end_float_token(Tokenize *t) { |
| 314 | 314 | } |
| 315 | 315 | t->exponent_in_bin_or_dec = (int)(t->exponent_in_bin_or_dec + specified_exponent); |
| 316 | 316 | |
| 317 | | if (!bigint_fits_in_bits(&t->significand, 64, false)) { |
| 317 | if (!bigint_fits_in_bits(&t->significand, 128, false)) { |
| 318 | 318 | t->cur_tok->data.float_lit.overflow = true; |
| 319 | 319 | return; |
| 320 | 320 | } |
| 321 | 321 | |
| 322 | | uint64_t significand = bigint_as_unsigned(&t->significand); |
| 323 | | uint64_t significand_bits; |
| 324 | | uint64_t exponent_bits; |
| 325 | | if (significand == 0) { |
| 326 | | // 0 is all 0's |
| 327 | | significand_bits = 0; |
| 328 | | exponent_bits = 0; |
| 322 | // A SoftFloat-3d float128 is represented internally as a standard |
| 323 | // quad-precision float with 15bit exponent and 113bit fractional. |
| 324 | union { uint64_t repr[2]; float128_t actual; } f_bits; |
| 325 | |
| 326 | if (bigint_cmp_zero(&t->significand) == CmpEQ) { |
| 327 | f_bits.repr[0] = 0; |
| 328 | f_bits.repr[1] = 0; |
| 329 | 329 | } else { |
| 330 | 330 | // normalize the significand |
| 331 | 331 | if (t->radix == 10) { |
| 332 | 332 | zig_panic("TODO: decimal floats"); |
| 333 | 333 | } else { |
| 334 | | int significand_magnitude_in_bin = clzll(1) - clzll(significand); |
| 334 | int significand_magnitude_in_bin = 127 - bigint_clz(&t->significand, 128); |
| 335 | 335 | t->exponent_in_bin_or_dec += significand_magnitude_in_bin; |
| 336 | | if (!(-1022 <= t->exponent_in_bin_or_dec && t->exponent_in_bin_or_dec <= 1023)) { |
| 336 | if (!(-16382 <= t->exponent_in_bin_or_dec && t->exponent_in_bin_or_dec <= 16383)) { |
| 337 | 337 | t->cur_tok->data.float_lit.overflow = true; |
| 338 | 338 | return; |
| 339 | } |
| 340 | |
| 341 | uint64_t sig_bits[2] = {0, 0}; |
| 342 | bigint_write_twos_complement(&t->significand, (uint8_t*) sig_bits, 128, false); |
| 343 | |
| 344 | const uint64_t shift = 112 - significand_magnitude_in_bin; |
| 345 | const uint64_t exp_shift = 48; |
| 346 | // Mask the sign bit to 0 since always non-negative lex |
| 347 | const uint64_t exp_mask = 0xfffful << exp_shift; |
| 348 | |
| 349 | if (shift >= 64) { |
| 350 | f_bits.repr[0] = 0; |
| 351 | f_bits.repr[1] = sig_bits[0] << (shift - 64); |
| 339 | 352 | } else { |
| 340 | | // this should chop off exactly one 1 bit from the top. |
| 341 | | significand_bits = ((uint64_t)significand << (52 - significand_magnitude_in_bin)) & 0xfffffffffffffULL; |
| 342 | | exponent_bits = t->exponent_in_bin_or_dec + 1023; |
| 353 | f_bits.repr[0] = sig_bits[0] << shift; |
| 354 | f_bits.repr[1] = ((sig_bits[1] << shift) | (sig_bits[0] >> (64 - shift))); |
| 343 | 355 | } |
| 356 | |
| 357 | f_bits.repr[1] &= ~exp_mask; |
| 358 | f_bits.repr[1] |= (uint64_t)(t->exponent_in_bin_or_dec + 16383) << exp_shift; |
| 344 | 359 | } |
| 345 | 360 | } |
| 346 | | uint64_t double_bits = (exponent_bits << 52) | significand_bits; |
| 347 | | double dbl_value; |
| 348 | | safe_memcpy(&dbl_value, (double *)&double_bits, 1); |
| 349 | | bigfloat_init_64(&t->cur_tok->data.float_lit.bigfloat, dbl_value); |
| 361 | |
| 362 | bigfloat_init_128(&t->cur_tok->data.float_lit.bigfloat, f_bits.actual); |
| 350 | 363 | } |
| 351 | 364 | |
| 352 | 365 | static void end_token(Tokenize *t) { |