about summary refs log tree commit diff
path: root/sysdeps/ieee754/flt-32/math_config.h
diff options
context:
space:
mode:
authorSzabolcs Nagy <szabolcs.nagy@arm.com>2017-09-04 17:55:33 +0100
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2017-09-29 11:51:12 +0100
commite260a9f8a9279c231405593c449e1f5bd39b3fd1 (patch)
tree7b80b0dc7fab5bec38a78ebbf13b940386873294 /sysdeps/ieee754/flt-32/math_config.h
parenteb38f71b3504ac132b5c65ba23a15ddb9d02a435 (diff)
downloadglibc-e260a9f8a9279c231405593c449e1f5bd39b3fd1.tar.gz
glibc-e260a9f8a9279c231405593c449e1f5bd39b3fd1.tar.xz
glibc-e260a9f8a9279c231405593c449e1f5bd39b3fd1.zip
New generic powf
without wrapper on aarch64:
powf reciprocal-throughput: 4.2x faster
powf latency: 2.6x faster
old worst-case error: 1.11 ulp
new worst-case error: 0.82 ulp
aarch64 .text size: -780 bytes
aarch64 .rodata size: +144 bytes

powf(x,y) is implemented as exp2(y*log2(x)) with the same algorithms
that are used in exp2f and log2f, except that the log2f polynomial is
larger for extra precision and its output (and exp2f input) may be
scaled by a power of 2 (POWF_SCALE) to simplify the argument reduction
step of exp2 (possible when efficient round and convert toint operation
is available).

The special case handling tries to minimize the checks in the hot path.
When the input of exp2_inline is checked, int arithmetics is used as
that was faster on the tested aarch64 cores.

2017-09-19  Szabolcs Nagy  <szabolcs.nagy@arm.com>

	* math/Makefile (type-float-routines): Add e_powf_log2_data.
	* sysdeps/ieee754/flt-32/e_powf.c: New implementation.
	* sysdeps/ieee754/flt-32/e_powf_log2_data.c: New file.
	* sysdeps/ieee754/flt-32/math_config.h (__powf_data): Define.
	(issignalingf_inline): Likewise.
	(POWF_LOG2_TABLE_BITS): Likewise.
	(POWF_LOG2_POLY_ORDER): Likewise.
	(POWF_SCALE_BITS): Likewise.
	(POWF_SCALE): Likewise.
	* sysdeps/i386/fpu/e_powf_log2_data.c: New file.
	* sysdeps/ia64/fpu/e_powf_log2_data.c: New file.
	* sysdeps/m68k/m680x0/fpu/e_powf_log2_data.c: New file.
Diffstat (limited to 'sysdeps/ieee754/flt-32/math_config.h')
-rw-r--r--sysdeps/ieee754/flt-32/math_config.h27
1 files changed, 27 insertions, 0 deletions
diff --git a/sysdeps/ieee754/flt-32/math_config.h b/sysdeps/ieee754/flt-32/math_config.h
index f869fbc66c..7e78cb0c96 100644
--- a/sysdeps/ieee754/flt-32/math_config.h
+++ b/sysdeps/ieee754/flt-32/math_config.h
@@ -21,6 +21,7 @@
 
 #include <math.h>
 #include <math_private.h>
+#include <nan-high-order-bit.h>
 #include <stdint.h>
 
 #ifndef WANT_ROUNDING
@@ -90,6 +91,15 @@ asdouble (uint64_t i)
   return u.f;
 }
 
+static inline int
+issignalingf_inline (float x)
+{
+  uint32_t ix = asuint (x);
+  if (HIGH_ORDER_BIT_IS_SET_FOR_SNAN)
+    return (ix & 0x7fc00000) == 0x7fc00000;
+  return 2 * (ix ^ 0x00400000) > 2u * 0x7fc00000;
+}
+
 #define NOINLINE __attribute__ ((noinline))
 
 attribute_hidden float __math_oflowf (unsigned long);
@@ -134,4 +144,21 @@ extern const struct log2f_data
   double poly[LOG2F_POLY_ORDER];
 } __log2f_data attribute_hidden;
 
+#define POWF_LOG2_TABLE_BITS 4
+#define POWF_LOG2_POLY_ORDER 5
+#if TOINT_INTRINSICS
+#define POWF_SCALE_BITS EXP2F_TABLE_BITS
+#else
+#define POWF_SCALE_BITS 0
+#endif
+#define POWF_SCALE ((double) (1 << POWF_SCALE_BITS))
+extern const struct powf_log2_data
+{
+  struct
+  {
+    double invc, logc;
+  } tab[1 << POWF_LOG2_TABLE_BITS];
+  double poly[POWF_LOG2_POLY_ORDER];
+} __powf_log2_data attribute_hidden;
+
 #endif