| ... | @@ -303,7 +303,7 @@ static void end_float_token(Tokenize *t) { | ... | @@ -303,7 +303,7 @@ static void end_float_token(Tokenize *t) { |
| 303 | return; | 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 | t->cur_tok->data.float_lit.overflow = true; | 307 | t->cur_tok->data.float_lit.overflow = true; |
| 308 | return; | 308 | return; |
| 309 | } | 309 | } |
| ... | @@ -314,39 +314,52 @@ static void end_float_token(Tokenize *t) { | ... | @@ -314,39 +314,52 @@ static void end_float_token(Tokenize *t) { |
| 314 | } | 314 | } |
| 315 | t->exponent_in_bin_or_dec = (int)(t->exponent_in_bin_or_dec + specified_exponent); | 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 | t->cur_tok->data.float_lit.overflow = true; | 318 | t->cur_tok->data.float_lit.overflow = true; |
| 319 | return; | 319 | return; |
| 320 | } | 320 | } |
| 321 | | 321 | |
| 322 | uint64_t significand = bigint_as_unsigned(&t->significand); | 322 | // A SoftFloat-3d float128 is represented internally as a standard |
| 323 | uint64_t significand_bits; | 323 | // quad-precision float with 15bit exponent and 113bit fractional. |
| 324 | uint64_t exponent_bits; | 324 | union { uint64_t repr[2]; float128_t actual; } f_bits; |
| 325 | if (significand == 0) { | 325 | |
| 326 | // 0 is all 0's | 326 | if (bigint_cmp_zero(&t->significand) == CmpEQ) { |
| 327 | significand_bits = 0; | 327 | f_bits.repr[0] = 0; |
| 328 | exponent_bits = 0; | 328 | f_bits.repr[1] = 0; |
| 329 | } else { | 329 | } else { |
| 330 | // normalize the significand | 330 | // normalize the significand |
| 331 | if (t->radix == 10) { | 331 | if (t->radix == 10) { |
| 332 | zig_panic("TODO: decimal floats"); | 332 | zig_panic("TODO: decimal floats"); |
| 333 | } else { | 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 | t->exponent_in_bin_or_dec += significand_magnitude_in_bin; | 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 | t->cur_tok->data.float_lit.overflow = true; | 337 | t->cur_tok->data.float_lit.overflow = true; |
| 338 | return; | 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 | } else { | 352 | } else { |
| 340 | // this should chop off exactly one 1 bit from the top. | 353 | f_bits.repr[0] = sig_bits[0] << shift; |
| 341 | significand_bits = ((uint64_t)significand << (52 - significand_magnitude_in_bin)) & 0xfffffffffffffULL; | 354 | f_bits.repr[1] = ((sig_bits[1] << shift) | (sig_bits[0] >> (64 - shift))); |
| 342 | exponent_bits = t->exponent_in_bin_or_dec + 1023; | | |
| 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; | 361 | |
| 347 | double dbl_value; | 362 | bigfloat_init_128(&t->cur_tok->data.float_lit.bigfloat, f_bits.actual); |
| 348 | safe_memcpy(&dbl_value, (double *)&double_bits, 1); | | |
| 349 | bigfloat_init_64(&t->cur_tok->data.float_lit.bigfloat, dbl_value); | | |
| 350 | } | 363 | } |
| 351 | | 364 | |
| 352 | static void end_token(Tokenize *t) { | 365 | static void end_token(Tokenize *t) { |