[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