Coverage Report

Created: 2026-11-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/include/experimental/math.hpp
Line
Count
Source
1
// SPDX-License-Identifier: CC0-1.0
2
///
3
// math - A C++17 implementation of roundeven, and a NaN quieting helper
4
//
5
// To the extent possible under law, the author(s) have dedicated all
6
// copyright and related and neighboring rights to this software to the
7
// public domain worldwide. This software is distributed without any warranty.
8
//
9
// You should have received a copy of the CC0 Public Domain Dedication
10
// along with this software. If not, see
11
// <http://creativecommons.org/publicdomain/zero/1.0/>.
12
///
13
14
#pragma once
15
16
#include "experimental/assume.hpp"
17
#include "experimental/bit.hpp"
18
19
#include <cfenv>
20
#include <cmath>
21
#include <cstdint>
22
#include <limits>
23
#include <type_traits>
24
25
#if defined(__has_builtin) && defined(__GLIBC_PREREQ)
26
#if __has_builtin(__builtin_roundeven) &&                                      \
27
    (__GLIBC_PREREQ(2, 26) || defined(__clang__))
28
#define CXX26_HAS_BUILTIN_ROUNDEVEN 1
29
#endif
30
#endif
31
32
namespace cxx26 {
33
34
0
inline float roundeven(float Value) noexcept {
35
0
#if defined(CXX26_HAS_BUILTIN_ROUNDEVEN)
36
0
  return __builtin_roundevenf(Value);
37
0
#elif defined(__AVX512F__)
38
0
  float Ret;
39
0
  __asm__("vrndscaless $8, %0, %1, %1" : "=v"(Ret) : "v"(Value));
40
0
  return Ret;
41
0
#elif defined(__AVX__)
42
0
  float Ret;
43
0
  __asm__("vroundss $8, %1, %1, %0" : "=v"(Ret) : "v"(Value));
44
0
  return Ret;
45
0
#elif defined(__SSE4_1__)
46
0
  float Ret;
47
0
  __asm__("roundss $8, %1, %0" : "=v"(Ret) : "v"(Value));
48
0
  return Ret;
49
0
#elif defined(__aarch64__)
50
0
  float Ret;
51
0
  __asm__("frintn %s0, %s1" : "=w"(Ret) : "w"(Value));
52
0
  return Ret;
53
0
#else
54
0
  CXX23_ASSUME(std::fegetround() == FE_TONEAREST);
55
0
  return std::nearbyint(Value);
56
0
#endif
57
0
}
58
59
0
inline double roundeven(double Value) noexcept {
60
0
#if defined(CXX26_HAS_BUILTIN_ROUNDEVEN)
61
0
  return __builtin_roundeven(Value);
62
0
#elif defined(__AVX512F__)
63
0
  double Ret;
64
0
  __asm__("vrndscalesd $8, %0, %1, %1" : "=v"(Ret) : "v"(Value));
65
0
  return Ret;
66
0
#elif defined(__AVX__)
67
0
  double Ret;
68
0
  __asm__("vroundsd $8, %1, %1, %0" : "=v"(Ret) : "v"(Value));
69
0
  return Ret;
70
0
#elif defined(__SSE4_1__)
71
0
  double Ret;
72
0
  __asm__("roundsd $8, %1, %0" : "=v"(Ret) : "v"(Value));
73
0
  return Ret;
74
0
#elif defined(__aarch64__)
75
0
  double Ret;
76
0
  __asm__("frintn %d0, %d1" : "=w"(Ret) : "w"(Value));
77
0
  return Ret;
78
0
#else
79
0
  CXX23_ASSUME(std::fegetround() == FE_TONEAREST);
80
0
  return std::nearbyint(Value);
81
0
#endif
82
0
}
83
84
// Non-standard. Returns Value with the most significant payload bit set when
85
// it is a NaN, which makes a signaling NaN quiet. IEEE 754 operations quiet a
86
// signaling NaN, but some libm functions return it unchanged.
87
0
template <class T> T quiet_nan(T Value) noexcept {
88
0
  static_assert(std::is_floating_point_v<T>);
89
0
  using U = std::conditional_t<sizeof(T) == 4, std::uint32_t, std::uint64_t>;
90
0
  if (!std::isnan(Value)) {
91
0
    return Value;
92
0
  }
93
0
  return cxx20::bit_cast<T>(cxx20::bit_cast<U>(Value) |
94
0
                            U{1} << (std::numeric_limits<T>::digits - 2));
95
0
}
Unexecuted instantiation: float cxx26::quiet_nan<float>(float)
Unexecuted instantiation: double cxx26::quiet_nan<double>(double)
96
97
} // namespace cxx26
98
99
#undef CXX26_HAS_BUILTIN_ROUNDEVEN