[libc-commits] [libc] [libc][mathvec][aarch64] Add AdvSIMD optimised expf (PR #206776)

via libc-commits libc-commits at lists.llvm.org
Tue Jul 7 07:55:35 PDT 2026


================
@@ -0,0 +1,120 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains an AdvSIMD architecture optimised single-precision expf.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/mathvec/expf.h"
+#include "arm_neon.h"
+#include "src/__support/common.h"
+#include "src/__support/mathvec/expf_utils.h"
+#include "src/mathvec/aarch64/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr struct expf_data {
+  float64x2_t shift, inv_ln2;
+  double ln2_hi, ln2_lo;
+  double c1, c3;
+  float64x2_t c0, c2;
+  float32x4_t range_val;
+  uint32x4_t inf;
+  uint64x2_t idx_mask;
+  const uint64_t *mantissa;
+} expf_data = {
+    V2(0x1.800000000ffc0p+46), // shift
+    V2(0x1.71547652b82fep+0),  // inv_ln2
+    0x1.62e42fefa39efp-1,      // ln2_hi
+    0x1.abc9e3b39803fp-56,     // ln2_lo
+    0x1.55555555543c2p-3,      // c1
+    0x1.111126b4eff73p-7,      // c3
+    V2(0x1.fffffffffdbcep-2),  // c0
+    V2(0x1.555573c64f2e3p-5),  // c2
+    V4(0x1p+9),                // range_val
+    V4(0x7f800000),            // inf
+    V2(0x3f),                  // idx_mask
+    mathvec::EXP_MANTISSA,     // mantissa
+};
+
+LIBC_INLINE static float64x2_t exp_lookup(uint64x2_t u,
+                                          const struct expf_data *data) {
+  uint64_t idx0 = vgetq_lane_u64(u & data->idx_mask, 0);
+  uint64_t idx1 = vgetq_lane_u64(u & data->idx_mask, 1);
+
+  uint64_t mant0 = data->mantissa[idx0];
+  uint64_t mant1 = data->mantissa[idx1];
+
+  uint64x2_t mantissa = vdupq_n_u64(mant0);
+  mantissa = vsetq_lane_u64(mant1, mantissa, 1);
+
+  uint64x2_t mask = vdupq_n_u64(0xfff0000000000000);
+  uint64x2_t exponent = vshlq_n_u64(u, 46);
----------------
lntue wrote:

Can the magic number `46` be explained?  Either in the comments or computed from named constants?

https://github.com/llvm/llvm-project/pull/206776


More information about the libc-commits mailing list