Coverage Report

Created: 2025-07-01 06:18

/src/WasmEdge/include/common/roundeven.h
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: 2019-2024 Second State INC
3
4
//===-- wasmedge/common/roundeven.h - rounding to nearest integer ---------===//
5
//
6
// Part of the WasmEdge Project.
7
//
8
//===----------------------------------------------------------------------===//
9
///
10
/// \file
11
/// This file contents the helper function for rounding to nearest integer.
12
///
13
//===----------------------------------------------------------------------===//
14
#pragma once
15
16
#include "errcode.h"
17
18
#include <cfenv>
19
#include <cmath>
20
#include <cstdint>
21
#include <cstring>
22
#include <type_traits>
23
24
#ifndef __has_builtin
25
#define __has_builtin(x) 0
26
#endif
27
28
#if defined(__GLIBC_PREREQ)
29
#if __GLIBC_PREREQ(2, 26) && __has_builtin(__builtin_roundeven)
30
#define HAVE_BUILTIN_ROUNDEVEN 1
31
#elif defined(__clang__) && __has_builtin(__builtin_roundeven)
32
#define HAVE_BUILTIN_ROUNDEVEN 1
33
#endif
34
#endif
35
#if !__has_builtin(__builtin_is_constant_evaluated)
36
#define __builtin_is_constant_evaluated() false
37
#endif
38
39
namespace WasmEdge {
40
namespace detail {
41
42
0
inline float roundevenf(float Value) {
43
0
#if defined(HAVE_BUILTIN_ROUNDEVEN)
44
0
  return __builtin_roundevenf(Value);
45
#elif defined(__AVX512F__)
46
  float Ret;
47
  __asm__("vrndscaless $8, %0, %1, %1" : "=v"(Ret) : "v"(Value));
48
  return Ret;
49
#elif defined(__AVX__)
50
  float Ret;
51
  __asm__("vroundss $8, %1, %1, %0" : "=v"(Ret) : "v"(Value));
52
  return Ret;
53
#elif defined(__SSE4_1__)
54
  float Ret;
55
  __asm__("roundss $8, %1, %0" : "=v"(Ret) : "v"(Value));
56
  return Ret;
57
#elif defined(__aarch64__)
58
  float Ret;
59
  __asm__("frintn %s0, %s1" : "=w"(Ret) : "w"(Value));
60
  return Ret;
61
#else
62
  assuming(fegetround() == FE_TONEAREST);
63
  return std::nearbyint(Value);
64
#endif
65
0
}
66
67
0
inline double roundeven(double Value) noexcept {
68
0
#if defined(HAVE_BUILTIN_ROUNDEVEN)
69
0
  return __builtin_roundeven(Value);
70
#elif defined(__AVX512F__)
71
  double Ret;
72
  __asm__("vrndscalesd $8, %0, %1, %1" : "=v"(Ret) : "v"(Value));
73
  return Ret;
74
#elif defined(__AVX__)
75
  double Ret;
76
  __asm__("vroundsd $8, %1, %1, %0" : "=v"(Ret) : "v"(Value));
77
  return Ret;
78
#elif defined(__SSE4_1__)
79
  double Ret;
80
  __asm__("roundsd $8, %1, %0" : "=v"(Ret) : "v"(Value));
81
  return Ret;
82
#elif defined(__aarch64__)
83
  double Ret;
84
  __asm__("frintn %d0, %d1" : "=w"(Ret) : "w"(Value));
85
  return Ret;
86
#else
87
  assuming(fegetround() == FE_TONEAREST);
88
  return std::nearbyint(Value);
89
#endif
90
0
}
91
92
} // namespace detail
93
94
using detail::roundeven;
95
0
inline float roundeven(float Value) { return detail::roundevenf(Value); }
96
97
} // namespace WasmEdge