https://gcc.gnu.org/g:2830b0b8655f0d1a62b416af8ade31f5b96f0ffb
commit r15-1343-g2830b0b8655f0d1a62b416af8ade31f5b96f0ffb Author: Georg-Johann Lay <a...@gjlay.de> Date: Fri Jun 14 18:24:13 2024 +0200 AVR: target/115419 - Tie breaks are rounded-to-even. libgcc/config/avr/libf7/ PR target/115419 * libf7.c (f7_get_double): Round tie breaks to even LSB. Diff: --- libgcc/config/avr/libf7/libf7.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/libgcc/config/avr/libf7/libf7.c b/libgcc/config/avr/libf7/libf7.c index 375becb854c1..6fae4fc1a2de 100644 --- a/libgcc/config/avr/libf7/libf7.c +++ b/libgcc/config/avr/libf7/libf7.c @@ -440,11 +440,21 @@ f7_double_t f7_get_double (const f7_t *aa) mant &= 0x00ffffffffffffff; - // FIXME: For subnormals, rounding is premature and should be - // done *after* the mantissa has been shifted into place - // (or the round value be shifted left accordingly). - // Round. - mant += 1u << (F7_MANT_BITS - (1 + DBL_DIG_MANT) - 1); + // PR115419: The least significant nibble tells how to round: + // Tie breaks are rounded to even (Banker's rounding). + uint8_t lsn = mant & 0xff; + lsn &= 0xf; + // The LSB of the outgoing double is at bit 3. + if (lsn & (1 << 3)) + ++lsn; + if (lsn > (1 << 2)) + { + // FIXME: For subnormals, rounding is premature and should be + // done *after* the mantissa has been shifted into place + // (or the round value be shifted left accordingly). + // Round. + mant += 1u << (F7_MANT_BITS - (1 + DBL_DIG_MANT) - 1); + } uint8_t dex; register uint64_t r18 __asm ("r18") = mant;