gtk: import patch to support softfloat targets
authorDaniel Golle <daniel@makrotopia.org>
Sat, 7 Dec 2024 19:58:30 +0000 (19:58 +0000)
committerDaniel Golle <daniel@makrotopia.org>
Sat, 7 Dec 2024 21:56:37 +0000 (21:56 +0000)
Use work-around for missing fesetround() options on targets without
floating point unit.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
frameworks/gtk/patches/001-gtkcssnumbervalue-Don-t-use-fesetround-on-softfloat.patch [new file with mode: 0644]

diff --git a/frameworks/gtk/patches/001-gtkcssnumbervalue-Don-t-use-fesetround-on-softfloat.patch b/frameworks/gtk/patches/001-gtkcssnumbervalue-Don-t-use-fesetround-on-softfloat.patch
new file mode 100644 (file)
index 0000000..a4c6c51
--- /dev/null
@@ -0,0 +1,77 @@
+From: Simon McVittie <smcv@debian.org>
+Date: Sat, 31 Aug 2024 10:13:48 +0100
+Subject: gtkcssnumbervalue: Don't use fesetround() on softfloat
+
+Older ARM CPUs have to emulate floating-point in software, and do not
+implement rounding modes other than the default, FE_TONEAREST.
+Implement nearbyint() the hard way when targeting an affected platform.
+
+Bug-Debian: https://bugs.debian.org/1079545
+Signed-off-by: Simon McVittie <smcv@debian.org>
+[daniel@makrotopia.org: also handle MIPS soft-float]
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ gtk/gtkcssnumbervalue.c | 34 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 34 insertions(+)
+
+--- a/gtk/gtkcssnumbervalue.c
++++ b/gtk/gtkcssnumbervalue.c
+@@ -1846,11 +1846,21 @@ gtk_css_dimension_value_is_zero (const G
+   return value->dimension.value == 0;
+ }
++#if (defined(__arm__) && !defined(__ARM_PCS_VFP)) || defined(__mips_soft_float)
++/* Floating-point emulated in software. Setting the rounding mode to
++ * anything other than FE_TONEAREST doesn't work */
++#undef HAVE_WORKING_FESETROUND
++#else
++#define HAVE_WORKING_FESETROUND
++#endif
++
+ static double
+ _round (guint mode, double a, double b)
+ {
++#ifdef HAVE_WORKING_FESETROUND
+   int old_mode;
+   int modes[] = { FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO };
++#endif
+   double result;
+   if (b == 0)
+@@ -1880,12 +1890,36 @@ _round (guint mode, double a, double b)
+         }
+     }
++#ifdef HAVE_WORKING_FESETROUND
+   old_mode = fegetround ();
+   fesetround (modes[mode]);
+   result = nearbyint (a/b) * b;
+   fesetround (old_mode);
++#else
++  result = a / b;
++
++  switch (mode)
++    {
++    case ROUND_NEAREST:
++      result = round (result);
++      break;
++    case ROUND_TO_ZERO:
++      result = (result >= 0 ? floor (result) : ceil (result));
++      break;
++    case ROUND_UP:
++      result = ceil (result);
++      break;
++    case ROUND_DOWN:
++      result = floor (result);
++      break;
++    default:
++      g_assert_not_reached ();
++    }
++
++  result *= b;
++#endif
+   return result;
+ }