| ... | @@ -326,7 +326,7 @@ static void end_float_token(Tokenize *t) { | ... | @@ -326,7 +326,7 @@ 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 113bit 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 | |
| ... | @@ -345,29 +345,37 @@ static void end_float_token(Tokenize *t) { | ... | @@ -345,29 +345,37 @@ static void end_float_token(Tokenize *t) { |
| 345 | return; | 345 | return; |
| 346 | } | 346 | } |
| 347 | | 347 | |
| 348 | uint64_t sig_bits[2] = {0, 0}; | 348 | const int shift = 112 - significand_magnitude_in_bin; |
| 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 | | 349 | |
| 356 | // must be special-cased to avoid undefined behavior on shift == 64 | 350 | // must be special-cased to avoid undefined behavior on shift == 64 |
| 357 | if (shift == 128) { | 351 | if (shift == 128) { |
| | 352 | uint64_t sig_bits[2] = {0, 0}; |
| | 353 | bigint_write_twos_complement(&t->significand, (uint8_t*) sig_bits, 128, false); |
| 358 | f_bits.repr[0] = 0; | 354 | f_bits.repr[0] = 0; |
| 359 | f_bits.repr[1] = sig_bits[0]; | 355 | f_bits.repr[1] = sig_bits[0]; |
| 360 | } else if (shift == 0) { | 356 | } else if (shift == 0) { |
| 361 | f_bits.repr[0] = sig_bits[0]; | 357 | bigint_write_twos_complement(&t->significand, (uint8_t*) f_bits.repr, 128, false); |
| 362 | f_bits.repr[1] = sig_bits[1]; | | |
| 363 | } else if (shift >= 64) { | 358 | } else if (shift >= 64) { |
| | 359 | uint64_t sig_bits[2] = {0, 0}; |
| | 360 | bigint_write_twos_complement(&t->significand, (uint8_t*) sig_bits, 128, false); |
| 364 | f_bits.repr[0] = 0; | 361 | f_bits.repr[0] = 0; |
| 365 | f_bits.repr[1] = sig_bits[0] << (shift - 64); | 362 | f_bits.repr[1] = sig_bits[0] << (shift - 64); |
| | 363 | } else if (shift < 0) { |
| | 364 | BigInt shift_bigint; |
| | 365 | bigint_init_unsigned(&shift_bigint, -shift); |
| | 366 | BigInt shifted_significand; |
| | 367 | bigint_shr(&shifted_significand, &t->significand, &shift_bigint); |
| | 368 | bigint_write_twos_complement(&shifted_significand, (uint8_t*) f_bits.repr, 128, false); |
| 366 | } else { | 369 | } else { |
| | 370 | uint64_t sig_bits[2] = {0, 0}; |
| | 371 | bigint_write_twos_complement(&t->significand, (uint8_t*) sig_bits, 128, false); |
| 367 | f_bits.repr[0] = sig_bits[0] << shift; | 372 | f_bits.repr[0] = sig_bits[0] << shift; |
| 368 | f_bits.repr[1] = (sig_bits[1] << shift) | (sig_bits[0] >> (64 - shift)); | 373 | f_bits.repr[1] = (sig_bits[1] << shift) | (sig_bits[0] >> (64 - shift)); |
| 369 | } | 374 | } |
| 370 | | 375 | |
| | 376 | const uint64_t exp_shift = 48; |
| | 377 | // Mask the sign bit to 0 since always non-negative lex |
| | 378 | const uint64_t exp_mask = 0xffffull << exp_shift; |
| 371 | f_bits.repr[1] &= ~exp_mask; | 379 | f_bits.repr[1] &= ~exp_mask; |
| 372 | f_bits.repr[1] |= (uint64_t)(t->exponent_in_bin_or_dec + 16383) << exp_shift; | 380 | f_bits.repr[1] |= (uint64_t)(t->exponent_in_bin_or_dec + 16383) << exp_shift; |
| 373 | } | 381 | } |