public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [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).