| ... | @@ -326,51 +326,49 @@ static void end_float_token(Tokenize *t) { | ... | @@ -326,51 +326,49 @@ static void end_float_token(Tokenize *t) { |
| 326 | return; | 326 | return; |
| 327 | } | 327 | } |
| 328 | | 328 | |
| 329 | // A SoftFloat-3d float128 is represented internally as a standard | 329 | // A SoftFloat-3e float128 is represented internally as a standard |
| 330 | // quad-precision float with 15bit exponent and 113bit fractional. | 330 | // quad-precision float with 15bit exponent and 112bit fractional. |
| 331 | union { uint64_t repr[2]; float128_t actual; } f_bits; | 331 | union { uint64_t repr[2]; float128_t actual; } f_bits; |
| 332 | | 332 | |
| 333 | if (bigint_cmp_zero(&t->significand) == CmpEQ) { | 333 | if (bigint_cmp_zero(&t->significand) == CmpEQ) { |
| 334 | f_bits.repr[0] = 0; | 334 | f_bits.repr[0] = 0; |
| 335 | f_bits.repr[1] = 0; | 335 | f_bits.repr[1] = 0; |
| 336 | } else { | 336 | } else { |
| 337 | // normalize the significand | 337 | int significand_magnitude_in_bin = 127 - bigint_clz(&t->significand, 128); |
| 338 | if (t->radix == 10) { | 338 | t->exponent_in_bin_or_dec += significand_magnitude_in_bin; |
| 339 | zig_panic("TODO: decimal floats"); | 339 | if (!(-16382 <= t->exponent_in_bin_or_dec && t->exponent_in_bin_or_dec <= 16383)) { |
| 340 | } else { | 340 | t->cur_tok->data.float_lit.overflow = true; |
| 341 | int significand_magnitude_in_bin = 127 - bigint_clz(&t->significand, 128); | 341 | return; |
| 342 | t->exponent_in_bin_or_dec += significand_magnitude_in_bin; | 342 | } |
| 343 | if (!(-16382 <= t->exponent_in_bin_or_dec && t->exponent_in_bin_or_dec <= 16383)) { | | |
| 344 | t->cur_tok->data.float_lit.overflow = true; | | |
| 345 | return; | | |
| 346 | } | | |
| 347 | | | |
| 348 | uint64_t sig_bits[2] = {0, 0}; | | |
| 349 | bigint_write_twos_complement(&t->significand, (uint8_t*) sig_bits, 128, false); | | |
| 350 | | | |
| 351 | const uint64_t shift = 112 - significand_magnitude_in_bin; | | |
| 352 | const uint64_t exp_shift = 48; | | |
| 353 | // Mask the sign bit to 0 since always non-negative lex | | |
| 354 | const uint64_t exp_mask = 0xffffull << exp_shift; | | |
| 355 | | | |
| 356 | // must be special-cased to avoid undefined behavior on shift == 64 | | |
| 357 | if (shift == 128) { | | |
| 358 | f_bits.repr[0] = 0; | | |
| 359 | f_bits.repr[1] = sig_bits[0]; | | |
| 360 | } else if (shift == 0) { | | |
| 361 | f_bits.repr[0] = sig_bits[0]; | | |
| 362 | f_bits.repr[1] = sig_bits[1]; | | |
| 363 | } else if (shift >= 64) { | | |
| 364 | f_bits.repr[0] = 0; | | |
| 365 | f_bits.repr[1] = sig_bits[0] << (shift - 64); | | |
| 366 | } else { | | |
| 367 | f_bits.repr[0] = sig_bits[0] << shift; | | |
| 368 | f_bits.repr[1] = (sig_bits[1] << shift) | (sig_bits[0] >> (64 - shift)); | | |
| 369 | } | | |
| 370 | | 343 | |
| 371 | f_bits.repr[1] &= ~exp_mask; | 344 | // Shift bits of significand so they are left-justified at the 112-bit |
| 372 | f_bits.repr[1] |= (uint64_t)(t->exponent_in_bin_or_dec + 16383) << exp_shift; | 345 | // mark. We truncate excess bits and lose precision. No rounding. |
| | 346 | // |
| | 347 | // -16 <= shift <= 112 |
| | 348 | // |
| | 349 | // NOTE: The loss of precision could be considered a limitation of using |
| | 350 | // 128-bit floats. In stage2 we should use an arbitrary precision |
| | 351 | // float/rational type to represent these and avoid this. |
| | 352 | const int shift = 112 - significand_magnitude_in_bin; |
| | 353 | bigint_write_twos_complement(&t->significand, (uint8_t*) f_bits.repr, 128, false); |
| | 354 | |
| | 355 | if (shift >= 64) { |
| | 356 | f_bits.repr[1] = f_bits.repr[0] << (shift - 64); |
| | 357 | f_bits.repr[0] = 0; |
| | 358 | } else if (shift > 0) { |
| | 359 | f_bits.repr[1] = (f_bits.repr[1] << shift) | (f_bits.repr[0] >> (64 - shift)); |
| | 360 | f_bits.repr[0] = f_bits.repr[0] << shift; |
| | 361 | } else if (shift < 0) { |
| | 362 | int positive_shift = -shift; |
| | 363 | assert(positive_shift <= 16); |
| | 364 | f_bits.repr[0] = (f_bits.repr[0] >> positive_shift) | (f_bits.repr[1] << (64 - positive_shift)); |
| | 365 | f_bits.repr[1] = f_bits.repr[1] >> positive_shift; |
| 373 | } | 366 | } |
| | 367 | |
| | 368 | // Lexer separates negative sign from value so this is always non-negative. |
| | 369 | const uint64_t exp_mask = 0xffffull << 48; |
| | 370 | f_bits.repr[1] &= ~exp_mask; |
| | 371 | f_bits.repr[1] |= (uint64_t)(t->exponent_in_bin_or_dec + 16383) << 48; |
| 374 | } | 372 | } |
| 375 | | 373 | |
| 376 | bigfloat_init_128(&t->cur_tok->data.float_lit.bigfloat, f_bits.actual); | 374 | bigfloat_init_128(&t->cur_tok->data.float_lit.bigfloat, f_bits.actual); |