summaryrefslogtreecommitdiff
path: root/libre/iceweasel/firefox-93.0_x86_math_private_20211110.patch
blob: bdc8890616386882cc42b115e9c6274198378497 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
diff -w -ruN firefox-93.0.org/modules/fdlibm/src/math_private.h firefox-93.0/modules/fdlibm/src/math_private.h
--- firefox-93.0.org/modules/fdlibm/src/math_private.h	2021-09-27 16:47:42.000000000 -0600
+++ firefox-93.0/modules/fdlibm/src/math_private.h	2021-11-10 17:39:03.495621830 -0600
@@ -30,9 +30,13 @@
  * Adapted from https://github.com/freebsd/freebsd-src/search?q=__double_t
  */
 
+#ifdef __LP64__
 typedef double      __double_t;
+#else
+typedef long double __double_t;
+#endif
 typedef __double_t  double_t;
-
+typedef float   __float_t;
 /*
  * The original fdlibm code used statements like:
  *	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
@@ -630,6 +634,53 @@
 	return ((double)(x + 0x1.8p52) - 0x1.8p52);
 }
 
+static inline float
+rnintf(__float_t x)
+{
+	/*
+	 * As for rnint(), except we could just call that to handle the
+	 * extra precision case, usually without losing efficiency.
+	 */
+	return ((float)(x + 0x1.8p23F) - 0x1.8p23F);
+}
+
+#ifdef LDBL_MANT_DIG
+/*
+ * The complications for extra precision are smaller for rnintl() since it
+ * can safely assume that the rounding precision has been increased from
+ * its default to FP_PE on x86.  We don't exploit that here to get small
+ * optimizations from limiting the rangle to double.  We just need it for
+ * the magic number to work with long doubles.  ld128 callers should use
+ * rnint() instead of this if possible.  ld80 callers should prefer
+ * rnintl() since for amd64 this avoids swapping the register set, while
+ * for i386 it makes no difference (assuming FP_PE), and for other arches
+ * it makes little difference.
+ */
+
+static inline long double
+rnintl(long double x)
+{
+  /* The WRAPPED__CONCAT() macro below is required for non-FreeBSD targets
+     which don't have a multi-level CONCAT macro implementation. On those
+     targets the hexadecimal floating-point values being created don't expand
+     properly resulting in code that cannot be compiled.
+
+     The extra level provided by this macro should not affect FreeBSD, should
+     this code be used there.
+
+     See the following for more details:
+
+       https://gcc.gnu.org/onlinedocs/gcc-3.0.1/cpp_3.html#SEC32
+       https://sources.debian.org/src/glibc/2.32-3/misc/sys/cdefs.h/
+       https://github.com/freebsd/freebsd-src/blob/main/sys/sys/cdefs.h
+  */
+	#define WRAPPED__CONCAT(x,y) __CONCAT(x,y)
+
+	return (x + WRAPPED__CONCAT(0x1.8p, LDBL_MANT_DIG) / 2 -
+		WRAPPED__CONCAT(0x1.8p, LDBL_MANT_DIG) / 2);
+}
+#endif /* LDBL_MANT_DIG */
+
 /*
  * irint() and i64rint() give the same result as casting to their integer
  * return type provided their arg is a floating point integer.  They can
@@ -646,6 +697,39 @@
 #define	irint(x)	((int)(x))
 #endif
 
+#define	i64rint(x)	((int64_t)(x))	/* only needed for ld128 so not opt. */
+
+#if defined(__i386__) && defined(__GNUCLIKE_ASM)
+static __inline int
+irintf(float x)
+{
+	int n;
+
+	__asm("fistl %0" : "=m" (n) : "t" (x));
+	return (n);
+}
+
+static __inline int
+irintd(double x)
+{
+	int n;
+
+	__asm("fistl %0" : "=m" (n) : "t" (x));
+	return (n);
+}
+#endif
+
+#if (defined(__amd64__) || defined(__i386__)) && defined(__GNUCLIKE_ASM)
+static __inline int
+irintl(long double x)
+{
+	int n;
+
+	__asm("fistl %0" : "=m" (n) : "t" (x));
+	return (n);
+}
+#endif
+
 #ifdef DEBUG
 #if defined(__amd64__) || defined(__i386__)
 #define	breakpoint()	asm("int $3")