aboutsummaryrefslogtreecommitdiff
path: root/packages/gcc/13.2.0/0012-libgcc-m68k-Fixes-for-soft-float.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/gcc/13.2.0/0012-libgcc-m68k-Fixes-for-soft-float.patch')
-rw-r--r--packages/gcc/13.2.0/0012-libgcc-m68k-Fixes-for-soft-float.patch348
1 files changed, 0 insertions, 348 deletions
diff --git a/packages/gcc/13.2.0/0012-libgcc-m68k-Fixes-for-soft-float.patch b/packages/gcc/13.2.0/0012-libgcc-m68k-Fixes-for-soft-float.patch
deleted file mode 100644
index 005b519d..00000000
--- a/packages/gcc/13.2.0/0012-libgcc-m68k-Fixes-for-soft-float.patch
+++ /dev/null
@@ -1,348 +0,0 @@
-From 3393fcce1e6b18e580b712c0855bba13fb622531 Mon Sep 17 00:00:00 2001
-From: Keith Packard <keithp@keithp.com>
-Date: Tue, 22 Aug 2023 12:28:53 -0700
-Subject: [PATCH] libgcc/m68k: Fixes for soft float
-
-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.
-
-Return correctly signed zero on float and double divide underflow
-
-Return positive qNaN instead of negative.
-
-Signed-off-by: Keith Packard <keithp@keithp.com>
----
- libgcc/config/m68k/fpgnulib.c | 162 +++++++++++++++++++++++++++-------
- libgcc/config/m68k/lb1sf68.S | 20 +++--
- 2 files changed, 143 insertions(+), 39 deletions(-)
-
-diff --git a/libgcc/config/m68k/fpgnulib.c b/libgcc/config/m68k/fpgnulib.c
-index fe41edf26aa..eaa7858493c 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,8 +448,31 @@ __extenddfxf2 (double d)
- }
-
- exp = EXPD (dl) - EXCESSD + EXCESSX;
-- ldl.l.upper |= exp << 16;
-+ dl.l.upper &= MANTDMASK;
- ldl.l.middle = HIDDENX;
-+
-+ /* Recover from a denorm. */
-+ if (exp == -EXCESSD + EXCESSX)
-+ {
-+ exp++;
-+ while ((dl.l.upper & HIDDEND) == 0)
-+ {
-+ exp--;
-+ dl.l.upper = (dl.l.upper << 1) | (dl.l.lower >> 31);
-+ dl.l.lower = dl.l.lower << 1;
-+ }
-+ }
-+
-+ /* Handle inf and NaN */
-+ else if (exp == EXPDMASK - EXCESSD + EXCESSX)
-+ {
-+ exp = EXPXMASK;
-+ /* No hidden one bit for INF */
-+ if (dl.l.upper == 0 && dl.l.lower == 0)
-+ ldl.l.middle = 0;
-+ }
-+
-+ ldl.l.upper |= exp << 16;
- /* 31-20: # mantissa bits in ldl.l.middle - # mantissa bits in dl.l.upper */
- ldl.l.middle |= (dl.l.upper & MANTDMASK) << (31 - 20);
- /* 1+20: explicit-integer-bit + # mantissa bits in dl.l.upper */
-@@ -464,9 +503,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 +579,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 - 64;
-+
-+ 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..e12888bd7f8 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
-@@ -1383,6 +1385,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:
-@@ -2080,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:
-@@ -2090,8 +2095,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
-@@ -2186,6 +2190,7 @@ Lround$exit:
- #endif
- beq 2f | if not loop back
- bra 1b |
-+ movel a0,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
-@@ -2548,7 +2553,7 @@ Lround$to$minus:
- .globl SYM (_fpCCR)
- .globl $_exception_handler
-
--QUIET_NaN = 0xffffffff
-+QUIET_NaN = 0x7fffffff
- SIGNL_NaN = 0x7f800001
- INFINITY = 0x7f800000
-
-@@ -2614,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
-@@ -2936,7 +2942,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
-