@@ -21,6 +21,8 @@
#include <fenv.h>
#include <fpu_control.h>
+#include <stdint.h>
+#include <math.h>
static __always_inline void
libc_feholdexcept_aarch64 (fenv_t *envp)
@@ -298,25 +300,20 @@ libc_feresetround_noex_aarch64_ctx (struct rm_ctx *ctx)
#define libc_feresetround_noexf_ctx libc_feresetround_noex_aarch64_ctx
#define libc_feresetround_noexl_ctx libc_feresetround_noex_aarch64_ctx
-/* Hack: only include the large arm_neon.h when needed. */
-#ifdef _MATH_CONFIG_H
-# include <arm_neon.h>
-
-/* ACLE intrinsics for frintn and fcvtns instructions. */
-# define TOINT_INTRINSICS 1
+/* Use inline round and lround instructions. */
+#define TOINT_INTRINSICS 1
static inline double_t
roundtoint (double_t x)
{
- return vget_lane_f64 (vrndn_f64 (vld1_f64 (&x)), 0);
+ return round (x);
}
-static inline uint64_t
+static inline int32_t
converttoint (double_t x)
{
- return vcvtnd_s64_f64 (x);
+ return lround (x);
}
-#endif
#include_next <math_private.h>
@@ -85,10 +85,7 @@ __expf (float x)
#if TOINT_INTRINSICS
kd = roundtoint (z);
ki = converttoint (z);
-#elif TOINT_RINT
- kd = rint (z);
- ki = (long) kd;
-#elif TOINT_SHIFT
+#else
# define SHIFT __exp2f_data.shift
kd = math_narrow_eval ((double) (z + SHIFT)); /* Needs to be double. */
ki = asuint64 (kd);
@@ -38,13 +38,23 @@
#endif
#ifndef TOINT_INTRINSICS
+/* When set, the roundtoint and converttoint functions are provided with
+ the semantics documented below. */
# define TOINT_INTRINSICS 0
#endif
-#ifndef TOINT_RINT
-# define TOINT_RINT 0
-#endif
-#ifndef TOINT_SHIFT
-# define TOINT_SHIFT 1
+
+#if TOINT_INTRINSICS
+/* Round x to nearest int in all rounding modes, ties have to be rounded
+ consistently with converttoint so the results match. If the result
+ would be outside of [-2^31, 2^31-1] then the semantics is unspecified. */
+static inline double_t
+roundtoint (double_t x);
+
+/* Convert x to nearest int in all rounding modes, ties have to be rounded
+ consistently with roundtoint. If the result is not representible in an
+ int32_t then the semantics is unspecified. */
+static inline int32_t
+converttoint (double_t x);
#endif
static inline uint32_t