* [PATCH] libgcc/m68k: Fixes for soft float
@ 2023-08-23 2:15 Keith Packard
2023-11-10 23:49 ` Jeff Law
2025-01-01 21:16 ` [PATCH] libgcc/m68k: More fixes " Keith Packard
0 siblings, 2 replies; 6+ messages in thread
From: Keith Packard @ 2023-08-23 2:15 UTC (permalink / raw)
To: gcc-patches; +Cc: Keith Packard
Check for non-zero denorm in __adddf3. Need to check both the upper and
lower 32-bit chunks of a 64-bit float for a non-zero value when
checking to see if the value is -0.
Fix __addsf3 when the sum exponent is exactly 0xff to ensure that
produces infinity and not nan.
Handle converting NaN/inf values between formats.
Handle underflow and overflow when truncating.
Write a replacement for __fixxfsi so that it does not raise extra
exceptions during an extra conversion from long double to double.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
libgcc/config/m68k/fpgnulib.c | 161 +++++++++++++++++++++++++++-------
libgcc/config/m68k/lb1sf68.S | 7 +-
2 files changed, 134 insertions(+), 34 deletions(-)
diff --git a/libgcc/config/m68k/fpgnulib.c b/libgcc/config/m68k/fpgnulib.c
index fe41edf26aa..5b53778e986 100644
--- a/libgcc/config/m68k/fpgnulib.c
+++ b/libgcc/config/m68k/fpgnulib.c
@@ -54,6 +54,7 @@
#define SIGNBIT 0x80000000L
#define HIDDEN (1L << 23L)
#define SIGN(fp) ((fp) & SIGNBIT)
+#define EXPMASK 0xFFL
#define EXP(fp) (((fp) >> 23L) & 0xFF)
#define MANT(fp) (((fp) & 0x7FFFFFL) | HIDDEN)
#define PACK(s,e,m) ((s) | ((e) << 23L) | (m))
@@ -262,6 +263,9 @@ __extendsfdf2 (float a1)
mant &= ~HIDDEN;
}
exp = exp - EXCESS + EXCESSD;
+ /* Handle inf and NaN */
+ if (exp == EXPMASK - EXCESS + EXCESSD)
+ exp = EXPDMASK;
dl.l.upper |= exp << 20;
dl.l.upper |= mant >> 3;
dl.l.lower = mant << 29;
@@ -295,40 +299,52 @@ __truncdfsf2 (double a1)
/* shift double mantissa 6 bits so we can round */
sticky |= mant & ((1 << 6) - 1);
mant >>= 6;
-
- /* Check for underflow and denormals. */
- if (exp <= 0)
+ if (exp == EXPDMASK - EXCESSD + EXCESS)
+ {
+ exp = EXPMASK;
+ mant = mant >> 1 | (mant & 1) | !!sticky;
+ }
+ else
{
- if (exp < -24)
+ /* Check for underflow and denormals. */
+ if (exp <= 0)
{
- sticky |= mant;
- mant = 0;
+ if (exp < -24)
+ {
+ sticky |= mant;
+ mant = 0;
+ }
+ else
+ {
+ sticky |= mant & ((1 << (1 - exp)) - 1);
+ mant >>= 1 - exp;
+ }
+ exp = 0;
}
- else
+
+ /* now round */
+ shift = 1;
+ if ((mant & 1) && (sticky || (mant & 2)))
{
- sticky |= mant & ((1 << (1 - exp)) - 1);
- mant >>= 1 - exp;
- }
- exp = 0;
- }
-
- /* now round */
- shift = 1;
- if ((mant & 1) && (sticky || (mant & 2)))
- {
- int rounding = exp ? 2 : 1;
+ int rounding = exp ? 2 : 1;
- mant += 1;
+ mant += 1;
- /* did the round overflow? */
- if (mant >= (HIDDEN << rounding))
+ /* did the round overflow? */
+ if (mant >= (HIDDEN << rounding))
+ {
+ exp++;
+ shift = rounding;
+ }
+ }
+ /* shift down */
+ mant >>= shift;
+ if (exp >= EXPMASK)
{
- exp++;
- shift = rounding;
+ exp = EXPMASK;
+ mant = 0;
}
}
- /* shift down */
- mant >>= shift;
mant &= ~HIDDEN;
@@ -432,6 +448,30 @@ __extenddfxf2 (double d)
}
exp = EXPD (dl) - EXCESSD + EXCESSX;
+ /* Check for underflow and denormals. */
+ if (exp < 0)
+ {
+ if (exp < -53)
+ {
+ ldl.l.middle = 0;
+ ldl.l.lower = 0;
+ }
+ else if (exp < -30)
+ {
+ ldl.l.lower = (ldl.l.middle & MANTXMASK) >> ((1 - exp) - 32);
+ ldl.l.middle &= ~MANTXMASK;
+ }
+ else
+ {
+ ldl.l.lower >>= 1 - exp;
+ ldl.l.lower |= (ldl.l.middle & MANTXMASK) << (32 - (1 - exp));
+ ldl.l.middle = (ldl.l.middle & ~MANTXMASK) | (ldl.l.middle & MANTXMASK >> (1 - exp));
+ }
+ exp = 0;
+ }
+ /* Handle inf and NaN */
+ if (exp == EXPDMASK - EXCESSD + EXCESSX)
+ exp = EXPXMASK;
ldl.l.upper |= exp << 16;
ldl.l.middle = HIDDENX;
/* 31-20: # mantissa bits in ldl.l.middle - # mantissa bits in dl.l.upper */
@@ -464,9 +504,38 @@ __truncxfdf2 (long double ld)
}
exp = EXPX (ldl) - EXCESSX + EXCESSD;
- /* ??? quick and dirty: keep `exp' sane */
- if (exp >= EXPDMASK)
- exp = EXPDMASK - 1;
+ /* Check for underflow and denormals. */
+ if (exp <= 0)
+ {
+ if (exp < -53)
+ {
+ ldl.l.middle = 0;
+ ldl.l.lower = 0;
+ }
+ else if (exp < -30)
+ {
+ ldl.l.lower = (ldl.l.middle & MANTXMASK) >> ((1 - exp) - 32);
+ ldl.l.middle &= ~MANTXMASK;
+ }
+ else
+ {
+ ldl.l.lower >>= 1 - exp;
+ ldl.l.lower |= (ldl.l.middle & MANTXMASK) << (32 - (1 - exp));
+ ldl.l.middle = (ldl.l.middle & ~MANTXMASK) | (ldl.l.middle & MANTXMASK >> (1 - exp));
+ }
+ exp = 0;
+ }
+ else if (exp == EXPXMASK - EXCESSX + EXCESSD)
+ {
+ exp = EXPDMASK;
+ ldl.l.middle |= ldl.l.lower;
+ }
+ else if (exp >= EXPDMASK)
+ {
+ exp = EXPDMASK;
+ ldl.l.middle = 0;
+ ldl.l.lower = 0;
+ }
dl.l.upper |= exp << (32 - (EXPDBITS + 1));
/* +1-1: add one for sign bit, but take one off for explicit-integer-bit */
dl.l.upper |= (ldl.l.middle & MANTXMASK) >> (EXPDBITS + 1 - 1);
@@ -511,10 +580,40 @@ __floatunsixf (unsigned long l)
/* convert a long double to an int */
long
-__fixxfsi (long double ld)
+__fixxfsi (long double a)
{
- long foo = __fixdfsi ((double) ld);
- return foo;
+ union long_double_long ldl;
+ long exp;
+ long l;
+
+ ldl.ld = a;
+
+ exp = EXPX(ldl);
+ if (exp == 0 && ldl.l.middle == 0 && ldl.l.lower == 0)
+ return 0;
+
+ exp = exp - EXCESSX - 63;
+
+ if (exp > 0)
+ {
+ /* Return largest integer. */
+ return SIGNX (ldl) ? 0x80000000L : 0x7fffffffL;
+ }
+
+ if (exp <= -64)
+ return 0;
+
+ if (exp <= -32)
+ {
+ ldl.l.lower = ldl.l.middle >> (-exp - 32);
+ }
+ else if (exp < 0)
+ {
+ ldl.l.lower = ldl.l.lower >> -exp;
+ ldl.l.lower |= ldl.l.middle << (32 + exp);
+ }
+
+ return SIGNX(ldl) ? -ldl.l.lower : ldl.l.lower;
}
/* The remaining provide crude math support by working in double precision. */
diff --git a/libgcc/config/m68k/lb1sf68.S b/libgcc/config/m68k/lb1sf68.S
index 8ba85c53656..736a9a7872f 100644
--- a/libgcc/config/m68k/lb1sf68.S
+++ b/libgcc/config/m68k/lb1sf68.S
@@ -1383,6 +1383,8 @@ Ladddf$a:
bge 2f |
movel d0,d0 | check for zero, since we don't '
bne Ladddf$ret | want to return -0 by mistake
+ movel d1,d1 |
+ bne Ladddf$ret |
bclr IMM (31),d7 |
bra Ladddf$ret |
2:
@@ -2090,8 +2092,7 @@ Ldivdf$a$nf:
| If a is INFINITY we have to check b
cmpl d7,d2 | compare b with INFINITY
bge Ld$inop | if b is NaN or INFINITY return NaN
- tstl d3 |
- bne Ld$inop |
+ movl a0,d7 | restore sign bit to d7
bra Ld$overflow | else return overflow
| If a number is denormalized we put an exponent of 1 but do not put the
@@ -2936,7 +2937,7 @@ Laddsf$4:
#else
cmpl IMM (0xff),d2
#endif
- bhi 1f
+ bge 1f
bclr IMM (FLT_MANT_DIG-1),d0
#ifndef __mcoldfire__
lslw IMM (7),d2
--
2.40.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] libgcc/m68k: Fixes for soft float
2023-08-23 2:15 [PATCH] libgcc/m68k: Fixes for soft float Keith Packard
@ 2023-11-10 23:49 ` Jeff Law
2023-11-11 1:02 ` Keith Packard
2025-01-01 21:16 ` [PATCH] libgcc/m68k: More fixes " Keith Packard
1 sibling, 1 reply; 6+ messages in thread
From: Jeff Law @ 2023-11-10 23:49 UTC (permalink / raw)
To: Keith Packard, gcc-patches
On 8/22/23 20:15, Keith Packard via Gcc-patches wrote:
> Check for non-zero denorm in __adddf3. Need to check both the upper and
> lower 32-bit chunks of a 64-bit float for a non-zero value when
> checking to see if the value is -0.
>
> Fix __addsf3 when the sum exponent is exactly 0xff to ensure that
> produces infinity and not nan.
>
> Handle converting NaN/inf values between formats.
>
> Handle underflow and overflow when truncating.
>
> Write a replacement for __fixxfsi so that it does not raise extra
> exceptions during an extra conversion from long double to double.
>
> Signed-off-by: Keith Packard <keithp@keithp.com>
I pushed this to the trunk after fixing a few minor whitespace nits.
You didn't mention the divdf change, but I'll assume that was just an
oversight.
I'm largely trusting your reputation on the fpgnulib changes. I won't
claim to know that code at all. The assembly bits were simple enough
that I could make out what you were doing relatively easily.
Thanks again,
Jeff
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] libgcc/m68k: Fixes for soft float
2023-11-10 23:49 ` Jeff Law
@ 2023-11-11 1:02 ` Keith Packard
2023-11-11 17:51 ` Jeff Law
0 siblings, 1 reply; 6+ messages in thread
From: Keith Packard @ 2023-11-11 1:02 UTC (permalink / raw)
To: Jeff Law, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 983 bytes --]
> I pushed this to the trunk after fixing a few minor whitespace nits.
> You didn't mention the divdf change, but I'll assume that was just an
> oversight.
Yeah, a couple of minor fixes there that I forgot to mention in the log.
> I'm largely trusting your reputation on the fpgnulib changes. I won't
> claim to know that code at all. The assembly bits were simple enough
> that I could make out what you were doing relatively easily.
Thanks for that review -- m68k assembly isn't my strongest language. The
kludge to return pointers in both d1 and a1 was a bit ugly, but seemed
like a much more robust plan than attempting to use different registers
depending on the target ABI...
The real check for these fixes was to run a fairly comprehensive C
library test suite (part of picolibc) and just iterate until I stopped
getting failures. Those tests have found so many corner cases in both
the C library, FPU emulation and compilers ...
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] libgcc/m68k: Fixes for soft float
2023-11-11 1:02 ` Keith Packard
@ 2023-11-11 17:51 ` Jeff Law
0 siblings, 0 replies; 6+ messages in thread
From: Jeff Law @ 2023-11-11 17:51 UTC (permalink / raw)
To: Keith Packard, gcc-patches
On 11/10/23 18:02, Keith Packard wrote:
>
>> I'm largely trusting your reputation on the fpgnulib changes. I won't
>> claim to know that code at all. The assembly bits were simple enough
>> that I could make out what you were doing relatively easily.
>
> Thanks for that review -- m68k assembly isn't my strongest language. The
> kludge to return pointers in both d1 and a1 was a bit ugly, but seemed
> like a much more robust plan than attempting to use different registers
> depending on the target ABI...
I get by. Things like m68k, hppa, etc have stuck harder than I would
have ever imagined. But ppc, alpha, and some of the others I've worked
on through the years, not so much.
And yes there are ABI implications on the return value. As you know
back in the day things weren't typed so well, so varying the location of
the return value based on type wasn't terribly safe. Dual output worked
around a class of problems. These days varying args/return value
location based on types is common.
>
> The real check for these fixes was to run a fairly comprehensive C
> library test suite (part of picolibc) and just iterate until I stopped
> getting failures. Those tests have found so many corner cases in both
> the C library, FPU emulation and compilers ...
Not surprised.
Thanks again,
Jeff
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] libgcc/m68k: More fixes for soft float
2023-08-23 2:15 [PATCH] libgcc/m68k: Fixes for soft float Keith Packard
2023-11-10 23:49 ` Jeff Law
@ 2025-01-01 21:16 ` Keith Packard
2025-01-07 21:59 ` Jeff Law
1 sibling, 1 reply; 6+ messages in thread
From: Keith Packard @ 2025-01-01 21:16 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1.1: Type: text/plain, Size: 386 bytes --]
I thought I had sent all of my m68k soft float fixes along last year,
but it looks like I managed to leave some out. I had been building
my toolchain from a private repo (oops), which masked my mistake. We're
fixing that by automatically building toolchains from upstream source
with a list of patches now, so this "shouldn't" happen again. Now to
drive that list of patches to zero.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: 0001-libgcc-m68k-Fixes-for-soft-float.patch --]
[-- Type: text/x-diff, Size: 7515 bytes --]
From 1a3e403603f5a687724c7e2f6625debc3d23d934 Mon Sep 17 00:00:00 2001
From: Keith Packard <keithp@keithp.com>
Date: Sun, 29 Dec 2024 01:42:29 -0800
Subject: [PATCH] libgcc/m68k: Fixes for soft float
Fix __extenddfxf2:
* Remove bogus denorm handling block which would never execute --
the converted exp value is always positive as EXCESSX > EXCESSD.
* Compute the whole significand in dl instead of doing part of it in
ldl.
* Mask off exponent from dl.l.upper so the denorm shift test
works.
* Insert the hidden one bit into dl.l.upper as needed.
Fix __truncxfdf2 denorm handling. All that is required is to shift the
significand right by the correct amount; it already has all of the
necessary bits set including the explicit one. Compute the shift
amount, then perform the wide shift across both elements of the
significand.
Fix __fixxfsi:
* The value was off by a factor of two as the significand contains
32 bits, not 31 so we need to shift by one more than the equivalent
code in __fixdfsi.
* Simplify the code having realized that the lower 32 bits of the
significand can never appear in the results.
Return positive qNaN instead of negative. For floats, qNaN is 0x7fff_ffff. For
doubles, qNaN is 0x7fff_ffff_ffff_ffff.
Return correctly signed zero on float and double divide underflow. This means
that Ld$underflow now expects d7 to contain the sign bit, just like the other
return paths.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
libgcc/config/m68k/fpgnulib.c | 78 ++++++++++++++++-------------------
libgcc/config/m68k/lb1sf68.S | 13 ++++--
2 files changed, 45 insertions(+), 46 deletions(-)
diff --git a/libgcc/config/m68k/fpgnulib.c b/libgcc/config/m68k/fpgnulib.c
index 70bfd442d75..a7d4258dff0 100644
--- a/libgcc/config/m68k/fpgnulib.c
+++ b/libgcc/config/m68k/fpgnulib.c
@@ -449,34 +449,37 @@ __extenddfxf2 (double d)
}
exp = EXPD (dl) - EXCESSD + EXCESSX;
- /* Check for underflow and denormals. */
- if (exp < 0)
+
+ dl.l.upper &= MANTDMASK;
+
+ /* Recover from a denorm. */
+ if (exp == -EXCESSD + EXCESSX)
{
- if (exp < -53)
- {
- ldl.l.middle = 0;
- ldl.l.lower = 0;
- }
- else if (exp < -30)
- {
- ldl.l.lower = (ldl.l.middle & MANTXMASK) >> ((1 - exp) - 32);
- ldl.l.middle &= ~MANTXMASK;
- }
- else
+ exp++;
+ while ((dl.l.upper & HIDDEND) == 0)
{
- ldl.l.lower >>= 1 - exp;
- ldl.l.lower |= (ldl.l.middle & MANTXMASK) << (32 - (1 - exp));
- ldl.l.middle = (ldl.l.middle & ~MANTXMASK) | (ldl.l.middle & MANTXMASK >> (1 - exp));
+ exp--;
+ dl.l.upper = (dl.l.upper << 1) | (dl.l.lower >> 31);
+ dl.l.lower = dl.l.lower << 1;
}
- exp = 0;
}
+
/* Handle inf and NaN */
- if (exp == EXPDMASK - EXCESSD + EXCESSX)
- exp = EXPXMASK;
+ else if (exp == EXPDMASK - EXCESSD + EXCESSX)
+ {
+ exp = EXPXMASK;
+ /* Add hidden one bit for NaN */
+ if (dl.l.upper != 0 || dl.l.lower != 0)
+ dl.l.upper |= HIDDEND;
+ }
+ else
+ {
+ dl.l.upper |= HIDDEND;
+ }
+
ldl.l.upper |= exp << 16;
- ldl.l.middle = HIDDENX;
/* 31-20: # mantissa bits in ldl.l.middle - # mantissa bits in dl.l.upper */
- ldl.l.middle |= (dl.l.upper & MANTDMASK) << (31 - 20);
+ ldl.l.middle = dl.l.upper << (31 - 20);
/* 1+20: explicit-integer-bit + # mantissa bits in dl.l.upper */
ldl.l.middle |= dl.l.lower >> (1 + 20);
/* 32 - 21: # bits of dl.l.lower in ldl.l.middle */
@@ -508,21 +511,21 @@ __truncxfdf2 (long double ld)
/* Check for underflow and denormals. */
if (exp <= 0)
{
- if (exp < -53)
+ long shift = 1 - exp;
+ if (shift > 52)
{
ldl.l.middle = 0;
ldl.l.lower = 0;
}
- else if (exp < -30)
+ else if (shift >= 32)
{
- ldl.l.lower = (ldl.l.middle & MANTXMASK) >> ((1 - exp) - 32);
- ldl.l.middle &= ~MANTXMASK;
+ ldl.l.lower = (ldl.l.middle) >> (shift - 32);
+ ldl.l.middle = 0;
}
else
{
- ldl.l.lower >>= 1 - exp;
- ldl.l.lower |= (ldl.l.middle & MANTXMASK) << (32 - (1 - exp));
- ldl.l.middle = (ldl.l.middle & ~MANTXMASK) | (ldl.l.middle & MANTXMASK >> (1 - exp));
+ ldl.l.lower = (ldl.l.middle << (32 - shift)) | (ldl.l.lower >> shift);
+ ldl.l.middle = ldl.l.middle >> shift;
}
exp = 0;
}
@@ -585,7 +588,6 @@ __fixxfsi (long double a)
{
union long_double_long ldl;
long exp;
- long l;
ldl.ld = a;
@@ -593,28 +595,20 @@ __fixxfsi (long double a)
if (exp == 0 && ldl.l.middle == 0 && ldl.l.lower == 0)
return 0;
- exp = exp - EXCESSX - 63;
+ exp = exp - EXCESSX - 32;
- if (exp > 0)
+ if (exp >= 0)
{
/* Return largest integer. */
return SIGNX (ldl) ? 0x80000000L : 0x7fffffffL;
}
- if (exp <= -64)
+ if (exp <= -32)
return 0;
- if (exp <= -32)
- {
- ldl.l.lower = ldl.l.middle >> (-exp - 32);
- }
- else if (exp < 0)
- {
- ldl.l.lower = ldl.l.lower >> -exp;
- ldl.l.lower |= ldl.l.middle << (32 + exp);
- }
+ ldl.l.middle >>= -exp;
- return SIGNX (ldl) ? -ldl.l.lower : ldl.l.lower;
+ return SIGNX (ldl) ? -ldl.l.middle : ldl.l.middle;
}
/* The remaining provide crude math support by working in double precision. */
diff --git a/libgcc/config/m68k/lb1sf68.S b/libgcc/config/m68k/lb1sf68.S
index 22f2772520c..ebec095c6e7 100644
--- a/libgcc/config/m68k/lb1sf68.S
+++ b/libgcc/config/m68k/lb1sf68.S
@@ -635,7 +635,7 @@ SYM (__modsi3):
.globl SYM (_fpCCR)
.globl $_exception_handler
-QUIET_NaN = 0xffffffff
+QUIET_NaN = 0x7fffffff
D_MAX_EXP = 0x07ff
D_BIAS = 1022
@@ -700,9 +700,10 @@ Ld$overflow:
PICJUMP $_exception_handler
Ld$underflow:
-| Return 0 and set the exception flags
+| Return a properly signed 0 and set the exception flags
movel IMM (0),d0
movel d0,d1
+ orl d7,d0
movew IMM (INEXACT_RESULT+UNDERFLOW),d7
moveq IMM (DOUBLE_FLOAT),d6
PICJUMP $_exception_handler
@@ -711,6 +712,7 @@ Ld$inop:
| Return a quiet NaN and set the exception flags
movel IMM (QUIET_NaN),d0
movel d0,d1
+ bset IMM (31),d1
movew IMM (INEXACT_RESULT+INVALID_OPERATION),d7
moveq IMM (DOUBLE_FLOAT),d6
PICJUMP $_exception_handler
@@ -2082,6 +2084,7 @@ Ldivdf$b$nf:
| If d2 == 0x7ff00000 we have to check d3.
tstl d3 |
bne Ld$inop | if d3 <> 0, b is NaN
+ movel a0,d7 | put a's sign
bra Ld$underflow | else b is +/-INFINITY, so signal underflow
Ldivdf$a$nf:
@@ -2187,6 +2190,7 @@ Lround$exit:
#endif
beq 2f | if not loop back
bra 1b |
+ movel a0,d7 | get back sign bit into d7
bra Ld$underflow | safety check, shouldn't execute '
2: orl d6,d2 | this is a trick so we don't lose '
orl d7,d3 | the bits which were flushed right
@@ -2549,7 +2553,7 @@ Lround$to$minus:
.globl SYM (_fpCCR)
.globl $_exception_handler
-QUIET_NaN = 0xffffffff
+QUIET_NaN = 0x7fffffff
SIGNL_NaN = 0x7f800001
INFINITY = 0x7f800000
@@ -2615,8 +2619,9 @@ Lf$overflow:
PICJUMP $_exception_handler
Lf$underflow:
-| Return 0 and set the exception flags
+| Return a properly signed 0 and set the exception flags
moveq IMM (0),d0
+ orl d7,d0
moveq IMM (INEXACT_RESULT+UNDERFLOW),d7
moveq IMM (SINGLE_FLOAT),d6
PICJUMP $_exception_handler
--
2.45.2
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] libgcc/m68k: More fixes for soft float
2025-01-01 21:16 ` [PATCH] libgcc/m68k: More fixes " Keith Packard
@ 2025-01-07 21:59 ` Jeff Law
0 siblings, 0 replies; 6+ messages in thread
From: Jeff Law @ 2025-01-07 21:59 UTC (permalink / raw)
To: Keith Packard, gcc-patches
On 1/1/25 2:16 PM, Keith Packard wrote:
> I thought I had sent all of my m68k soft float fixes along last year,
> but it looks like I managed to leave some out. I had been building
> my toolchain from a private repo (oops), which masked my mistake. We're
> fixing that by automatically building toolchains from upstream source
> with a list of patches now, so this "shouldn't" happen again. Now to
> drive that list of patches to zero.
>
>
> 0001-libgcc-m68k-Fixes-for-soft-float.patch
>
> From 1a3e403603f5a687724c7e2f6625debc3d23d934 Mon Sep 17 00:00:00 2001
> From: Keith Packard<keithp@keithp.com>
> Date: Sun, 29 Dec 2024 01:42:29 -0800
> Subject: [PATCH] libgcc/m68k: Fixes for soft float
>
> Fix __extenddfxf2:
>
> * Remove bogus denorm handling block which would never execute --
> the converted exp value is always positive as EXCESSX > EXCESSD.
>
> * Compute the whole significand in dl instead of doing part of it in
> ldl.
>
> * Mask off exponent from dl.l.upper so the denorm shift test
> works.
>
> * Insert the hidden one bit into dl.l.upper as needed.
>
> Fix __truncxfdf2 denorm handling. All that is required is to shift the
> significand right by the correct amount; it already has all of the
> necessary bits set including the explicit one. Compute the shift
> amount, then perform the wide shift across both elements of the
> significand.
>
> Fix __fixxfsi:
>
> * The value was off by a factor of two as the significand contains
> 32 bits, not 31 so we need to shift by one more than the equivalent
> code in __fixdfsi.
>
> * Simplify the code having realized that the lower 32 bits of the
> significand can never appear in the results.
>
> Return positive qNaN instead of negative. For floats, qNaN is 0x7fff_ffff. For
> doubles, qNaN is 0x7fff_ffff_ffff_ffff.
>
> Return correctly signed zero on float and double divide underflow. This means
> that Ld$underflow now expects d7 to contain the sign bit, just like the other
> return paths.
>
> Signed-off-by: Keith Packard<keithp@keithp.com>
Thanks. I pushed this to the trunk.
jeff
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-01-07 21:59 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-23 2:15 [PATCH] libgcc/m68k: Fixes for soft float Keith Packard
2023-11-10 23:49 ` Jeff Law
2023-11-11 1:02 ` Keith Packard
2023-11-11 17:51 ` Jeff Law
2025-01-01 21:16 ` [PATCH] libgcc/m68k: More fixes " Keith Packard
2025-01-07 21:59 ` Jeff Law
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).