]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/experimental/simd/tests/bits/verify.h
1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
18 #ifndef TESTS_BITS_VERIFY_H_
19 #define TESTS_BITS_VERIFY_H_
21 #include <experimental/simd>
26 #ifdef _GLIBCXX_SIMD_HAVE_NEON
27 // work around PR89357:
28 #define alignas(...) __attribute__((aligned(__VA_ARGS__)))
31 using schar
= signed char;
32 using uchar
= unsigned char;
33 using ushort
= unsigned short;
34 using uint
= unsigned int;
35 using ulong
= unsigned long;
36 using llong
= long long;
37 using ullong
= unsigned long long;
38 using ldouble
= long double;
39 using wchar
= wchar_t;
40 using char16
= char16_t
;
41 using char32
= char32_t
;
45 make_value_unknown(const T
& x
)
47 if constexpr (std::is_constructible_v
<T
, const volatile T
&>)
49 const volatile T
& y
= x
;
62 const bool m_failed
= false;
66 typename
= decltype(std::declval
<std::stringstream
&>()
67 << std::declval
<const T
&>())>
69 print(const T
& x
, int) const
73 __builtin_fprintf(stderr
, "%s", ss
.str().c_str());
78 print(const T
& x
, ...) const
80 if constexpr (std::experimental::is_simd_v
<T
>)
83 if constexpr (std::is_floating_point_v
<typename
T::value_type
>)
85 ss
<< '(' << x
[0] << " == " << std::hexfloat
<< x
[0]
86 << std::defaultfloat
<< ')';
87 for (unsigned i
= 1; i
< x
.size(); ++i
)
89 ss
<< (i
% 4 == 0 ? ",\n(" : ", (") << x
[i
]
90 << " == " << std::hexfloat
<< x
[i
] << std::defaultfloat
97 for (unsigned i
= 1; i
< x
.size(); ++i
)
102 __builtin_fprintf(stderr
, "%s", ss
.str().c_str());
104 else if constexpr (std::experimental::is_simd_mask_v
<T
>)
106 __builtin_fprintf(stderr
, (x
[0] ? "[1" : "[0"));
107 for (unsigned i
= 1; i
< x
.size(); ++i
)
109 __builtin_fprintf(stderr
, (x
[i
] ? "1" : "0"));
111 __builtin_fprintf(stderr
, "]");
115 print_hex(&x
, sizeof(T
));
120 print_hex(const void* x
, std::size_t n
) const
122 __builtin_fprintf(stderr
, "0x");
123 const auto* bytes
= static_cast<const unsigned char*>(x
);
124 for (std::size_t i
= 0; i
< n
; ++i
)
126 __builtin_fprintf(stderr
, (i
&& i
% 4 == 0) ? "'%02x" : "%02x",
132 template <typename
... Ts
>
133 [[gnu::always_inline
]]
134 verify(bool ok
, const char* file
, const int line
,
135 const char* func
, const char* cond
, const Ts
&... extra_info
)
136 : m_failed(!ok
), m_ip(get_ip())
140 __builtin_fprintf(stderr
, "%s:%d: (%s):\nInstruction Pointer: %zx\n"
141 "Assertion '%s' failed.\n",
142 file
, line
, func
, m_ip
, cond
);
143 (print(extra_info
, int()), ...);
147 [[gnu::always_inline
]] ~verify()
151 __builtin_fprintf(stderr
, "\n");
156 template <typename T
>
157 [[gnu::always_inline
]]
159 operator<<(const T
& x
) const
166 template <typename
... Ts
>
167 [[gnu::always_inline
]]
169 on_failure(const Ts
&... xs
) const
172 [&] { (print(xs
, int()), ...); }();
176 [[gnu::always_inline
]] static inline
182 asm volatile("lea 0(%%rip),%0" : "=r"(_ip
));
183 #elif defined __i386__
184 asm volatile("1: movl $1b,%0" : "=r"(_ip
));
185 #elif defined __arm__
186 asm volatile("mov %0,pc" : "=r"(_ip
));
187 #elif defined __aarch64__
188 asm volatile("adr %0,." : "=r"(_ip
));
194 #if __FLT_EVAL_METHOD__ != 0
195 template <typename T
>
196 [[gnu::always_inline
]] inline decltype(auto)
197 force_fp_truncation(const T
& x
)
199 namespace stdx
= std::experimental
;
200 if constexpr (stdx::is_simd_v
<T
>)
202 using U
= typename
T::value_type
;
203 if constexpr (std::is_floating_point_v
<typename
T::value_type
>
204 && sizeof(U
) <= 8 && (sizeof(T
) < 16 || std::is_same_v
<
205 T
, stdx::fixed_size_simd
<U
, T::size()>>))
214 else if constexpr (std::is_floating_point_v
<T
> && sizeof(T
) <= 8)
224 #define COMPARE(_a, _b) \
225 [&](auto&& _aa, auto&& _bb) { \
226 return verify(std::experimental::all_of(_aa == _bb), __FILE__, __LINE__, \
227 __PRETTY_FUNCTION__, #_a " == " #_b, #_a " = ", _aa, \
228 "\n" #_b " = ", _bb); \
229 }(force_fp_truncation(_a), force_fp_truncation(_b))
231 #define COMPARE(_a, _b) \
232 [&](auto&& _aa, auto&& _bb) { \
233 return verify(std::experimental::all_of(_aa == _bb), __FILE__, __LINE__, \
234 __PRETTY_FUNCTION__, #_a " == " #_b, #_a " = ", _aa, \
235 "\n" #_b " = ", _bb); \
239 #define VERIFY(_test) \
240 verify(_test, __FILE__, __LINE__, __PRETTY_FUNCTION__, #_test)
242 // ulp_distance_signed can raise FP exceptions and thus must be conditionally
244 #define ULP_COMPARE(_a, _b, _allowed_distance) \
245 [&](auto&& _aa, auto&& _bb) { \
246 const bool success = std::experimental::all_of( \
247 vir::test::ulp_distance(_aa, _bb) <= (_allowed_distance)); \
248 return verify(success, __FILE__, __LINE__, __PRETTY_FUNCTION__, \
249 #_a " ~~ " #_b, #_a " = ", _aa, "\n" #_b " = ", _bb, \
251 success ? 0 : vir::test::ulp_distance_signed(_aa, _bb)); \
257 template <typename T
>
258 inline T _S_fuzzyness
= 0;
260 template <typename T
>
263 { _S_fuzzyness
<T
> = x
; }
267 #define FUZZY_COMPARE(_a, _b) \
270 vir::test::_S_fuzzyness<vir::test::value_type_t<decltype((_a) + (_b))>>)
272 template <typename V
>
276 template <typename V
>
281 template <typename V
, typename
= decltype(V())>
286 __builtin_fprintf(stderr
, "PASS: %s\n", __PRETTY_FUNCTION__
);
289 #endif // TESTS_BITS_VERIFY_H_