[libre-riscv-dev] IEEE754 FPU
Luke Kenneth Casson Leighton
lkcl at lkcl.net
Tue Feb 12 09:54:53 GMT 2019
ok some notes:
https://steve.hollasch.net/cgindex/coding/ieeefloat.html
* exponents are "offset" by 127 (32-bit)
* mantissa (the fraction part), the leading 1 is stripped off.
therefore, when 2 numbers are added, you *know* that the 2 leading 1s
will be added and result in '0b10, so you don't even need to include
the leading 1s as part of the sum of the 2 fractions.
https://github.com/ucb-bar/berkeley-softfloat-3/blob/master/source/s_addMagsF32.c#L68
"expA==0" is the special-case for indicating a "denormalised" number.
denormalised means that instead of there being a leading implicit 1,
you drop down to *inaccurate* fractions. so the result can be just
the sum of the original A plus the *fractional* part of B, and if that
happens to overflow (more than 23 bits), that's perfect! it means
that the result contains an exponent of 0b0000001.
https://github.com/ucb-bar/berkeley-softfloat-3/blob/master/source/s_addMagsF32.c#L73
"expA==0xFF" is an "infinity" indicator. so if either or both of the
two infinities are negative-signed, a special infinity-based
calculation has to take place because you can do +inf or -inf, they
are *different* numbers
https://github.com/ucb-bar/berkeley-softfloat-3/blob/master/source/s_addMagsF32.c#L79
this is really clever. the two fractions are summed however an
additional "0x1000000" is included which is (1<<24) which is an
*exponent* of 0b0000001.
now, what that does is, it means that the sum of the two fractions is
to be multiplied by 2 (exponent += 1). to COMPENSATE for that, the
fraction part is DIVIDED by 2 (right-shifted down). however... there
is a corner-case that needs to be dealt with: if the exponent could
run out of range. so that's where the test "expZ<0xFE" comes in to
play.
if you look closely at packToF32UI, it does *NOT* do an OR of the
three arguments, it does an *ADD*. consequently, that 0x1000000 which
was included in the sum of the 2 fractions gets ADDED to the exponent.
also, if the sum of the 2 fractions overflows, it results in that
0x1000000 in the exponent becoming a *0x2000000*.
it's really really clever.
https://github.com/ucb-bar/berkeley-softfloat-3/blob/master/source/s_addMagsF32.c#L79
sigZ <<= 6, remember that the add will have already shifted the result
up by 1 (the additional 0x1000000 at line 79), so actually, the sum is
shifted up by *seven* bits.
i haven't yet investigated softfloat_roundPackToF32 however a quick
analysis "roundBits = sig & 0x7F" in s_roundPackToF32.c that matches
with the above paragraph, the sum actually being shifted up by 7 bits
(not 6).
so it looks like the softfloat library has an additional 7 bits that
go into the rounding assessment for 32-bit FP numbers.
l.
More information about the libre-riscv-dev
mailing list