diff options
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 6 | ||||
-rw-r--r-- | libgcc/libgcc2.c | 41 |
2 files changed, 19 insertions, 28 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 7e907b6..f05492e 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,9 @@ +2025-07-10 Jan Dubiec <jdx@o2.pl> + + PR target/116363 + * libgcc2.c (__fixunssfDI): Fix SFtype to UDWtype conversion for targets + without LIBGCC2_HAS_DF_MODE defined + 2025-05-27 Jakub Jelinek <jakub@redhat.com> * config/t-softfp (softfp_bid_list): Don't guard with diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c index faefff3..df99c78 100644 --- a/libgcc/libgcc2.c +++ b/libgcc/libgcc2.c @@ -2187,36 +2187,21 @@ __fixunssfDI (SFtype a) if (a < 1) return 0; if (a < Wtype_MAXp1_F) - return (UWtype)a; + return (UWtype) a; if (a < Wtype_MAXp1_F * Wtype_MAXp1_F) { - /* Since we know that there are fewer significant bits in the SFmode - quantity than in a word, we know that we can convert out all the - significant bits in one step, and thus avoid losing bits. */ - - /* ??? This following loop essentially performs frexpf. If we could - use the real libm function, or poke at the actual bits of the fp - format, it would be significantly faster. */ - - UWtype shift = 0, counter; - SFtype msb; - - a /= Wtype_MAXp1_F; - for (counter = W_TYPE_SIZE / 2; counter != 0; counter >>= 1) - { - SFtype counterf = (UWtype)1 << counter; - if (a >= counterf) - { - shift |= counter; - a /= counterf; - } - } - - /* Rescale into the range of one word, extract the bits of that - one word, and shift the result into position. */ - a *= Wtype_MAXp1_F; - counter = a; - return (DWtype)counter << shift; + /* We assume that SFtype -> UWtype and UWtype -> UDWtype casts work + properly. Obviously, we *cannot* assume that SFtype -> UDWtype + works as expected. */ + SFtype a_hi, a_lo; + + a_hi = a / Wtype_MAXp1_F; + a_lo = a - a_hi * Wtype_MAXp1_F; + + /* A lot of parentheses. This is to make it very clear what is + the sequence of operations. */ + return ((UDWtype) ((UWtype) a_hi)) << W_TYPE_SIZE + | (UDWtype) ((UWtype) a_lo); } return -1; #else |