aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog6
-rw-r--r--libgcc/libgcc2.c41
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