* [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).