math: add single precision error handling functions
authorSzabolcs Nagy <nsz@port70.net>
Sun, 22 Oct 2017 13:51:35 +0000 (13:51 +0000)
committerRich Felker <dalias@aerifal.cx>
Wed, 17 Apr 2019 17:08:42 +0000 (13:08 -0400)
These are supposed to be used in tail call positions when handling
special cases in new code. (fp exceptions may be raised "naturally"
by the common code path if special casing is more effort.)

This implements the error handling apis used in
https://github.com/ARM-software/optimized-routines
without errno setting.

src/internal/libm.h
src/math/__math_divzerof.c [new file with mode: 0644]
src/math/__math_invalidf.c [new file with mode: 0644]
src/math/__math_oflowf.c [new file with mode: 0644]
src/math/__math_uflowf.c [new file with mode: 0644]
src/math/__math_xflowf.c [new file with mode: 0644]

index 09fcfde39eac5b9a50ccc958753a8e80fbfde5ae..a52a0b83888914e4c92d7439b78f4c7f845ba4b8 100644 (file)
@@ -216,4 +216,11 @@ extern int __signgam;
 hidden double __lgamma_r(double, int *);
 hidden float __lgammaf_r(float, int *);
 
+/* error handling functions */
+hidden float __math_xflowf(uint32_t, float);
+hidden float __math_uflowf(uint32_t);
+hidden float __math_oflowf(uint32_t);
+hidden float __math_divzerof(uint32_t);
+hidden float __math_invalidf(float);
+
 #endif
diff --git a/src/math/__math_divzerof.c b/src/math/__math_divzerof.c
new file mode 100644 (file)
index 0000000..ce046f3
--- /dev/null
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float __math_divzerof(uint32_t sign)
+{
+       return fp_barrierf(sign ? -1.0f : 1.0f) / 0.0f;
+}
diff --git a/src/math/__math_invalidf.c b/src/math/__math_invalidf.c
new file mode 100644 (file)
index 0000000..357d4b1
--- /dev/null
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float __math_invalidf(float x)
+{
+       return (x - x) / (x - x);
+}
diff --git a/src/math/__math_oflowf.c b/src/math/__math_oflowf.c
new file mode 100644 (file)
index 0000000..fa7d062
--- /dev/null
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float __math_oflowf(uint32_t sign)
+{
+       return __math_xflowf(sign, 0x1p97f);
+}
diff --git a/src/math/__math_uflowf.c b/src/math/__math_uflowf.c
new file mode 100644 (file)
index 0000000..94d50f2
--- /dev/null
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float __math_uflowf(uint32_t sign)
+{
+       return __math_xflowf(sign, 0x1p-95f);
+}
diff --git a/src/math/__math_xflowf.c b/src/math/__math_xflowf.c
new file mode 100644 (file)
index 0000000..f2c8478
--- /dev/null
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float __math_xflowf(uint32_t sign, float y)
+{
+       return eval_as_float(fp_barrierf(sign ? -y : y) * y);
+}