// Copyright (C) 2020-2024 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . #ifndef SIMD_TESTS_BITS_MATHREFERENCE_H_ #define SIMD_TESTS_BITS_MATHREFERENCE_H_ #include #include #include template struct SincosReference { T x, s, c; std::tuple as_tuple() const { return std::tie(x, s, c); } }; template struct Reference { T x, ref; std::tuple as_tuple() const { return std::tie(x, ref); } }; template struct Array { std::size_t size_; const T *data_; Array() : size_(0), data_(nullptr) {} Array(size_t s, const T *p) : size_(s), data_(p) {} const T* begin() const { return data_; } const T* end() const { return data_ + size_; } std::size_t size() const { return size_; } }; namespace function { struct sincos{ static constexpr const char *const str = "sincos"; }; struct atan { static constexpr const char *const str = "atan"; }; struct asin { static constexpr const char *const str = "asin"; }; struct acos { static constexpr const char *const str = "acos"; }; struct log { static constexpr const char *const str = "ln"; }; struct log2 { static constexpr const char *const str = "log2"; }; struct log10 { static constexpr const char *const str = "log10"; }; } template struct testdatatype_for_function { template using type = Reference; }; template <> struct testdatatype_for_function { template using type = SincosReference; }; template using testdatatype_for_function_t = typename testdatatype_for_function::template type; template struct StaticDeleter { const T *ptr; StaticDeleter(const T *p) : ptr(p) {} ~StaticDeleter() { delete[] ptr; } }; template inline std::string filename() { static_assert(std::is_floating_point::value, ""); static const auto cache = std::string("reference-") + F::str + (sizeof(T) == 4 && std::__digits_v == 24 && std::__max_exponent_v == 128 ? "-sp" : (sizeof(T) == 8 && std::__digits_v == 53 && std::__max_exponent_v == 1024 ? "-dp" : (sizeof(T) == 16 && std::__digits_v == 64 && std::__max_exponent_v == 16384 ? "-ep" : (sizeof(T) == 16 && std::__digits_v == 113 && std::__max_exponent_v == 16384 ? "-qp" : "-unknown")))) + ".dat"; return cache; } template > Array referenceData() { static Array data; if (data.data_ == nullptr) { FILE* file = std::fopen(filename().c_str(), "rb"); if (file) { std::fseek(file, 0, SEEK_END); const size_t size = std::ftell(file) / sizeof(Ref); std::rewind(file); auto mem = new Ref[size]; static StaticDeleter _cleanup(data.data_); data.size_ = std::fread(mem, sizeof(Ref), size, file); data.data_ = mem; std::fclose(file); } else { __builtin_fprintf( stderr, "%s:%d: the reference data %s does not exist in the current " "working directory.\n", __FILE__, __LINE__, filename().c_str()); __builtin_abort(); } } return data; } #endif // SIMD_TESTS_BITS_MATHREFERENCE_H_