diff options
Diffstat (limited to 'libc')
497 files changed, 14524 insertions, 2389 deletions
diff --git a/libc/benchmarks/gpu/BenchmarkLogger.cpp b/libc/benchmarks/gpu/BenchmarkLogger.cpp deleted file mode 100644 index d5996a7..0000000 --- a/libc/benchmarks/gpu/BenchmarkLogger.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include "benchmarks/gpu/BenchmarkLogger.h" -#include "hdr/stdint_proxy.h" -#include "src/__support/CPP/string.h" -#include "src/__support/CPP/string_view.h" -#include "src/__support/OSUtil/io.h" // write_to_stderr -#include "src/__support/big_int.h" // is_big_int -#include "src/__support/macros/config.h" -#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128 -#include "src/__support/uint128.h" - -namespace LIBC_NAMESPACE_DECL { -namespace benchmarks { - -// cpp::string_view specialization -template <> -BenchmarkLogger & - BenchmarkLogger::operator<< <cpp::string_view>(cpp::string_view str) { - LIBC_NAMESPACE::write_to_stderr(str); - return *this; -} - -// cpp::string specialization -template <> -BenchmarkLogger &BenchmarkLogger::operator<< <cpp::string>(cpp::string str) { - return *this << static_cast<cpp::string_view>(str); -} - -// const char* specialization -template <> -BenchmarkLogger &BenchmarkLogger::operator<< <const char *>(const char *str) { - return *this << cpp::string_view(str); -} - -// char* specialization -template <> BenchmarkLogger &BenchmarkLogger::operator<< <char *>(char *str) { - return *this << cpp::string_view(str); -} - -// char specialization -template <> BenchmarkLogger &BenchmarkLogger::operator<<(char ch) { - return *this << cpp::string_view(&ch, 1); -} - -// bool specialization -template <> BenchmarkLogger &BenchmarkLogger::operator<<(bool cond) { - return *this << (cond ? "true" : "false"); -} - -// void * specialization -template <> BenchmarkLogger &BenchmarkLogger::operator<<(void *addr) { - return *this << "0x" << cpp::to_string(reinterpret_cast<uintptr_t>(addr)); -} - -template <typename T> BenchmarkLogger &BenchmarkLogger::operator<<(T t) { - if constexpr (is_big_int_v<T> || - (cpp::is_integral_v<T> && cpp::is_unsigned_v<T> && - (sizeof(T) > sizeof(uint64_t)))) { - static_assert(sizeof(T) % 8 == 0, "Unsupported size of UInt"); - const IntegerToString<T, radix::Hex::WithPrefix> buffer(t); - return *this << buffer.view(); - } else { - return *this << cpp::to_string(t); - } -} - -// is_integral specializations -// char is already specialized to handle character -template BenchmarkLogger &BenchmarkLogger::operator<< <short>(short); -template BenchmarkLogger &BenchmarkLogger::operator<< <int>(int); -template BenchmarkLogger &BenchmarkLogger::operator<< <long>(long); -template BenchmarkLogger &BenchmarkLogger::operator<< <long long>(long long); -template BenchmarkLogger & - BenchmarkLogger::operator<< <unsigned char>(unsigned char); -template BenchmarkLogger & - BenchmarkLogger::operator<< <unsigned short>(unsigned short); -template BenchmarkLogger & - BenchmarkLogger::operator<< <unsigned int>(unsigned int); -template BenchmarkLogger & - BenchmarkLogger::operator<< <unsigned long>(unsigned long); -template BenchmarkLogger & - BenchmarkLogger::operator<< <unsigned long long>(unsigned long long); - -#ifdef LIBC_TYPES_HAS_INT128 -template BenchmarkLogger & - BenchmarkLogger::operator<< <__uint128_t>(__uint128_t); -#endif // LIBC_TYPES_HAS_INT128 -template BenchmarkLogger &BenchmarkLogger::operator<< <UInt<128>>(UInt<128>); -template BenchmarkLogger &BenchmarkLogger::operator<< <UInt<192>>(UInt<192>); -template BenchmarkLogger &BenchmarkLogger::operator<< <UInt<256>>(UInt<256>); -template BenchmarkLogger &BenchmarkLogger::operator<< <UInt<320>>(UInt<320>); - -// TODO: Add floating point formatting once it's supported by StringStream. - -BenchmarkLogger log; - -} // namespace benchmarks -} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/benchmarks/gpu/BenchmarkLogger.h b/libc/benchmarks/gpu/BenchmarkLogger.h deleted file mode 100644 index 2b22aba..0000000 --- a/libc/benchmarks/gpu/BenchmarkLogger.h +++ /dev/null @@ -1,29 +0,0 @@ -//===-- Utilities to log to standard output during tests --------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIBC_BENCHMARKS_GPU_BENCHMARKLOGGER_H -#define LLVM_LIBC_BENCHMARKS_GPU_BENCHMARKLOGGER_H - -#include "src/__support/macros/config.h" - -namespace LIBC_NAMESPACE_DECL { -namespace benchmarks { - -// A class to log to standard output in the context of hermetic tests. -struct BenchmarkLogger { - constexpr BenchmarkLogger() = default; - template <typename T> BenchmarkLogger &operator<<(T); -}; - -// A global TestLogger instance to be used in tests. -extern BenchmarkLogger log; - -} // namespace benchmarks -} // namespace LIBC_NAMESPACE_DECL - -#endif /* LLVM_LIBC_BENCHMARKS_GPU_BENCHMARKLOGGER_H */ diff --git a/libc/benchmarks/gpu/CMakeLists.txt b/libc/benchmarks/gpu/CMakeLists.txt index 6ec64bf2..cf8c990 100644 --- a/libc/benchmarks/gpu/CMakeLists.txt +++ b/libc/benchmarks/gpu/CMakeLists.txt @@ -22,8 +22,6 @@ function(add_benchmark benchmark_name) ${BENCHMARK_LINK_LIBRARIES} DEPENDS libc.src.stdio.printf - libc.src.stdlib.srand - libc.src.stdlib.rand ${BENCHMARK_DEPENDS} ${BENCHMARK_UNPARSED_ARGUMENTS} COMPILE_OPTIONS @@ -40,34 +38,31 @@ add_unittest_framework_library( SRCS LibcGpuBenchmark.cpp LibcGpuBenchmarkMain.cpp - BenchmarkLogger.cpp HDRS LibcGpuBenchmark.h - BenchmarkLogger.h + Random.h DEPENDS + libc.benchmarks.gpu.timing.timing libc.hdr.stdint_proxy - libc.src.__support.big_int - libc.src.__support.c_string libc.src.__support.CPP.string libc.src.__support.CPP.string_view libc.src.__support.CPP.type_traits - libc.src.__support.CPP.functional - libc.src.__support.CPP.limits libc.src.__support.CPP.algorithm libc.src.__support.CPP.atomic libc.src.__support.CPP.array - libc.src.__support.fixed_point.fx_rep - libc.src.__support.macros.properties.types - libc.src.__support.OSUtil.osutil - libc.src.__support.uint128 + libc.src.__support.CPP.optional libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.nearest_integer_operations libc.src.__support.FPUtil.sqrt + libc.src.__support.sign libc.src.__support.fixedvector - libc.src.time.clock - libc.src.stdlib.rand - libc.src.stdlib.srand - libc.benchmarks.gpu.timing.timing + libc.src.__support.GPU.utils + libc.src.__support.time.gpu.time_utils + libc.src.__support.macros.attributes + libc.src.__support.macros.config + libc.src.__support.macros.properties.types libc.src.stdio.printf + libc.src.time.clock ) add_subdirectory(src) diff --git a/libc/benchmarks/gpu/LibcGpuBenchmark.cpp b/libc/benchmarks/gpu/LibcGpuBenchmark.cpp index 57ff5b9..a4a0ff4 100644 --- a/libc/benchmarks/gpu/LibcGpuBenchmark.cpp +++ b/libc/benchmarks/gpu/LibcGpuBenchmark.cpp @@ -1,15 +1,18 @@ #include "LibcGpuBenchmark.h" + +#include "hdr/stdint_proxy.h" #include "src/__support/CPP/algorithm.h" -#include "src/__support/CPP/array.h" #include "src/__support/CPP/atomic.h" #include "src/__support/CPP/string.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" #include "src/__support/FPUtil/sqrt.h" #include "src/__support/GPU/utils.h" #include "src/__support/fixedvector.h" #include "src/__support/macros/config.h" #include "src/__support/time/gpu/time_utils.h" #include "src/stdio/printf.h" -#include "src/stdlib/srand.h" +#include "src/time/clock.h" namespace LIBC_NAMESPACE_DECL { namespace benchmarks { @@ -20,37 +23,56 @@ void Benchmark::add_benchmark(Benchmark *benchmark) { benchmarks.push_back(benchmark); } +static void atomic_add_double(cpp::Atomic<uint64_t> &atomic_bits, + double value) { + using FPBits = LIBC_NAMESPACE::fputil::FPBits<double>; + + uint64_t expected_bits = atomic_bits.load(cpp::MemoryOrder::RELAXED); + + while (true) { + double current_value = FPBits(expected_bits).get_val(); + double next_value = current_value + value; + + uint64_t desired_bits = FPBits(next_value).uintval(); + if (atomic_bits.compare_exchange_strong(expected_bits, desired_bits, + cpp::MemoryOrder::ACQUIRE, + cpp::MemoryOrder::RELAXED)) + break; + } +} + struct AtomicBenchmarkSums { - cpp::Atomic<uint64_t> cycles_sum = 0; - cpp::Atomic<uint64_t> standard_deviation_sum = 0; + cpp::Atomic<uint32_t> active_threads = 0; + cpp::Atomic<uint64_t> iterations_sum = 0; + cpp::Atomic<uint64_t> weighted_cycles_sum_bits = 0; + cpp::Atomic<uint64_t> weighted_squared_cycles_sum_bits = 0; cpp::Atomic<uint64_t> min = UINT64_MAX; cpp::Atomic<uint64_t> max = 0; - cpp::Atomic<uint32_t> samples_sum = 0; - cpp::Atomic<uint32_t> iterations_sum = 0; - cpp::Atomic<clock_t> time_sum = 0; - cpp::Atomic<uint64_t> active_threads = 0; void reset() { cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE); active_threads.store(0, cpp::MemoryOrder::RELAXED); - cycles_sum.store(0, cpp::MemoryOrder::RELAXED); - standard_deviation_sum.store(0, cpp::MemoryOrder::RELAXED); + iterations_sum.store(0, cpp::MemoryOrder::RELAXED); + weighted_cycles_sum_bits.store(0, cpp::MemoryOrder::RELAXED); + weighted_squared_cycles_sum_bits.store(0, cpp::MemoryOrder::RELAXED); min.store(UINT64_MAX, cpp::MemoryOrder::RELAXED); max.store(0, cpp::MemoryOrder::RELAXED); - samples_sum.store(0, cpp::MemoryOrder::RELAXED); - iterations_sum.store(0, cpp::MemoryOrder::RELAXED); - time_sum.store(0, cpp::MemoryOrder::RELAXED); cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE); } void update(const BenchmarkResult &result) { cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE); active_threads.fetch_add(1, cpp::MemoryOrder::RELAXED); + iterations_sum.fetch_add(result.total_iterations, + cpp::MemoryOrder::RELAXED); - cycles_sum.fetch_add(result.cycles, cpp::MemoryOrder::RELAXED); - standard_deviation_sum.fetch_add( - static_cast<uint64_t>(result.standard_deviation), - cpp::MemoryOrder::RELAXED); + const double n_i = static_cast<double>(result.total_iterations); + const double mean_i = result.cycles; + const double stddev_i = result.standard_deviation; + const double variance_i = stddev_i * stddev_i; + atomic_add_double(weighted_cycles_sum_bits, n_i * mean_i); + atomic_add_double(weighted_squared_cycles_sum_bits, + n_i * (variance_i + mean_i * mean_i)); // Perform a CAS loop to atomically update the min uint64_t orig_min = min.load(cpp::MemoryOrder::RELAXED); @@ -66,10 +88,6 @@ struct AtomicBenchmarkSums { cpp::MemoryOrder::RELAXED)) ; - samples_sum.fetch_add(result.samples, cpp::MemoryOrder::RELAXED); - iterations_sum.fetch_add(result.total_iterations, - cpp::MemoryOrder::RELAXED); - time_sum.fetch_add(result.total_time, cpp::MemoryOrder::RELAXED); cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE); } }; @@ -79,46 +97,51 @@ constexpr auto GREEN = "\033[32m"; constexpr auto RESET = "\033[0m"; void print_results(Benchmark *b) { - BenchmarkResult result; + using FPBits = LIBC_NAMESPACE::fputil::FPBits<double>; + + BenchmarkResult final_result; cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE); - int num_threads = all_results.active_threads.load(cpp::MemoryOrder::RELAXED); - result.cycles = - all_results.cycles_sum.load(cpp::MemoryOrder::RELAXED) / num_threads; - result.standard_deviation = - all_results.standard_deviation_sum.load(cpp::MemoryOrder::RELAXED) / - num_threads; - result.min = all_results.min.load(cpp::MemoryOrder::RELAXED); - result.max = all_results.max.load(cpp::MemoryOrder::RELAXED); - result.samples = - all_results.samples_sum.load(cpp::MemoryOrder::RELAXED) / num_threads; - result.total_iterations = - all_results.iterations_sum.load(cpp::MemoryOrder::RELAXED) / num_threads; - const uint64_t duration_ns = - all_results.time_sum.load(cpp::MemoryOrder::RELAXED) / num_threads; - const uint64_t duration_us = duration_ns / 1000; - const uint64_t duration_ms = duration_ns / (1000 * 1000); - uint64_t converted_duration = duration_ns; - const char *time_unit; - if (duration_ms != 0) { - converted_duration = duration_ms; - time_unit = "ms"; - } else if (duration_us != 0) { - converted_duration = duration_us; - time_unit = "us"; + + const uint32_t num_threads = + all_results.active_threads.load(cpp::MemoryOrder::RELAXED); + final_result.total_iterations = + all_results.iterations_sum.load(cpp::MemoryOrder::RELAXED); + + if (final_result.total_iterations > 0) { + const uint64_t s1_bits = + all_results.weighted_cycles_sum_bits.load(cpp::MemoryOrder::RELAXED); + const uint64_t s2_bits = all_results.weighted_squared_cycles_sum_bits.load( + cpp::MemoryOrder::RELAXED); + + const double S1 = FPBits(s1_bits).get_val(); + const double S2 = FPBits(s2_bits).get_val(); + const double N = static_cast<double>(final_result.total_iterations); + + const double global_mean = S1 / N; + const double global_mean_of_squares = S2 / N; + const double global_variance = + global_mean_of_squares - (global_mean * global_mean); + + final_result.cycles = global_mean; + final_result.standard_deviation = + fputil::sqrt<double>(global_variance < 0.0 ? 0.0 : global_variance); } else { - converted_duration = duration_ns; - time_unit = "ns"; + final_result.cycles = 0.0; + final_result.standard_deviation = 0.0; } - result.total_time = converted_duration; - // result.total_time = - // all_results.time_sum.load(cpp::MemoryOrder::RELAXED) / num_threads; + + final_result.min = all_results.min.load(cpp::MemoryOrder::RELAXED); + final_result.max = all_results.max.load(cpp::MemoryOrder::RELAXED); cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE); LIBC_NAMESPACE::printf( - "%-24s |%8ld |%8ld |%8ld |%11d |%14ld %2s |%9ld |%9d |\n", - b->get_test_name().data(), result.cycles, result.min, result.max, - result.total_iterations, result.total_time, time_unit, - static_cast<uint64_t>(result.standard_deviation), num_threads); + "%-24s |%15.0f |%9.0f |%8llu |%8llu |%15llu |%9u |\n", + b->get_test_name().data(), final_result.cycles, + final_result.standard_deviation, + static_cast<unsigned long long>(final_result.min), + static_cast<unsigned long long>(final_result.max), + static_cast<unsigned long long>(final_result.total_iterations), + static_cast<unsigned>(num_threads)); } void print_header() { @@ -126,9 +149,8 @@ void print_header() { LIBC_NAMESPACE::printf("Running Suite: %-10s\n", benchmarks[0]->get_suite_name().data()); LIBC_NAMESPACE::printf("%s", RESET); - cpp::string titles = - "Benchmark | Cycles | Min | Max | " - "Iterations | Time / Iteration | Stddev | Threads |\n"; + cpp::string titles = "Benchmark | Cycles (Mean) | Stddev | " + " Min | Max | Iterations | Threads |\n"; LIBC_NAMESPACE::printf(titles.data()); cpp::string separator(titles.size(), '-'); @@ -139,10 +161,8 @@ void print_header() { void Benchmark::run_benchmarks() { uint64_t id = gpu::get_thread_id(); - if (id == 0) { + if (id == 0) print_header(); - LIBC_NAMESPACE::srand(gpu::processor_clock()); - } gpu::sync_threads(); @@ -164,69 +184,64 @@ void Benchmark::run_benchmarks() { } BenchmarkResult benchmark(const BenchmarkOptions &options, - cpp::function<uint64_t(void)> wrapper_func) { + const BenchmarkTarget &target) { BenchmarkResult result; RuntimeEstimationProgression rep; - uint32_t total_iterations = 0; uint32_t iterations = options.initial_iterations; + if (iterations < 1u) iterations = 1; uint32_t samples = 0; uint64_t total_time = 0; - uint64_t best_guess = 0; - uint64_t cycles_squared = 0; uint64_t min = UINT64_MAX; uint64_t max = 0; - uint64_t overhead = UINT64_MAX; - int overhead_iterations = 10; - for (int i = 0; i < overhead_iterations; i++) - overhead = cpp::min(overhead, LIBC_NAMESPACE::overhead()); + uint32_t call_index = 0; for (int64_t time_budget = options.max_duration; time_budget >= 0;) { - uint64_t sample_cycles = 0; - const clock_t start = static_cast<double>(clock()); - for (uint32_t i = 0; i < iterations; i++) { - auto wrapper_intermediate = wrapper_func(); - uint64_t current_result = wrapper_intermediate - overhead; + RefinableRuntimeEstimator sample_estimator; + + const clock_t start = clock(); + while (sample_estimator.get_iterations() < iterations) { + auto current_result = target(call_index++); max = cpp::max(max, current_result); min = cpp::min(min, current_result); - sample_cycles += current_result; + sample_estimator.update(current_result); } const clock_t end = clock(); + const clock_t duration_ns = ((end - start) * 1000 * 1000 * 1000) / CLOCKS_PER_SEC; total_time += duration_ns; time_budget -= duration_ns; samples++; - cycles_squared += sample_cycles * sample_cycles; - total_iterations += iterations; - const double change_ratio = - rep.compute_improvement({iterations, sample_cycles}); - best_guess = rep.current_estimation; + const double change_ratio = rep.compute_improvement(sample_estimator); if (samples >= options.max_samples || iterations >= options.max_iterations) break; + + const auto total_iterations = rep.get_estimator().get_iterations(); + if (total_time >= options.min_duration && samples >= options.min_samples && total_iterations >= options.min_iterations && change_ratio < options.epsilon) break; - iterations *= options.scaling_factor; + iterations = static_cast<uint32_t>( + fputil::ceil(iterations * options.scaling_factor)); } - result.cycles = best_guess; - result.standard_deviation = fputil::sqrt<double>( - static_cast<double>(cycles_squared) / total_iterations - - static_cast<double>(best_guess * best_guess)); + + const auto &estimator = rep.get_estimator(); + result.total_iterations = estimator.get_iterations(); + result.cycles = estimator.get_mean(); + result.standard_deviation = estimator.get_stddev(); result.min = min; result.max = max; - result.samples = samples; - result.total_iterations = total_iterations; - result.total_time = total_time / total_iterations; + return result; -}; +} } // namespace benchmarks } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/benchmarks/gpu/LibcGpuBenchmark.h b/libc/benchmarks/gpu/LibcGpuBenchmark.h index a6cf62d..b310d49 100644 --- a/libc/benchmarks/gpu/LibcGpuBenchmark.h +++ b/libc/benchmarks/gpu/LibcGpuBenchmark.h @@ -1,18 +1,18 @@ #ifndef LLVM_LIBC_BENCHMARKS_LIBC_GPU_BENCHMARK_H #define LLVM_LIBC_BENCHMARKS_LIBC_GPU_BENCHMARK_H -#include "benchmarks/gpu/BenchmarkLogger.h" +#include "benchmarks/gpu/Random.h" + #include "benchmarks/gpu/timing/timing.h" + #include "hdr/stdint_proxy.h" +#include "src/__support/CPP/algorithm.h" #include "src/__support/CPP/array.h" -#include "src/__support/CPP/functional.h" -#include "src/__support/CPP/limits.h" #include "src/__support/CPP/string_view.h" #include "src/__support/CPP/type_traits.h" #include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/sqrt.h" #include "src/__support/macros/config.h" -#include "src/stdlib/rand.h" -#include "src/time/clock.h" namespace LIBC_NAMESPACE_DECL { @@ -30,68 +30,136 @@ struct BenchmarkOptions { double scaling_factor = 1.4; }; -struct Measurement { +class RefinableRuntimeEstimator { uint32_t iterations = 0; - uint64_t elapsed_cycles = 0; -}; - -class RefinableRuntimeEstimation { - uint64_t total_cycles = 0; - uint32_t total_iterations = 0; + uint64_t sum_of_cycles = 0; + uint64_t sum_of_squared_cycles = 0; public: - uint64_t update(const Measurement &M) { - total_cycles += M.elapsed_cycles; - total_iterations += M.iterations; - return total_cycles / total_iterations; + void update(uint64_t cycles) noexcept { + iterations += 1; + sum_of_cycles += cycles; + sum_of_squared_cycles += cycles * cycles; + } + + void update(const RefinableRuntimeEstimator &other) noexcept { + iterations += other.iterations; + sum_of_cycles += other.sum_of_cycles; + sum_of_squared_cycles += other.sum_of_squared_cycles; } + + double get_mean() const noexcept { + if (iterations == 0) + return 0.0; + + return static_cast<double>(sum_of_cycles) / iterations; + } + + double get_variance() const noexcept { + if (iterations == 0) + return 0.0; + + const double num = static_cast<double>(iterations); + const double sum_x = static_cast<double>(sum_of_cycles); + const double sum_x2 = static_cast<double>(sum_of_squared_cycles); + + const double mean_of_squares = sum_x2 / num; + const double mean = sum_x / num; + const double mean_squared = mean * mean; + const double variance = mean_of_squares - mean_squared; + + return variance < 0.0 ? 0.0 : variance; + } + + double get_stddev() const noexcept { + return fputil::sqrt<double>(get_variance()); + } + + uint32_t get_iterations() const noexcept { return iterations; } }; // Tracks the progression of the runtime estimation class RuntimeEstimationProgression { - RefinableRuntimeEstimation rre; + RefinableRuntimeEstimator estimator; + double current_mean = 0.0; public: - uint64_t current_estimation = 0; + const RefinableRuntimeEstimator &get_estimator() const noexcept { + return estimator; + } + + double + compute_improvement(const RefinableRuntimeEstimator &sample_estimator) { + if (sample_estimator.get_iterations() == 0) + return 1.0; - double compute_improvement(const Measurement &M) { - const uint64_t new_estimation = rre.update(M); - double ratio = - (static_cast<double>(current_estimation) / new_estimation) - 1.0; + estimator.update(sample_estimator); - // Get absolute value + const double new_mean = estimator.get_mean(); + if (current_mean == 0.0 || new_mean == 0.0) { + current_mean = new_mean; + return 1.0; + } + + double ratio = (current_mean / new_mean) - 1.0; if (ratio < 0) - ratio *= -1; + ratio = -ratio; - current_estimation = new_estimation; + current_mean = new_mean; return ratio; } }; struct BenchmarkResult { - uint64_t cycles = 0; + uint64_t total_iterations = 0; + double cycles = 0; double standard_deviation = 0; uint64_t min = UINT64_MAX; uint64_t max = 0; - uint32_t samples = 0; - uint32_t total_iterations = 0; - clock_t total_time = 0; +}; + +struct BenchmarkTarget { + using IndexedFnPtr = uint64_t (*)(uint32_t); + using IndexlessFnPtr = uint64_t (*)(); + + enum class Kind : uint8_t { Indexed, Indexless } kind; + union { + IndexedFnPtr indexed_fn_ptr; + IndexlessFnPtr indexless_fn_ptr; + }; + + LIBC_INLINE BenchmarkTarget(IndexedFnPtr func) + : kind(Kind::Indexed), indexed_fn_ptr(func) {} + LIBC_INLINE BenchmarkTarget(IndexlessFnPtr func) + : kind(Kind::Indexless), indexless_fn_ptr(func) {} + + LIBC_INLINE uint64_t operator()([[maybe_unused]] uint32_t call_index) const { + return kind == Kind::Indexed ? indexed_fn_ptr(call_index) + : indexless_fn_ptr(); + } }; BenchmarkResult benchmark(const BenchmarkOptions &options, - cpp::function<uint64_t(void)> wrapper_func); + const BenchmarkTarget &target); class Benchmark { - const cpp::function<uint64_t(void)> func; + const BenchmarkTarget target; const cpp::string_view suite_name; const cpp::string_view test_name; const uint32_t num_threads; public: - Benchmark(cpp::function<uint64_t(void)> func, char const *suite_name, + Benchmark(uint64_t (*f)(), const char *suite, const char *test, + uint32_t threads) + : target(BenchmarkTarget(f)), suite_name(suite), test_name(test), + num_threads(threads) { + add_benchmark(this); + } + + Benchmark(uint64_t (*f)(uint32_t), char const *suite_name, char const *test_name, uint32_t num_threads) - : func(func), suite_name(suite_name), test_name(test_name), - num_threads(num_threads) { + : target(BenchmarkTarget(f)), suite_name(suite_name), + test_name(test_name), num_threads(num_threads) { add_benchmark(this); } @@ -105,67 +173,49 @@ protected: private: BenchmarkResult run() { BenchmarkOptions options; - return benchmark(options, func); + return benchmark(options, target); } }; -// We want our random values to be approximately -// Output: a random number with the exponent field between min_exp and max_exp, -// i.e. 2^min_exp <= |real_value| < 2^(max_exp + 1), -// Caveats: -// -EXP_BIAS corresponding to denormal values, -// EXP_BIAS + 1 corresponding to inf or nan. -template <typename T> -static T -get_rand_input(int max_exp = LIBC_NAMESPACE::fputil::FPBits<T>::EXP_BIAS, - int min_exp = -LIBC_NAMESPACE::fputil::FPBits<T>::EXP_BIAS) { - using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; - - // Required to correctly instantiate FPBits for floats and doubles. - using RandType = typename cpp::conditional_t<(cpp::is_same_v<T, double>), - uint64_t, uint32_t>; - RandType bits; - if constexpr (cpp::is_same_v<T, uint64_t>) - bits = (static_cast<uint64_t>(LIBC_NAMESPACE::rand()) << 32) | - static_cast<uint64_t>(LIBC_NAMESPACE::rand()); - else - bits = LIBC_NAMESPACE::rand(); - double scale = - static_cast<double>(max_exp - min_exp + 1) / (2 * FPBits::EXP_BIAS + 1); - FPBits fp(bits); - fp.set_biased_exponent( - static_cast<uint32_t>(fp.get_biased_exponent() * scale + min_exp)); - return fp.get_val(); -} - template <typename T> class MathPerf { - using FPBits = fputil::FPBits<T>; - using StorageType = typename FPBits::StorageType; - static constexpr StorageType UIntMax = - cpp::numeric_limits<StorageType>::max(); + static LIBC_INLINE uint64_t make_seed(uint64_t base_seed, uint64_t salt) { + const uint64_t tid = gpu::get_thread_id(); + return base_seed ^ (salt << 32) ^ (tid * 0x9E3779B97F4A7C15ULL); + } public: - template <size_t N = 1> - static uint64_t run_throughput_in_range(T f(T), int min_exp, int max_exp) { + // Returns cycles-per-call (lower is better) + template <size_t N = 1, typename Dist> + static uint64_t run_throughput(T (*f)(T), const Dist &dist, + uint32_t call_index) { cpp::array<T, N> inputs; + + uint64_t base_seed = static_cast<uint64_t>(call_index); + uint64_t salt = static_cast<uint64_t>(N); + RandomGenerator rng(make_seed(base_seed, salt)); + for (size_t i = 0; i < N; ++i) - inputs[i] = get_rand_input<T>(min_exp, max_exp); + inputs[i] = dist(rng); uint64_t total_time = LIBC_NAMESPACE::throughput(f, inputs); return total_time / N; } - // Throughput benchmarking for functions that take 2 inputs. - template <size_t N = 1> - static uint64_t run_throughput_in_range(T f(T, T), int arg1_min_exp, - int arg1_max_exp, int arg2_min_exp, - int arg2_max_exp) { + // Returns cycles-per-call (lower is better) + template <size_t N = 1, typename Dist1, typename Dist2> + static uint64_t run_throughput(T (*f)(T, T), const Dist1 &dist1, + const Dist2 &dist2, uint32_t call_index) { cpp::array<T, N> inputs1; cpp::array<T, N> inputs2; + + uint64_t base_seed = static_cast<uint64_t>(call_index); + uint64_t salt = static_cast<uint64_t>(N); + RandomGenerator rng(make_seed(base_seed, salt)); + for (size_t i = 0; i < N; ++i) { - inputs1[i] = get_rand_input<T>(arg1_min_exp, arg1_max_exp); - inputs2[i] = get_rand_input<T>(arg2_min_exp, arg2_max_exp); + inputs1[i] = dist1(rng); + inputs2[i] = dist2(rng); } uint64_t total_time = LIBC_NAMESPACE::throughput(f, inputs1, inputs2); @@ -193,4 +243,5 @@ public: #define SINGLE_WAVE_BENCHMARK(SuiteName, TestName, Func) \ BENCHMARK_N_THREADS(SuiteName, TestName, Func, \ LIBC_NAMESPACE::gpu::get_lane_size()) -#endif + +#endif // LLVM_LIBC_BENCHMARKS_LIBC_GPU_BENCHMARK_H diff --git a/libc/benchmarks/gpu/Random.h b/libc/benchmarks/gpu/Random.h new file mode 100644 index 0000000..f7d2722 --- /dev/null +++ b/libc/benchmarks/gpu/Random.h @@ -0,0 +1,190 @@ +//===-- Pseudo-random number generation utilities ---------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_BENCHMARKS_GPU_RANDOM_H +#define LLVM_LIBC_BENCHMARKS_GPU_RANDOM_H + +#include "hdr/stdint_proxy.h" +#include "src/__support/CPP/algorithm.h" +#include "src/__support/CPP/optional.h" +#include "src/__support/CPP/type_traits.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/macros/attributes.h" +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" +#include "src/__support/sign.h" + +namespace LIBC_NAMESPACE_DECL { +namespace benchmarks { + +// Pseudo-random number generator (PRNG) that produces unsigned 64-bit, 32-bit, +// and 16-bit integers. The implementation is based on the xorshift* generator, +// seeded using SplitMix64 for robust initialization. For more details, see: +// https://en.wikipedia.org/wiki/Xorshift +class RandomGenerator { + uint64_t state; + + static LIBC_INLINE uint64_t splitmix64(uint64_t x) noexcept { + x += 0x9E3779B97F4A7C15ULL; + x = (x ^ (x >> 30)) * 0xBF58476D1CE4E5B9ULL; + x = (x ^ (x >> 27)) * 0x94D049BB133111EBULL; + x = (x ^ (x >> 31)); + return x ? x : 0x9E3779B97F4A7C15ULL; + } + +public: + explicit LIBC_INLINE RandomGenerator(uint64_t seed) noexcept + : state(splitmix64(seed)) {} + + LIBC_INLINE uint64_t next64() noexcept { + uint64_t x = state; + x ^= x >> 12; + x ^= x << 25; + x ^= x >> 27; + state = x; + return x * 0x2545F4914F6CDD1DULL; + } + + LIBC_INLINE uint32_t next32() noexcept { + return static_cast<uint32_t>(next64() >> 32); + } + + LIBC_INLINE uint16_t next16() noexcept { + return static_cast<uint16_t>(next64() >> 48); + } +}; + +// Generates random floating-point numbers where the unbiased binary exponent +// is sampled uniformly in `[min_exp, max_exp]`. The significand bits are +// always randomized, while the sign is randomized by default but can be fixed. +// Evenly covers orders of magnitude; never yields Inf/NaN. +template <typename T> class UniformExponent { + static_assert(cpp::is_same_v<T, float16> || cpp::is_same_v<T, float> || + cpp::is_same_v<T, double>, + "UniformExponent supports float16, float, and double"); + + using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; + using Storage = typename FPBits::StorageType; + +public: + explicit UniformExponent(int min_exp = -FPBits::EXP_BIAS, + int max_exp = FPBits::EXP_BIAS, + cpp::optional<Sign> forced_sign = cpp::nullopt) + : min_exp(clamp_exponent(cpp::min(min_exp, max_exp))), + max_exp(clamp_exponent(cpp::max(min_exp, max_exp))), + forced_sign(forced_sign) {} + + LIBC_INLINE T operator()(RandomGenerator &rng) const noexcept { + // Sample unbiased exponent e uniformly in [min_exp, max_exp] without modulo + // bias, using rejection sampling + auto sample_in_range = [&](uint64_t r) -> int32_t { + const uint64_t range = static_cast<uint64_t>( + static_cast<int64_t>(max_exp) - static_cast<int64_t>(min_exp) + 1); + const uint64_t threshold = (-range) % range; + while (r < threshold) + r = rng.next64(); + return static_cast<int32_t>(min_exp + static_cast<int64_t>(r % range)); + }; + const int32_t e = sample_in_range(rng.next64()); + + // Start from random bits to get random sign and mantissa + FPBits xbits([&] { + if constexpr (cpp::is_same_v<T, double>) + return FPBits(rng.next64()); + else if constexpr (cpp::is_same_v<T, float>) + return FPBits(rng.next32()); + else + return FPBits(rng.next16()); + }()); + + if (e == -FPBits::EXP_BIAS) { + // Subnormal: biased exponent must be 0; ensure mantissa != 0 to avoid 0 + xbits.set_biased_exponent(Storage(0)); + if (xbits.get_mantissa() == Storage(0)) + xbits.set_mantissa(Storage(1)); + } else { + // Normal: biased exponent in [1, 2 * FPBits::EXP_BIAS] + const int32_t biased = e + FPBits::EXP_BIAS; + xbits.set_biased_exponent(static_cast<Storage>(biased)); + } + + if (forced_sign) + xbits.set_sign(*forced_sign); + + return xbits.get_val(); + } + +private: + static LIBC_INLINE int clamp_exponent(int val) noexcept { + if (val < -FPBits::EXP_BIAS) + return -FPBits::EXP_BIAS; + + if (val > FPBits::EXP_BIAS) + return FPBits::EXP_BIAS; + + return val; + } + + const int min_exp; + const int max_exp; + const cpp::optional<Sign> forced_sign; +}; + +// Generates random floating-point numbers that are uniformly distributed on +// a linear scale. Values are sampled from `[min_val, max_val)`. +template <typename T> class UniformLinear { + static_assert(cpp::is_same_v<T, float16> || cpp::is_same_v<T, float> || + cpp::is_same_v<T, double>, + "UniformLinear supports float16, float, and double"); + + using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; + using Storage = typename FPBits::StorageType; + + static constexpr T MAX_NORMAL = FPBits::max_normal().get_val(); + +public: + explicit UniformLinear(T min_val = -MAX_NORMAL, T max_val = MAX_NORMAL) + : min_val(clamp_val(cpp::min(min_val, max_val))), + max_val(clamp_val(cpp::max(min_val, max_val))) {} + + LIBC_INLINE T operator()(RandomGenerator &rng) const noexcept { + double u = standard_uniform(rng.next64()); + double a = static_cast<double>(min_val); + double b = static_cast<double>(max_val); + double y = a + (b - a) * u; + return static_cast<T>(y); + } + +private: + static LIBC_INLINE T clamp_val(T val) noexcept { + if (val < -MAX_NORMAL) + return -MAX_NORMAL; + + if (val > MAX_NORMAL) + return MAX_NORMAL; + + return val; + } + + static LIBC_INLINE double standard_uniform(uint64_t x) noexcept { + constexpr int PREC_BITS = + LIBC_NAMESPACE::fputil::FPBits<double>::SIG_LEN + 1; + constexpr int SHIFT_BITS = LIBC_NAMESPACE::fputil::FPBits<double>::EXP_LEN; + constexpr double INV = 1.0 / static_cast<double>(1ULL << PREC_BITS); + + return static_cast<double>(x >> SHIFT_BITS) * INV; + } + + const T min_val; + const T max_val; +}; + +} // namespace benchmarks +} // namespace LIBC_NAMESPACE_DECL + +#endif diff --git a/libc/benchmarks/gpu/src/math/CMakeLists.txt b/libc/benchmarks/gpu/src/math/CMakeLists.txt index 7a12ce4e..53da45d 100644 --- a/libc/benchmarks/gpu/src/math/CMakeLists.txt +++ b/libc/benchmarks/gpu/src/math/CMakeLists.txt @@ -25,20 +25,19 @@ if(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU) endif() add_benchmark( - sin_benchmark + atan2_benchmark SUITE libc-gpu-math-benchmarks SRCS - sin_benchmark.cpp + atan2_benchmark.cpp + HDRS + platform.h DEPENDS libc.hdr.stdint_proxy - libc.src.math.sin - libc.src.math.sinf - libc.src.stdlib.srand - libc.src.stdlib.rand - libc.src.__support.FPUtil.fp_bits - libc.src.__support.CPP.bit - libc.src.__support.CPP.array + libc.src.__support.macros.attributes + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.math.atan2 COMPILE_OPTIONS ${math_benchmark_flags} LOADER_ARGS @@ -46,19 +45,143 @@ add_benchmark( ) add_benchmark( - atan2_benchmark + exp_benchmark SUITE libc-gpu-math-benchmarks SRCS - atan2_benchmark.cpp + exp_benchmark.cpp + HDRS + platform.h DEPENDS libc.hdr.stdint_proxy - libc.src.math.atan2 - libc.src.stdlib.srand - libc.src.stdlib.rand - libc.src.__support.FPUtil.fp_bits - libc.src.__support.CPP.bit - libc.src.__support.CPP.array + libc.src.__support.macros.attributes + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.math.exp + COMPILE_OPTIONS + ${math_benchmark_flags} + LOADER_ARGS + --threads 64 +) + +add_benchmark( + expf_benchmark + SUITE + libc-gpu-math-benchmarks + SRCS + expf_benchmark.cpp + HDRS + platform.h + DEPENDS + libc.hdr.stdint_proxy + libc.src.__support.macros.attributes + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.math.expf + COMPILE_OPTIONS + ${math_benchmark_flags} + LOADER_ARGS + --threads 64 +) + +add_benchmark( + expf16_benchmark + SUITE + libc-gpu-math-benchmarks + SRCS + expf16_benchmark.cpp + HDRS + platform.h + DEPENDS + libc.hdr.stdint_proxy + libc.src.__support.macros.attributes + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.math.expf16 + COMPILE_OPTIONS + ${math_benchmark_flags} + LOADER_ARGS + --threads 64 +) + +add_benchmark( + log_benchmark + SUITE + libc-gpu-math-benchmarks + SRCS + log_benchmark.cpp + HDRS + platform.h + DEPENDS + libc.hdr.stdint_proxy + libc.src.__support.macros.attributes + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.__support.sign + libc.src.math.log + COMPILE_OPTIONS + ${math_benchmark_flags} + LOADER_ARGS + --threads 64 +) + +add_benchmark( + logf_benchmark + SUITE + libc-gpu-math-benchmarks + SRCS + logf_benchmark.cpp + HDRS + platform.h + DEPENDS + libc.hdr.stdint_proxy + libc.src.__support.macros.attributes + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.__support.sign + libc.src.math.logf + COMPILE_OPTIONS + ${math_benchmark_flags} + LOADER_ARGS + --threads 64 +) + +add_benchmark( + logf16_benchmark + SUITE + libc-gpu-math-benchmarks + SRCS + logf16_benchmark.cpp + HDRS + platform.h + DEPENDS + libc.hdr.stdint_proxy + libc.src.__support.macros.attributes + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.__support.sign + libc.src.math.logf16 + COMPILE_OPTIONS + ${math_benchmark_flags} + LOADER_ARGS + --threads 64 +) + +add_benchmark( + sin_benchmark + SUITE + libc-gpu-math-benchmarks + SRCS + sin_benchmark.cpp + HDRS + platform.h + DEPENDS + libc.hdr.stdint_proxy + libc.src.__support.macros.attributes + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.math.sin + libc.src.math.sinf COMPILE_OPTIONS ${math_benchmark_flags} LOADER_ARGS diff --git a/libc/benchmarks/gpu/src/math/atan2_benchmark.cpp b/libc/benchmarks/gpu/src/math/atan2_benchmark.cpp index 1f91a9a..6039f0c 100644 --- a/libc/benchmarks/gpu/src/math/atan2_benchmark.cpp +++ b/libc/benchmarks/gpu/src/math/atan2_benchmark.cpp @@ -1,27 +1,30 @@ #include "benchmarks/gpu/LibcGpuBenchmark.h" +#include "hdr/stdint_proxy.h" #include "src/math/atan2.h" -#include "src/stdlib/rand.h" #if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND) #include "platform.h" #endif -#define BM_TWO_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, N) \ - []() { \ - return LIBC_NAMESPACE::benchmarks::MathPerf<T>::run_throughput_in_range< \ - N>(Func, MIN_EXP, MAX_EXP, MIN_EXP, MAX_EXP); \ +#define BM_RANDOM_INPUTS(T, Func, MinExp, MaxExp, N) \ + [](uint32_t call_index) { \ + using namespace LIBC_NAMESPACE::benchmarks; \ + \ + const UniformExponent<T> dist(MinExp, MaxExp); \ + return MathPerf<T>::template run_throughput<N>(Func, dist, dist, \ + call_index); \ } -#define BENCH(T, Name, Func, MIN_EXP, MAX_EXP) \ +#define BENCH(T, Name, Func, MinExp, MaxExp) \ SINGLE_WAVE_BENCHMARK(LlvmLibcAtan2GpuBenchmark, Name##_1, \ - BM_TWO_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 1)); \ + BM_RANDOM_INPUTS(T, Func, MinExp, MaxExp, 1)); \ SINGLE_WAVE_BENCHMARK(LlvmLibcAtan2GpuBenchmark, Name##_128, \ - BM_TWO_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 128)); \ + BM_RANDOM_INPUTS(T, Func, MinExp, MaxExp, 128)); \ SINGLE_WAVE_BENCHMARK(LlvmLibcAtan2GpuBenchmark, Name##_1024, \ - BM_TWO_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 1024)); \ + BM_RANDOM_INPUTS(T, Func, MinExp, MaxExp, 1024)); \ SINGLE_WAVE_BENCHMARK(LlvmLibcAtan2GpuBenchmark, Name##_4096, \ - BM_TWO_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 4096)) + BM_RANDOM_INPUTS(T, Func, MinExp, MaxExp, 4096)) BENCH(double, Atan2, LIBC_NAMESPACE::atan2, -1023, 1023); BENCH(double, Atan2TwoPi, LIBC_NAMESPACE::atan2, -10, 3); diff --git a/libc/benchmarks/gpu/src/math/exp_benchmark.cpp b/libc/benchmarks/gpu/src/math/exp_benchmark.cpp new file mode 100644 index 0000000..2398c4b --- /dev/null +++ b/libc/benchmarks/gpu/src/math/exp_benchmark.cpp @@ -0,0 +1,59 @@ +//===-- GPU benchmark for exp ---------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "benchmarks/gpu/LibcGpuBenchmark.h" +#include "benchmarks/gpu/Random.h" + +#include "hdr/stdint_proxy.h" +#include "src/math/exp.h" + +#if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND) +#include "platform.h" +#endif + +#define RANDOM_INPUT(T, Func, Dist, Min, Max, N) \ + [](uint32_t call_index) { \ + using namespace LIBC_NAMESPACE::benchmarks; \ + \ + const Dist<T> dist(Min, Max); \ + return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \ + } + +#define BENCH(T, Name, Func, Dist, Min, Max) \ + SINGLE_WAVE_BENCHMARK(LlvmLibcExpGpuBenchmark, Name##_1, \ + RANDOM_INPUT(T, Func, Dist, Min, Max, 1)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcExpGpuBenchmark, Name##_128, \ + RANDOM_INPUT(T, Func, Dist, Min, Max, 128)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcExpGpuBenchmark, Name##_1024, \ + RANDOM_INPUT(T, Func, Dist, Min, Max, 1024)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcExpGpuBenchmark, Name##_4096, \ + RANDOM_INPUT(T, Func, Dist, Min, Max, 4096)) + +using LIBC_NAMESPACE::exp; + +BENCH(double, ExpSubnormal, exp, UniformExponent, -1022, -1022); +BENCH(double, ExpCoreRange, exp, UniformLinear, -10.0, 10.0); +BENCH(double, ExpFinite, exp, UniformLinear, -745.0, 709.0); +BENCH(double, ExpUnderflow, exp, UniformLinear, -746.0, -745.0); +BENCH(double, ExpOverflow, exp, UniformLinear, 709.0, 710.0); + +#ifdef NVPTX_MATH_FOUND +BENCH(double, NvExpSubnormal, __nv_exp, UniformExponent, -1022, -1022); +BENCH(double, NvExpCoreRange, __nv_exp, UniformLinear, -10.0, 10.0); +BENCH(double, NvExpFinite, __nv_exp, UniformLinear, -745.0, 709.0); +BENCH(double, NvExpUnderflow, __nv_exp, UniformLinear, -746.0, -745.0); +BENCH(double, NvExpOverflow, __nv_exp, UniformLinear, 709.0, 710.0); +#endif + +#ifdef AMDGPU_MATH_FOUND +BENCH(double, AmdExpSubnormal, __ocml_exp_f64, UniformExponent, -1022, -1022); +BENCH(double, AmdExpCoreRange, __ocml_exp_f64, UniformLinear, -10.0, 10.0); +BENCH(double, AmdExpFinite, __ocml_exp_f64, UniformLinear, -745.0, 709.0); +BENCH(double, AmdExpUnderflow, __ocml_exp_f64, UniformLinear, -746.0, -745.0); +BENCH(double, AmdExpOverflow, __ocml_exp_f64, UniformLinear, 709.0, 710.0); +#endif diff --git a/libc/benchmarks/gpu/src/math/expf16_benchmark.cpp b/libc/benchmarks/gpu/src/math/expf16_benchmark.cpp new file mode 100644 index 0000000..20e045b --- /dev/null +++ b/libc/benchmarks/gpu/src/math/expf16_benchmark.cpp @@ -0,0 +1,56 @@ +//===-- GPU benchmark for expf16 ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "benchmarks/gpu/LibcGpuBenchmark.h" +#include "benchmarks/gpu/Random.h" + +#include "hdr/stdint_proxy.h" +#include "src/__support/macros/properties/types.h" +#include "src/math/expf16.h" + +#if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND) +#include "platform.h" +#endif + +#define RANDOM_INPUT(T, Func, Dist, Min, Max, N) \ + [](uint32_t call_index) { \ + using namespace LIBC_NAMESPACE::benchmarks; \ + \ + const Dist<T> dist(Min, Max); \ + return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \ + } + +#define BENCH(T, Name, Func, Dist, Min, Max) \ + SINGLE_WAVE_BENCHMARK(LlvmLibcExpf16GpuBenchmark, Name##_1, \ + RANDOM_INPUT(T, Func, Dist, Min, Max, 1)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcExpf16GpuBenchmark, Name##_128, \ + RANDOM_INPUT(T, Func, Dist, Min, Max, 128)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcExpf16GpuBenchmark, Name##_1024, \ + RANDOM_INPUT(T, Func, Dist, Min, Max, 1024)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcExpf16GpuBenchmark, Name##_4096, \ + RANDOM_INPUT(T, Func, Dist, Min, Max, 4096)) + +using LIBC_NAMESPACE::expf16; + +BENCH(float16, Expf16Subnormal, expf16, UniformExponent, -14, -14); +BENCH(float16, Expf16CoreRange, expf16, UniformLinear, -10.0f16, 10.0f16); +BENCH(float16, Expf16Finite, expf16, UniformLinear, -16.0f16, 11.0f16); +BENCH(float16, Expf16Underflow, expf16, UniformLinear, -17.0f16, -16.0f16); +BENCH(float16, Expf16Overflow, expf16, UniformLinear, 11.0f16, 12.0f16); + +#ifdef AMDGPU_MATH_FOUND +BENCH(float16, AmdExpf16Subnormal, __ocml_exp_f16, UniformExponent, -14, -14); +BENCH(float16, AmdExpf16CoreRange, __ocml_exp_f16, UniformLinear, -10.0f16, + 10.0f16); +BENCH(float16, AmdExpf16Finite, __ocml_exp_f16, UniformLinear, -16.0f16, + 11.0f16); +BENCH(float16, AmdExpf16Underflow, __ocml_exp_f16, UniformLinear, -17.0f16, + -16.0f16); +BENCH(float16, AmdExpf16Overflow, __ocml_exp_f16, UniformLinear, 11.0f16, + 12.0f16); +#endif diff --git a/libc/benchmarks/gpu/src/math/expf_benchmark.cpp b/libc/benchmarks/gpu/src/math/expf_benchmark.cpp new file mode 100644 index 0000000..4ef54c5 --- /dev/null +++ b/libc/benchmarks/gpu/src/math/expf_benchmark.cpp @@ -0,0 +1,59 @@ +//===-- GPU benchmark for expf --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "benchmarks/gpu/LibcGpuBenchmark.h" +#include "benchmarks/gpu/Random.h" + +#include "hdr/stdint_proxy.h" +#include "src/math/expf.h" + +#if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND) +#include "platform.h" +#endif + +#define RANDOM_INPUT(T, Func, Dist, Min, Max, N) \ + [](uint32_t call_index) { \ + using namespace LIBC_NAMESPACE::benchmarks; \ + \ + const Dist<T> dist(Min, Max); \ + return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \ + } + +#define BENCH(T, Name, Func, Dist, Min, Max) \ + SINGLE_WAVE_BENCHMARK(LlvmLibcExpfGpuBenchmark, Name##_1, \ + RANDOM_INPUT(T, Func, Dist, Min, Max, 1)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcExpfGpuBenchmark, Name##_128, \ + RANDOM_INPUT(T, Func, Dist, Min, Max, 128)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcExpfGpuBenchmark, Name##_1024, \ + RANDOM_INPUT(T, Func, Dist, Min, Max, 1024)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcExpfGpuBenchmark, Name##_4096, \ + RANDOM_INPUT(T, Func, Dist, Min, Max, 4096)) + +using LIBC_NAMESPACE::expf; + +BENCH(float, ExpfSubnormal, expf, UniformExponent, -126, -126); +BENCH(float, ExpfCoreRange, expf, UniformLinear, -10.0f, 10.0f); +BENCH(float, ExpfFinite, expf, UniformLinear, -103.0f, 88.0f); +BENCH(float, ExpfUnderflow, expf, UniformLinear, -104.0f, -103.0f); +BENCH(float, ExpfOverflow, expf, UniformLinear, 88.0f, 89.0f); + +#ifdef NVPTX_MATH_FOUND +BENCH(float, NvExpfSubnormal, __nv_expf, UniformExponent, -126, -126); +BENCH(float, NvExpfCoreRange, __nv_expf, UniformLinear, -10.0f, 10.0f); +BENCH(float, NvExpfFinite, __nv_expf, UniformLinear, -103.0f, 88.0f); +BENCH(float, NvExpfUnderflow, __nv_expf, UniformLinear, -104.0f, -103.0f); +BENCH(float, NvExpfOverflow, __nv_expf, UniformLinear, 88.0f, 89.0f); +#endif + +#ifdef AMDGPU_MATH_FOUND +BENCH(float, AmdExpfSubnormal, __ocml_exp_f32, UniformExponent, -126, -126); +BENCH(float, AmdExpfCoreRange, __ocml_exp_f32, UniformLinear, -10.0f, 10.0f); +BENCH(float, AmdExpfFinite, __ocml_exp_f32, UniformLinear, -103.0f, 88.0f); +BENCH(float, AmdExpfUnderflow, __ocml_exp_f32, UniformLinear, -104.0f, -103.0f); +BENCH(float, AmdExpfOverflow, __ocml_exp_f32, UniformLinear, 88.0f, 89.0f); +#endif diff --git a/libc/benchmarks/gpu/src/math/log_benchmark.cpp b/libc/benchmarks/gpu/src/math/log_benchmark.cpp new file mode 100644 index 0000000..0ea1906 --- /dev/null +++ b/libc/benchmarks/gpu/src/math/log_benchmark.cpp @@ -0,0 +1,68 @@ +//===-- GPU benchmark for log ---------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "benchmarks/gpu/LibcGpuBenchmark.h" +#include "benchmarks/gpu/Random.h" + +#include "hdr/stdint_proxy.h" +#include "src/__support/sign.h" +#include "src/math/log.h" + +#if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND) +#include "platform.h" +#endif + +#define RANDOM_INPUT_UniformExponent(T, Func, Min, Max, N) \ + [](uint32_t call_index) { \ + using namespace LIBC_NAMESPACE::benchmarks; \ + \ + const UniformExponent<T> dist(Min, Max, LIBC_NAMESPACE::Sign::POS); \ + return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \ + } + +#define RANDOM_INPUT_UniformLinear(T, Func, Min, Max, N) \ + [](uint32_t call_index) { \ + using namespace LIBC_NAMESPACE::benchmarks; \ + \ + const UniformLinear<T> dist(Min, Max); \ + return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \ + } + +#define BENCH(T, Name, Func, Dist, Min, Max) \ + SINGLE_WAVE_BENCHMARK(LlvmLibcLogGpuBenchmark, Name##_1, \ + RANDOM_INPUT_##Dist(T, Func, Min, Max, 1)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcLogGpuBenchmark, Name##_128, \ + RANDOM_INPUT_##Dist(T, Func, Min, Max, 128)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcLogGpuBenchmark, Name##_1024, \ + RANDOM_INPUT_##Dist(T, Func, Min, Max, 1024)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcLogGpuBenchmark, Name##_4096, \ + RANDOM_INPUT_##Dist(T, Func, Min, Max, 4096)) + +using LIBC_NAMESPACE::log; + +static constexpr double INV_E = 0x1.78b56362cef38p-2; // exp(-1.0) +static constexpr double E = 0x1.5bf0a8b145769p+1; // exp(+1.0) + +BENCH(double, LogSubnormal, log, UniformExponent, -1022, -1022); +BENCH(double, LogAroundOne, log, UniformLinear, INV_E, E); +BENCH(double, LogMedMag, log, UniformExponent, -10, 10); +BENCH(double, LogNormal, log, UniformExponent, -1021, 1023); + +#ifdef NVPTX_MATH_FOUND +BENCH(double, NvLogSubnormal, __nv_log, UniformExponent, -1022, -1022); +BENCH(double, NvLogAroundOne, __nv_log, UniformLinear, INV_E, E); +BENCH(double, NvLogMedMag, __nv_log, UniformExponent, -10, 10); +BENCH(double, NvLogNormal, __nv_log, UniformExponent, -1021, 1023); +#endif + +#ifdef AMDGPU_MATH_FOUND +BENCH(double, AmdLogSubnormal, __ocml_log_f64, UniformExponent, -1022, -1022); +BENCH(double, AmdLogAroundOne, __ocml_log_f64, UniformLinear, INV_E, E); +BENCH(double, AmdLogMedMag, __ocml_log_f64, UniformExponent, -10, 10); +BENCH(double, AmdLogNormal, __ocml_log_f64, UniformExponent, -1021, 1023); +#endif diff --git a/libc/benchmarks/gpu/src/math/logf16_benchmark.cpp b/libc/benchmarks/gpu/src/math/logf16_benchmark.cpp new file mode 100644 index 0000000..9748e15 --- /dev/null +++ b/libc/benchmarks/gpu/src/math/logf16_benchmark.cpp @@ -0,0 +1,62 @@ +//===-- GPU benchmark for logf16 ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "benchmarks/gpu/LibcGpuBenchmark.h" +#include "benchmarks/gpu/Random.h" + +#include "hdr/stdint_proxy.h" +#include "src/__support/macros/properties/types.h" +#include "src/__support/sign.h" +#include "src/math/logf16.h" + +#if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND) +#include "platform.h" +#endif + +#define RANDOM_INPUT_UniformExponent(T, Func, Min, Max, N) \ + [](uint32_t call_index) { \ + using namespace LIBC_NAMESPACE::benchmarks; \ + \ + const UniformExponent<T> dist(Min, Max, LIBC_NAMESPACE::Sign::POS); \ + return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \ + } + +#define RANDOM_INPUT_UniformLinear(T, Func, Min, Max, N) \ + [](uint32_t call_index) { \ + using namespace LIBC_NAMESPACE::benchmarks; \ + \ + const UniformLinear<T> dist(Min, Max); \ + return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \ + } + +#define BENCH(T, Name, Func, Dist, Min, Max) \ + SINGLE_WAVE_BENCHMARK(LlvmLibcLogf16GpuBenchmark, Name##_1, \ + RANDOM_INPUT_##Dist(T, Func, Min, Max, 1)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcLogf16GpuBenchmark, Name##_128, \ + RANDOM_INPUT_##Dist(T, Func, Min, Max, 128)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcLogf16GpuBenchmark, Name##_1024, \ + RANDOM_INPUT_##Dist(T, Func, Min, Max, 1024)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcLogf16GpuBenchmark, Name##_4096, \ + RANDOM_INPUT_##Dist(T, Func, Min, Max, 4096)) + +using LIBC_NAMESPACE::logf16; + +static constexpr float16 INV_E = 0x1.78b56362cef38p-2f16; // exp(-1.0) +static constexpr float16 E = 0x1.5bf0a8b145769p+1f16; // exp(+1.0) + +BENCH(float16, Logf16Subnormal, logf16, UniformExponent, -14, -14); +BENCH(float16, Logf16AroundOne, logf16, UniformLinear, INV_E, E); +BENCH(float16, Logf16MedMag, logf16, UniformExponent, -10, 10); +BENCH(float16, Logf16Normal, logf16, UniformExponent, -13, 15); + +#ifdef AMDGPU_MATH_FOUND +BENCH(float16, AmdLogf16Subnormal, __ocml_log_f16, UniformExponent, -14, -14); +BENCH(float16, AmdLogf16AroundOne, __ocml_log_f16, UniformLinear, INV_E, E); +BENCH(float16, AmdLogf16MedMag, __ocml_log_f16, UniformExponent, -10, 10); +BENCH(float16, AmdLogf16Normal, __ocml_log_f16, UniformExponent, -13, 15); +#endif diff --git a/libc/benchmarks/gpu/src/math/logf_benchmark.cpp b/libc/benchmarks/gpu/src/math/logf_benchmark.cpp new file mode 100644 index 0000000..c4e5a22 --- /dev/null +++ b/libc/benchmarks/gpu/src/math/logf_benchmark.cpp @@ -0,0 +1,68 @@ +//===-- GPU benchmark for logf --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "benchmarks/gpu/LibcGpuBenchmark.h" +#include "benchmarks/gpu/Random.h" + +#include "hdr/stdint_proxy.h" +#include "src/__support/sign.h" +#include "src/math/logf.h" + +#if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND) +#include "platform.h" +#endif + +#define RANDOM_INPUT_UniformExponent(T, Func, Min, Max, N) \ + [](uint32_t call_index) { \ + using namespace LIBC_NAMESPACE::benchmarks; \ + \ + const UniformExponent<T> dist(Min, Max, LIBC_NAMESPACE::Sign::POS); \ + return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \ + } + +#define RANDOM_INPUT_UniformLinear(T, Func, Min, Max, N) \ + [](uint32_t call_index) { \ + using namespace LIBC_NAMESPACE::benchmarks; \ + \ + const UniformLinear<T> dist(Min, Max); \ + return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \ + } + +#define BENCH(T, Name, Func, Dist, Min, Max) \ + SINGLE_WAVE_BENCHMARK(LlvmLibcLogfGpuBenchmark, Name##_1, \ + RANDOM_INPUT_##Dist(T, Func, Min, Max, 1)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcLogfGpuBenchmark, Name##_128, \ + RANDOM_INPUT_##Dist(T, Func, Min, Max, 128)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcLogfGpuBenchmark, Name##_1024, \ + RANDOM_INPUT_##Dist(T, Func, Min, Max, 1024)); \ + SINGLE_WAVE_BENCHMARK(LlvmLibcLogfGpuBenchmark, Name##_4096, \ + RANDOM_INPUT_##Dist(T, Func, Min, Max, 4096)) + +using LIBC_NAMESPACE::logf; + +static constexpr float INV_E = 0x1.78b56362cef38p-2f; // exp(-1.0) +static constexpr float E = 0x1.5bf0a8b145769p+1f; // exp(+1.0) + +BENCH(float, LogfSubnormal, logf, UniformExponent, -126, -126); +BENCH(float, LogfAroundOne, logf, UniformLinear, INV_E, E); +BENCH(float, LogfMedMag, logf, UniformExponent, -10, 10); +BENCH(float, LogfNormal, logf, UniformExponent, -125, 127); + +#ifdef NVPTX_MATH_FOUND +BENCH(float, NvLogfSubnormal, __nv_logf, UniformExponent, -126, -126); +BENCH(float, NvLogfAroundOne, __nv_logf, UniformLinear, INV_E, E); +BENCH(float, NvLogfMedMag, __nv_logf, UniformExponent, -10, 10); +BENCH(float, NvLogfNormal, __nv_logf, UniformExponent, -125, 127); +#endif + +#ifdef AMDGPU_MATH_FOUND +BENCH(float, AmdLogfSubnormal, __ocml_log_f32, UniformExponent, -126, -126); +BENCH(float, AmdLogfAroundOne, __ocml_log_f32, UniformLinear, INV_E, E); +BENCH(float, AmdLogfMedMag, __ocml_log_f32, UniformExponent, -10, 10); +BENCH(float, AmdLogfNormal, __ocml_log_f32, UniformExponent, -125, 127); +#endif diff --git a/libc/benchmarks/gpu/src/math/platform.h b/libc/benchmarks/gpu/src/math/platform.h index 2dfa9f2..e675d1e 100644 --- a/libc/benchmarks/gpu/src/math/platform.h +++ b/libc/benchmarks/gpu/src/math/platform.h @@ -11,6 +11,7 @@ #include "hdr/stdint_proxy.h" #include "src/__support/macros/attributes.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" namespace LIBC_NAMESPACE_DECL { @@ -41,17 +42,27 @@ extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 9000; // Forward declarations for the vendor math libraries. extern "C" { #ifdef AMDGPU_MATH_FOUND -double __ocml_sin_f64(double); -float __ocml_sin_f32(float); double __ocml_atan2_f64(double, double); float __ocml_atan2_f32(float, float); +double __ocml_exp_f64(double); +float __ocml_exp_f32(float); +float16 __ocml_exp_f16(float16); +double __ocml_log_f64(double); +float __ocml_log_f32(float); +float16 __ocml_log_f16(float16); +double __ocml_sin_f64(double); +float __ocml_sin_f32(float); #endif #ifdef NVPTX_MATH_FOUND -double __nv_sin(double); -float __nv_sinf(float); double __nv_atan2(double, double); float __nv_atan2f(float, float); +double __nv_exp(double); +float __nv_expf(float); +double __nv_log(double); +float __nv_logf(float); +double __nv_sin(double); +float __nv_sinf(float); #endif } diff --git a/libc/benchmarks/gpu/src/math/sin_benchmark.cpp b/libc/benchmarks/gpu/src/math/sin_benchmark.cpp index a759db2..5ed82c8 100644 --- a/libc/benchmarks/gpu/src/math/sin_benchmark.cpp +++ b/libc/benchmarks/gpu/src/math/sin_benchmark.cpp @@ -1,36 +1,31 @@ #include "benchmarks/gpu/LibcGpuBenchmark.h" +#include "benchmarks/gpu/Random.h" -#include "src/__support/CPP/array.h" -#include "src/__support/CPP/bit.h" -#include "src/__support/CPP/functional.h" -#include "src/__support/FPUtil/FPBits.h" +#include "hdr/stdint_proxy.h" #include "src/math/sin.h" #include "src/math/sinf.h" -#include "src/stdlib/rand.h" #if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND) #include "platform.h" #endif -// BENCHMARK() expects a function that with no parameters that returns a -// uint64_t representing the latency. Defining each benchmark using macro that -// expands to a lambda to allow us to switch the implementation of `sin()` to -// easily register NVPTX benchmarks. -#define BM_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, N) \ - []() { \ - return LIBC_NAMESPACE::benchmarks::MathPerf<T>::run_throughput_in_range< \ - N>(Func, MIN_EXP, MAX_EXP); \ +#define BM_RANDOM_INPUT(T, Func, MinExp, MaxExp, N) \ + [](uint32_t call_index) { \ + using namespace LIBC_NAMESPACE::benchmarks; \ + \ + const UniformExponent<T> dist(MinExp, MaxExp); \ + return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \ } -#define BENCH(T, Name, Func, MIN_EXP, MAX_EXP) \ +#define BENCH(T, Name, Func, MinExp, MaxExp) \ SINGLE_WAVE_BENCHMARK(LlvmLibcSinGpuBenchmark, Name##_1, \ - BM_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 1)); \ + BM_RANDOM_INPUT(T, Func, MinExp, MaxExp, 1)); \ SINGLE_WAVE_BENCHMARK(LlvmLibcSinGpuBenchmark, Name##_128, \ - BM_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 128)); \ + BM_RANDOM_INPUT(T, Func, MinExp, MaxExp, 128)); \ SINGLE_WAVE_BENCHMARK(LlvmLibcSinGpuBenchmark, Name##_1024, \ - BM_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 1024)); \ + BM_RANDOM_INPUT(T, Func, MinExp, MaxExp, 1024)); \ SINGLE_WAVE_BENCHMARK(LlvmLibcSinGpuBenchmark, Name##_4096, \ - BM_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 4096)) + BM_RANDOM_INPUT(T, Func, MinExp, MaxExp, 4096)) BENCH(double, Sin, LIBC_NAMESPACE::sin, -1023, 1023); BENCH(double, SinTwoPi, LIBC_NAMESPACE::sin, -10, 3); diff --git a/libc/benchmarks/gpu/timing/amdgpu/CMakeLists.txt b/libc/benchmarks/gpu/timing/amdgpu/CMakeLists.txt index dd7c2d3..f85152e 100644 --- a/libc/benchmarks/gpu/timing/amdgpu/CMakeLists.txt +++ b/libc/benchmarks/gpu/timing/amdgpu/CMakeLists.txt @@ -4,9 +4,11 @@ add_header_library( timing.h DEPENDS libc.hdr.stdint_proxy - libc.src.__support.common libc.src.__support.macros.config libc.src.__support.macros.attributes - libc.src.__support.CPP.type_traits + libc.src.__support.CPP.algorithm libc.src.__support.CPP.array + libc.src.__support.CPP.atomic + libc.src.__support.CPP.type_traits + libc.src.__support.GPU.utils ) diff --git a/libc/benchmarks/gpu/timing/amdgpu/timing.h b/libc/benchmarks/gpu/timing/amdgpu/timing.h index 37dbb9a..8b92584 100644 --- a/libc/benchmarks/gpu/timing/amdgpu/timing.h +++ b/libc/benchmarks/gpu/timing/amdgpu/timing.h @@ -10,11 +10,11 @@ #define LLVM_LIBC_UTILS_GPU_TIMING_AMDGPU #include "hdr/stdint_proxy.h" +#include "src/__support/CPP/algorithm.h" #include "src/__support/CPP/array.h" #include "src/__support/CPP/atomic.h" #include "src/__support/CPP/type_traits.h" #include "src/__support/GPU/utils.h" -#include "src/__support/common.h" #include "src/__support/macros/attributes.h" #include "src/__support/macros/config.h" @@ -105,20 +105,86 @@ template <typename F, typename T1, typename T2> return stop - start; } -// Provides throughput benchmarking. -template <typename F, typename T, size_t N> -[[gnu::noinline]] static LIBC_INLINE uint64_t -throughput(F f, const cpp::array<T, N> &inputs) { +// Provides the *baseline* for throughput: measures loop and measurement costs +// without calling the f function +template <typename T, size_t N> +static LIBC_INLINE uint64_t +throughput_baseline(const cpp::array<T, N> &inputs) { asm("" ::"v"(&inputs)); cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); uint64_t start = gpu::processor_clock(); + asm("" ::"s"(start)); + + T result{}; + +#pragma clang loop unroll(disable) + for (auto input : inputs) { + asm("" ::"v"(input)); + result = input; + asm("" ::"v"(result)); + } + + uint64_t stop = gpu::processor_clock(); + asm("" ::"s"(stop)); + cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); + + volatile auto output = result; + return stop - start; +} + +// Provides throughput benchmarking +template <typename F, typename T, size_t N> +static LIBC_INLINE uint64_t throughput(F f, const cpp::array<T, N> &inputs) { + uint64_t baseline = UINT64_MAX; + for (int i = 0; i < 5; ++i) + baseline = cpp::min(baseline, throughput_baseline<T, N>(inputs)); + + asm("" ::"v"(&inputs)); + + cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); + uint64_t start = gpu::processor_clock(); asm("" ::"s"(start)); + T result{}; + +#pragma clang loop unroll(disable) for (auto input : inputs) { - auto result = f(input); + asm("" ::"v"(input)); + result = f(input); + asm("" ::"v"(result)); + } + + uint64_t stop = gpu::processor_clock(); + asm("" ::"s"(stop)); + cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); + + volatile auto output = result; + + const uint64_t measured = stop - start; + return measured > baseline ? (measured - baseline) : 0; +} + +// Provides the *baseline* for throughput with 2 arguments: measures loop and +// measurement costs without calling the f function +template <typename T, size_t N> +static LIBC_INLINE uint64_t throughput_baseline( + const cpp::array<T, N> &inputs1, const cpp::array<T, N> &inputs2) { + asm("" ::"v"(&inputs1), "v"(&inputs2)); + + cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); + uint64_t start = gpu::processor_clock(); + asm("" ::"s"(start)); + T result{}; + +#pragma clang loop unroll(disable) + for (size_t i = 0; i < N; i++) { + T x = inputs1[i]; + T y = inputs2[i]; + asm("" ::"v"(x), "v"(y)); + result = x; asm("" ::"v"(result)); } @@ -126,24 +192,33 @@ throughput(F f, const cpp::array<T, N> &inputs) { asm("" ::"s"(stop)); cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); - // Return the time elapsed. + volatile auto output = result; + return stop - start; } // Provides throughput benchmarking for 2 arguments (e.g. atan2()) template <typename F, typename T, size_t N> -[[gnu::noinline]] static LIBC_INLINE uint64_t throughput( - F f, const cpp::array<T, N> &inputs1, const cpp::array<T, N> &inputs2) { +static LIBC_INLINE uint64_t throughput(F f, const cpp::array<T, N> &inputs1, + const cpp::array<T, N> &inputs2) { + uint64_t baseline = UINT64_MAX; + for (int i = 0; i < 5; ++i) + baseline = cpp::min(baseline, throughput_baseline<T, N>(inputs1, inputs2)); + asm("" ::"v"(&inputs1), "v"(&inputs2)); cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); uint64_t start = gpu::processor_clock(); - asm("" ::"s"(start)); - for (size_t i = 0; i < inputs1.size(); i++) { - auto result = f(inputs1[i], inputs2[i]); + T result{}; +#pragma clang loop unroll(disable) + for (size_t i = 0; i < N; i++) { + T x = inputs1[i]; + T y = inputs2[i]; + asm("" ::"v"(x), "v"(y)); + result = f(x, y); asm("" ::"v"(result)); } @@ -151,8 +226,10 @@ template <typename F, typename T, size_t N> asm("" ::"s"(stop)); cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); - // Return the time elapsed. - return stop - start; + volatile auto output = result; + + const uint64_t measured = stop - start; + return measured > baseline ? (measured - baseline) : 0; } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/benchmarks/gpu/timing/nvptx/CMakeLists.txt b/libc/benchmarks/gpu/timing/nvptx/CMakeLists.txt index a19c16e..4615f53 100644 --- a/libc/benchmarks/gpu/timing/nvptx/CMakeLists.txt +++ b/libc/benchmarks/gpu/timing/nvptx/CMakeLists.txt @@ -4,9 +4,11 @@ add_header_library( timing.h DEPENDS libc.hdr.stdint_proxy - libc.src.__support.common libc.src.__support.macros.config libc.src.__support.macros.attributes - libc.src.__support.CPP.type_traits + libc.src.__support.CPP.algorithm libc.src.__support.CPP.array + libc.src.__support.CPP.atomic + libc.src.__support.CPP.type_traits + libc.src.__support.GPU.utils ) diff --git a/libc/benchmarks/gpu/timing/nvptx/timing.h b/libc/benchmarks/gpu/timing/nvptx/timing.h index 3c72963..944d373 100644 --- a/libc/benchmarks/gpu/timing/nvptx/timing.h +++ b/libc/benchmarks/gpu/timing/nvptx/timing.h @@ -10,11 +10,10 @@ #define LLVM_LIBC_UTILS_GPU_TIMING_NVPTX #include "hdr/stdint_proxy.h" +#include "src/__support/CPP/algorithm.h" #include "src/__support/CPP/array.h" #include "src/__support/CPP/atomic.h" -#include "src/__support/CPP/type_traits.h" #include "src/__support/GPU/utils.h" -#include "src/__support/common.h" #include "src/__support/macros/attributes.h" #include "src/__support/macros/config.h" @@ -65,7 +64,7 @@ template <typename F, typename T> uint64_t stop = gpu::processor_clock(); cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); asm("" ::"r"(stop)); - volatile T output = result; + volatile auto output = result; // Return the time elapsed. return stop - start; @@ -95,18 +94,51 @@ static LIBC_INLINE uint64_t latency(F f, T1 t1, T2 t2) { return stop - start; } -// Provides throughput benchmarking. -template <typename F, typename T, size_t N> -[[gnu::noinline]] static LIBC_INLINE uint64_t -throughput(F f, const cpp::array<T, N> &inputs) { +// Provides the *baseline* for throughput: measures loop and measurement costs +// without calling the f function +template <typename T, size_t N> +static LIBC_INLINE uint64_t +throughput_baseline(const cpp::array<T, N> &inputs) { asm("" ::"r"(&inputs)); cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); uint64_t start = gpu::processor_clock(); + asm("" ::"llr"(start)); + + T result{}; + +#pragma clang loop unroll(disable) + for (auto input : inputs) { + asm("" ::"r"(input)); + result = input; + asm("" ::"r"(result)); + } + uint64_t stop = gpu::processor_clock(); + asm("" ::"r"(stop)); + cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); + + volatile auto output = result; + + return stop - start; +} + +// Provides throughput benchmarking +template <typename F, typename T, size_t N> +static LIBC_INLINE uint64_t throughput(F f, const cpp::array<T, N> &inputs) { + uint64_t baseline = UINT64_MAX; + for (int i = 0; i < 5; ++i) + baseline = cpp::min(baseline, throughput_baseline<T, N>(inputs)); + + asm("" ::"r"(&inputs)); + + cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); + uint64_t start = gpu::processor_clock(); asm("" ::"llr"(start)); - uint64_t result; + T result{}; + +#pragma clang loop unroll(disable) for (auto input : inputs) { asm("" ::"r"(input)); result = f(input); @@ -114,39 +146,81 @@ throughput(F f, const cpp::array<T, N> &inputs) { } uint64_t stop = gpu::processor_clock(); + asm("" ::"r"(stop)); + cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); + + volatile auto output = result; + + const uint64_t measured = stop - start; + return measured > baseline ? (measured - baseline) : 0; +} + +// Provides the *baseline* for throughput with 2 arguments: measures loop and +// measurement costs without calling the f function +template <typename T, size_t N> +static LIBC_INLINE uint64_t throughput_baseline( + const cpp::array<T, N> &inputs1, const cpp::array<T, N> &inputs2) { + asm("" ::"r"(&inputs1), "r"(&inputs2)); + cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); + uint64_t start = gpu::processor_clock(); + asm("" ::"llr"(start)); + + T result{}; + +#pragma clang loop unroll(disable) + for (size_t i = 0; i < N; i++) { + T x = inputs1[i]; + T y = inputs2[i]; + asm("" ::"r"(x), "r"(y)); + result = x; + asm("" ::"r"(result)); + } + + uint64_t stop = gpu::processor_clock(); asm("" ::"r"(stop)); + cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); + volatile auto output = result; - // Return the time elapsed. return stop - start; } // Provides throughput benchmarking for 2 arguments (e.g. atan2()) template <typename F, typename T, size_t N> -[[gnu::noinline]] static LIBC_INLINE uint64_t throughput( - F f, const cpp::array<T, N> &inputs1, const cpp::array<T, N> &inputs2) { +static LIBC_INLINE uint64_t throughput(F f, const cpp::array<T, N> &inputs1, + const cpp::array<T, N> &inputs2) { + uint64_t baseline = UINT64_MAX; + for (int i = 0; i < 5; ++i) + baseline = cpp::min(baseline, throughput_baseline<T, N>(inputs1, inputs2)); + asm("" ::"r"(&inputs1), "r"(&inputs2)); cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); uint64_t start = gpu::processor_clock(); - asm("" ::"llr"(start)); - uint64_t result; - for (size_t i = 0; i < inputs1.size(); i++) { - result = f(inputs1[i], inputs2[i]); + T result{}; + +#pragma clang loop unroll(disable) + for (size_t i = 0; i < N; i++) { + T x = inputs1[i]; + T y = inputs2[i]; + asm("" ::"r"(x), "r"(y)); + result = f(x, y); asm("" ::"r"(result)); } uint64_t stop = gpu::processor_clock(); - cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); asm("" ::"r"(stop)); + cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL); + volatile auto output = result; - // Return the time elapsed. - return stop - start; + const uint64_t measured = stop - start; + return measured > baseline ? (measured - baseline) : 0; } + } // namespace LIBC_NAMESPACE_DECL #endif // LLVM_LIBC_UTILS_GPU_TIMING_NVPTX diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake index d85c393..2eb0f06 100644 --- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake +++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake @@ -115,11 +115,31 @@ function(_get_compile_options_from_config output_var) set(${output_var} ${config_options} PARENT_SCOPE) endfunction(_get_compile_options_from_config) +function(_get_compile_options_from_arch output_var) + # Set options that are not found in src/__support/macros/properties/architectures.h + # and src/__support/macros/properties/os.h + # TODO: we probably want to unify these at some point for consistency + set(config_options "") + + if (LIBC_TARGET_OS_IS_BAREMETAL) + list(APPEND config_options "-DLIBC_TARGET_OS_IS_BAREMETAL") + endif() + if (LIBC_TARGET_OS_IS_GPU) + list(APPEND config_options "-DLIBC_TARGET_OS_IS_GPU") + endif() + if (LIBC_TARGET_OS_IS_UEFI) + list(APPEND config_options "-DLIBC_TARGET_OS_IS_UEFI") + endif() + + set(${output_var} ${config_options} PARENT_SCOPE) +endfunction(_get_compile_options_from_arch) + function(_get_common_compile_options output_var flags) _get_compile_options_from_flags(compile_flags ${flags}) _get_compile_options_from_config(config_flags) + _get_compile_options_from_arch(arch_flags) - set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT} ${compile_flags} ${config_flags}) + set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT} ${compile_flags} ${config_flags} ${arch_flags}) if(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE) list(APPEND compile_options "-fpie") diff --git a/libc/cmake/modules/LLVMLibCLibraryRules.cmake b/libc/cmake/modules/LLVMLibCLibraryRules.cmake index b464c18..80439de 100644 --- a/libc/cmake/modules/LLVMLibCLibraryRules.cmake +++ b/libc/cmake/modules/LLVMLibCLibraryRules.cmake @@ -151,35 +151,6 @@ function(add_entrypoint_library target_name) set_target_properties(${target_name} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR}) endfunction(add_entrypoint_library) -# Rule to build a shared library of redirector objects. -function(add_redirector_library target_name) - cmake_parse_arguments( - "REDIRECTOR_LIBRARY" - "" - "" - "DEPENDS" - ${ARGN} - ) - - set(obj_files "") - foreach(dep IN LISTS REDIRECTOR_LIBRARY_DEPENDS) - # TODO: Ensure that each dep is actually a add_redirector_object target. - list(APPEND obj_files $<TARGET_OBJECTS:${dep}>) - endforeach(dep) - - # TODO: Call the linker explicitly instead of calling the compiler driver to - # prevent DT_NEEDED on C++ runtime. - add_library( - ${target_name} - EXCLUDE_FROM_ALL - SHARED - ${obj_files} - ) - set_target_properties(${target_name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR}) - target_link_libraries(${target_name} -nostdlib -lc -lm) - set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE "C") -endfunction(add_redirector_library) - set(HDR_LIBRARY_TARGET_TYPE "HDR_LIBRARY") # Internal function, used by `add_header_library`. diff --git a/libc/cmake/modules/LLVMLibCObjectRules.cmake b/libc/cmake/modules/LLVMLibCObjectRules.cmake index 805da91..6c534df 100644 --- a/libc/cmake/modules/LLVMLibCObjectRules.cmake +++ b/libc/cmake/modules/LLVMLibCObjectRules.cmake @@ -1,4 +1,33 @@ set(OBJECT_LIBRARY_TARGET_TYPE "OBJECT_LIBRARY") +set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ") +set(ENTRYPOINT_EXT_TARGET_TYPE "ENTRYPOINT_EXT") + +# Rule to check if a list of dependencies contains any entrypoint objects. Returns a list in entrypoint_deps. +function(check_entrypoint_deps entrypoint_deps) + set(PUBLIC_DEPS "") + set(fq_deps_list "") + list(APPEND fq_deps_list ${ARGN}) + + #don't warn for deps that are allowed, such as errno + set(ALLOWED_DEPS + "libc.src.errno.errno" + "libc.src.setjmp.longjmp" + ) + list(REMOVE_ITEM fq_deps_list ${ALLOWED_DEPS}) + + foreach(dep IN LISTS fq_deps_list) + if(NOT TARGET ${dep}) + continue() + endif() + + get_target_property(target_type ${dep} "TARGET_TYPE") + if(${target_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE}) + list(APPEND PUBLIC_DEPS ${dep}) + endif() + endforeach() + set(${entrypoint_deps} ${PUBLIC_DEPS} PARENT_SCOPE) +endfunction() + # Rule which is essentially a wrapper over add_library to compile a set of # sources to object files. @@ -65,6 +94,18 @@ function(create_object_library fq_target_name) target_include_directories(${fq_target_name} PRIVATE ${LIBC_SOURCE_DIR}) target_compile_options(${fq_target_name} PRIVATE ${compile_options}) + #loop through the deps, check if any have the TARGET_TYPE of ENTRYPOINT_OBJ_TARGET_TYPE, and print a warning if they do. + if(LIBC_CMAKE_VERBOSE_LOGGING) + set(entrypoint_deps "") + if(NOT "${fq_deps_list}" STREQUAL "") + check_entrypoint_deps(entrypoint_deps ${fq_deps_list}) + endif() + if(NOT "${entrypoint_deps}" STREQUAL "") + message(WARNING "Object ${fq_target_name} depends on public entrypoint(s) ${entrypoint_deps}. + Depending on public entrypoints is not allowed in internal code.") + endif() + endif() + if(SHOW_INTERMEDIATE_OBJECTS) message(STATUS "Adding object library ${fq_target_name}") if(${SHOW_INTERMEDIATE_OBJECTS} STREQUAL "DEPS") @@ -110,7 +151,6 @@ function(add_object_library target_name) ${ARGN}) endfunction(add_object_library) -set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ") # A rule for entrypoint object targets. # Usage: @@ -179,7 +219,6 @@ function(create_entrypoint_object fq_target_name) get_target_property(obj_type ${fq_dep_name} "TARGET_TYPE") if((NOT obj_type) OR (NOT ${obj_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE})) - message(FATAL_ERROR "The aliasee of an entrypoint alias should be an entrypoint.") endif() @@ -230,6 +269,19 @@ function(create_entrypoint_object fq_target_name) _get_common_compile_options(common_compile_options "${ADD_ENTRYPOINT_OBJ_FLAGS}") list(APPEND common_compile_options ${ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS}) get_fq_deps_list(fq_deps_list ${ADD_ENTRYPOINT_OBJ_DEPENDS}) + + #loop through the deps, check if any have the TARGET_TYPE of entrypoint_target_type, and print a warning if they do. + if(LIBC_CMAKE_VERBOSE_LOGGING) + set(entrypoint_deps "") + if(NOT "${fq_deps_list}" STREQUAL "") + check_entrypoint_deps(entrypoint_deps ${fq_deps_list}) + endif() + if(NOT "${entrypoint_deps}" STREQUAL "") + message(WARNING "Entrypoint ${fq_target_name} depends on public entrypoint(s) ${entrypoint_deps}. + Depending on public entrypoints is not allowed in internal code.") + endif() + endif() + set(full_deps_list ${fq_deps_list} libc.src.__support.common) if(SHOW_INTERMEDIATE_OBJECTS) @@ -390,8 +442,6 @@ function(add_entrypoint_object target_name) ) endfunction(add_entrypoint_object) -set(ENTRYPOINT_EXT_TARGET_TYPE "ENTRYPOINT_EXT") - # A rule for external entrypoint targets. # Usage: # add_entrypoint_external( @@ -420,31 +470,6 @@ function(add_entrypoint_external target_name) endfunction(add_entrypoint_external) -# Rule build a redirector object file. -function(add_redirector_object target_name) - cmake_parse_arguments( - "REDIRECTOR_OBJECT" - "" # No optional arguments - "SRC" # The cpp file in which the redirector is defined. - "" # No multivalue arguments - ${ARGN} - ) - if(NOT REDIRECTOR_OBJECT_SRC) - message(FATAL_ERROR "'add_redirector_object' rule requires SRC option listing one source file.") - endif() - - add_library( - ${target_name} - EXCLUDE_FROM_ALL - OBJECT - ${REDIRECTOR_OBJECT_SRC} - ) - target_compile_options( - ${target_name} - BEFORE PRIVATE -fPIC ${LIBC_COMPILE_OPTIONS_DEFAULT} - ) -endfunction(add_redirector_object) - # Helper to define a function with multiple implementations # - Computes flags to satisfy required/rejected features and arch, # - Declares an entry point, diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake index 267c32e..d92fdb2 100644 --- a/libc/cmake/modules/LLVMLibCTestRules.cmake +++ b/libc/cmake/modules/LLVMLibCTestRules.cmake @@ -1,6 +1,7 @@ function(_get_common_test_compile_options output_var c_test flags) _get_compile_options_from_flags(compile_flags ${flags}) _get_compile_options_from_config(config_flags) + _get_compile_options_from_arch(arch_flags) # Remove -fno-math-errno if it was added. if(LIBC_ADD_FNO_MATH_ERRNO) @@ -16,7 +17,8 @@ function(_get_common_test_compile_options output_var c_test flags) ${LIBC_COMPILE_OPTIONS_DEFAULT} ${LIBC_TEST_COMPILE_OPTIONS_DEFAULT} ${compile_flags} - ${config_flags}) + ${config_flags} + ${arch_flags}) if(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE) list(APPEND compile_options "-fpie") @@ -836,7 +838,7 @@ function(add_libc_hermetic test_name) ${fq_deps_list}) # TODO: currently the dependency chain is broken such that getauxval cannot properly # propagate to hermetic tests. This is a temporary workaround. - if (LIBC_TARGET_ARCHITECTURE_IS_AARCH64) + if (LIBC_TARGET_ARCHITECTURE_IS_AARCH64 AND NOT(LIBC_TARGET_OS_IS_BAREMETAL)) target_link_libraries( ${fq_build_target_name} PRIVATE diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt index e24e2b9..782769e 100644 --- a/libc/config/baremetal/aarch64/entrypoints.txt +++ b/libc/config/baremetal/aarch64/entrypoints.txt @@ -757,9 +757,86 @@ endif() list(APPEND TARGET_LIBM_ENTRYPOINTS # bfloat16 entrypoints + libc.src.math.bf16add + libc.src.math.bf16addf + libc.src.math.bf16addl + libc.src.math.bf16div + libc.src.math.bf16divf + libc.src.math.bf16divl + libc.src.math.bf16fma + libc.src.math.bf16fmaf + libc.src.math.bf16fmal + libc.src.math.bf16mul + libc.src.math.bf16mulf + libc.src.math.bf16mull + libc.src.math.bf16sub + libc.src.math.bf16subf + libc.src.math.bf16subl + libc.src.math.canonicalizebf16 + libc.src.math.ceilbf16 + libc.src.math.copysignbf16 libc.src.math.fabsbf16 + libc.src.math.fdimbf16 + libc.src.math.floorbf16 + libc.src.math.fmaxbf16 + libc.src.math.fmaximumbf16 + libc.src.math.fmaximum_magbf16 + libc.src.math.fmaximum_mag_numbf16 + libc.src.math.fmaximum_numbf16 + libc.src.math.fminbf16 + libc.src.math.fminimumbf16 + libc.src.math.fminimum_magbf16 + libc.src.math.fminimum_mag_numbf16 + libc.src.math.fminimum_numbf16 + libc.src.math.fmodbf16 + libc.src.math.frexpbf16 + libc.src.math.fromfpbf16 + libc.src.math.fromfpxbf16 + libc.src.math.getpayloadbf16 + libc.src.math.ilogbbf16 + libc.src.math.iscanonicalbf16 + libc.src.math.issignalingbf16 + libc.src.math.ldexpbf16 + libc.src.math.llogbbf16 + libc.src.math.llrintbf16 + libc.src.math.llroundbf16 + libc.src.math.logbbf16 + libc.src.math.lrintbf16 + libc.src.math.lroundbf16 + libc.src.math.modfbf16 + libc.src.math.nanbf16 + libc.src.math.nearbyintbf16 + libc.src.math.nextafterbf16 + libc.src.math.nextdownbf16 + libc.src.math.nexttowardbf16 + libc.src.math.nextupbf16 + libc.src.math.remainderbf16 + libc.src.math.remquobf16 + libc.src.math.rintbf16 + libc.src.math.roundbf16 + libc.src.math.roundevenbf16 + libc.src.math.scalblnbf16 + libc.src.math.scalbnbf16 + libc.src.math.setpayloadbf16 + libc.src.math.setpayloadsigbf16 + libc.src.math.truncbf16 + libc.src.math.totalorderbf16 + libc.src.math.totalordermagbf16 + libc.src.math.ufromfpbf16 + libc.src.math.ufromfpxbf16 ) +if(LIBC_TYPES_HAS_FLOAT128) + list(APPEND TARGET_LIBM_ENTRYPOINTS + # math.h C++23 mixed bfloat16 and _Float128 entrypoints + libc.src.math.bf16addf128 + libc.src.math.bf16divf128 + libc.src.math.bf16fmaf128 + libc.src.math.bf16mulf128 + libc.src.math.bf16subf128 + ) +endif() + if(LIBC_COMPILER_HAS_FIXED_POINT) list(APPEND TARGET_LIBM_ENTRYPOINTS # stdfix.h _Fract and _Accum entrypoints diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt index 44e9c3e..f112c2b 100644 --- a/libc/config/baremetal/arm/entrypoints.txt +++ b/libc/config/baremetal/arm/entrypoints.txt @@ -760,9 +760,86 @@ endif() list(APPEND TARGET_LIBM_ENTRYPOINTS # bfloat16 entrypoints + libc.src.math.bf16add + libc.src.math.bf16addf + libc.src.math.bf16addl + libc.src.math.bf16div + libc.src.math.bf16divf + libc.src.math.bf16divl + libc.src.math.bf16fma + libc.src.math.bf16fmaf + libc.src.math.bf16fmal + libc.src.math.bf16mul + libc.src.math.bf16mulf + libc.src.math.bf16mull + libc.src.math.bf16sub + libc.src.math.bf16subf + libc.src.math.bf16subl + libc.src.math.canonicalizebf16 + libc.src.math.ceilbf16 + libc.src.math.copysignbf16 libc.src.math.fabsbf16 + libc.src.math.fdimbf16 + libc.src.math.floorbf16 + libc.src.math.fmaxbf16 + libc.src.math.fmaximumbf16 + libc.src.math.fmaximum_magbf16 + libc.src.math.fmaximum_mag_numbf16 + libc.src.math.fmaximum_numbf16 + libc.src.math.fminbf16 + libc.src.math.fminimumbf16 + libc.src.math.fminimum_magbf16 + libc.src.math.fminimum_mag_numbf16 + libc.src.math.fminimum_numbf16 + libc.src.math.fmodbf16 + libc.src.math.frexpbf16 + libc.src.math.fromfpbf16 + libc.src.math.fromfpxbf16 + libc.src.math.getpayloadbf16 + libc.src.math.ilogbbf16 + libc.src.math.iscanonicalbf16 + libc.src.math.issignalingbf16 + libc.src.math.ldexpbf16 + libc.src.math.llogbbf16 + libc.src.math.llrintbf16 + libc.src.math.llroundbf16 + libc.src.math.logbbf16 + libc.src.math.lrintbf16 + libc.src.math.lroundbf16 + libc.src.math.modfbf16 + libc.src.math.nanbf16 + libc.src.math.nearbyintbf16 + libc.src.math.nextafterbf16 + libc.src.math.nextdownbf16 + libc.src.math.nexttowardbf16 + libc.src.math.nextupbf16 + libc.src.math.remainderbf16 + libc.src.math.remquobf16 + libc.src.math.rintbf16 + libc.src.math.roundbf16 + libc.src.math.roundevenbf16 + libc.src.math.scalblnbf16 + libc.src.math.scalbnbf16 + libc.src.math.setpayloadbf16 + libc.src.math.setpayloadsigbf16 + libc.src.math.truncbf16 + libc.src.math.totalorderbf16 + libc.src.math.totalordermagbf16 + libc.src.math.ufromfpbf16 + libc.src.math.ufromfpxbf16 ) +if(LIBC_TYPES_HAS_FLOAT128) + list(APPEND TARGET_LIBM_ENTRYPOINTS + # math.h C++23 mixed bfloat16 and _Float128 entrypoints + libc.src.math.bf16addf128 + libc.src.math.bf16divf128 + libc.src.math.bf16fmaf128 + libc.src.math.bf16mulf128 + libc.src.math.bf16subf128 + ) +endif() + if(LIBC_COMPILER_HAS_FIXED_POINT) list(APPEND TARGET_LIBM_ENTRYPOINTS # stdfix.h _Fract and _Accum entrypoints diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt index 29cf322a..53e5914 100644 --- a/libc/config/baremetal/riscv/entrypoints.txt +++ b/libc/config/baremetal/riscv/entrypoints.txt @@ -760,9 +760,86 @@ endif() list(APPEND TARGET_LIBM_ENTRYPOINTS # bfloat16 entrypoints + libc.src.math.bf16add + libc.src.math.bf16addf + libc.src.math.bf16addl + libc.src.math.bf16div + libc.src.math.bf16divf + libc.src.math.bf16divl + libc.src.math.bf16fma + libc.src.math.bf16fmaf + libc.src.math.bf16fmal + libc.src.math.bf16mul + libc.src.math.bf16mulf + libc.src.math.bf16mull + libc.src.math.bf16sub + libc.src.math.bf16subf + libc.src.math.bf16subl + libc.src.math.canonicalizebf16 + libc.src.math.ceilbf16 + libc.src.math.copysignbf16 libc.src.math.fabsbf16 + libc.src.math.fdimbf16 + libc.src.math.floorbf16 + libc.src.math.fmaxbf16 + libc.src.math.fmaximumbf16 + libc.src.math.fmaximum_magbf16 + libc.src.math.fmaximum_mag_numbf16 + libc.src.math.fmaximum_numbf16 + libc.src.math.fminbf16 + libc.src.math.fminimumbf16 + libc.src.math.fminimum_magbf16 + libc.src.math.fminimum_mag_numbf16 + libc.src.math.fminimum_numbf16 + libc.src.math.fmodbf16 + libc.src.math.frexpbf16 + libc.src.math.fromfpbf16 + libc.src.math.fromfpxbf16 + libc.src.math.getpayloadbf16 + libc.src.math.ilogbbf16 + libc.src.math.iscanonicalbf16 + libc.src.math.issignalingbf16 + libc.src.math.ldexpbf16 + libc.src.math.llogbbf16 + libc.src.math.llrintbf16 + libc.src.math.llroundbf16 + libc.src.math.logbbf16 + libc.src.math.lrintbf16 + libc.src.math.lroundbf16 + libc.src.math.modfbf16 + libc.src.math.nanbf16 + libc.src.math.nearbyintbf16 + libc.src.math.nextafterbf16 + libc.src.math.nextdownbf16 + libc.src.math.nexttowardbf16 + libc.src.math.nextupbf16 + libc.src.math.remainderbf16 + libc.src.math.remquobf16 + libc.src.math.rintbf16 + libc.src.math.roundbf16 + libc.src.math.roundevenbf16 + libc.src.math.scalblnbf16 + libc.src.math.scalbnbf16 + libc.src.math.setpayloadbf16 + libc.src.math.setpayloadsigbf16 + libc.src.math.truncbf16 + libc.src.math.totalorderbf16 + libc.src.math.totalordermagbf16 + libc.src.math.ufromfpbf16 + libc.src.math.ufromfpxbf16 ) +if(LIBC_TYPES_HAS_FLOAT128) + list(APPEND TARGET_LIBM_ENTRYPOINTS + # math.h C++23 mixed bfloat16 and _Float128 entrypoints + libc.src.math.bf16addf128 + libc.src.math.bf16divf128 + libc.src.math.bf16fmaf128 + libc.src.math.bf16mulf128 + libc.src.math.bf16subf128 + ) +endif() + if(LIBC_COMPILER_HAS_FIXED_POINT) list(APPEND TARGET_LIBM_ENTRYPOINTS # stdfix.h _Fract and _Accum entrypoints diff --git a/libc/config/config.json b/libc/config/config.json index 1b05469..cfbe9a43 100644 --- a/libc/config/config.json +++ b/libc/config/config.json @@ -2,7 +2,7 @@ "errno": { "LIBC_CONF_ERRNO_MODE": { "value": "LIBC_ERRNO_MODE_DEFAULT", - "doc": "The implementation used for errno, acceptable values are LIBC_ERRNO_MODE_DEFAULT, LIBC_ERRNO_MODE_UNDEFINED, LIBC_ERRNO_MODE_THREAD_LOCAL, LIBC_ERRNO_MODE_SHARED, LIBC_ERRNO_MODE_EXTERNAL, LIBC_ERRNO_MODE_SYSTEM, and LIBC_ERRNO_MODE_SYSTEM_INLINE." + "doc": "The implementation used for errno, acceptable values are LIBC_ERRNO_MODE_DEFAULT, LIBC_ERRNO_MODE_UNDEFINED, LIBC_ERRNO_MODE_THREAD_LOCAL, LIBC_ERRNO_MODE_SHARED, LIBC_ERRNO_MODE_EXTERNAL, and LIBC_ERRNO_MODE_SYSTEM_INLINE." } }, "threads": { diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt index 03e00a3..b4e210a 100644 --- a/libc/config/darwin/aarch64/entrypoints.txt +++ b/libc/config/darwin/aarch64/entrypoints.txt @@ -590,9 +590,84 @@ endif() list(APPEND TARGET_LIBM_ENTRYPOINTS # bfloat16 entrypoints + libc.src.math.bf16add + libc.src.math.bf16addf + libc.src.math.bf16addl + libc.src.math.bf16div + libc.src.math.bf16divf + libc.src.math.bf16divl + libc.src.math.bf16fma + libc.src.math.bf16fmaf + libc.src.math.bf16fmal + libc.src.math.bf16mul + libc.src.math.bf16mulf + libc.src.math.bf16mull + libc.src.math.bf16sub + libc.src.math.bf16subf + libc.src.math.bf16subl + libc.src.math.canonicalizebf16 + libc.src.math.ceilbf16 + libc.src.math.copysignbf16 libc.src.math.fabsbf16 + libc.src.math.fdimbf16 + libc.src.math.floorbf16 + libc.src.math.fmaxbf16 + libc.src.math.fmaximumbf16 + libc.src.math.fmaximum_magbf16 + libc.src.math.fmaximum_mag_numbf16 + libc.src.math.fmaximum_numbf16 + libc.src.math.fminbf16 + libc.src.math.fminimumbf16 + libc.src.math.fminimum_magbf16 + libc.src.math.fminimum_mag_numbf16 + libc.src.math.fminimum_numbf16 + libc.src.math.fmodbf16 + libc.src.math.frexpbf16 + libc.src.math.fromfpbf16 + libc.src.math.fromfpxbf16 + libc.src.math.getpayloadbf16 + libc.src.math.ilogbbf16 + libc.src.math.iscanonicalbf16 + libc.src.math.issignalingbf16 + libc.src.math.ldexpbf16 + libc.src.math.llogbbf16 + libc.src.math.llrintbf16 + libc.src.math.llroundbf16 + libc.src.math.logbbf16 + libc.src.math.lrintbf16 + libc.src.math.lroundbf16 + libc.src.math.modfbf16 + libc.src.math.nanbf16 + libc.src.math.nearbyintbf16 + libc.src.math.nextafterbf16 + libc.src.math.nextdownbf16 + libc.src.math.nexttowardbf16 + libc.src.math.nextupbf16 + libc.src.math.remainderbf16 + libc.src.math.remquobf16 + libc.src.math.rintbf16 + libc.src.math.roundbf16 + libc.src.math.roundevenbf16 + libc.src.math.scalblnbf16 + libc.src.math.scalbnbf16 + libc.src.math.setpayloadbf16 + libc.src.math.setpayloadsigbf16 + libc.src.math.truncbf16 + libc.src.math.totalorderbf16 + libc.src.math.totalordermagbf16 + libc.src.math.ufromfpbf16 + libc.src.math.ufromfpxbf16 ) +if(LIBC_TYPES_HAS_FLOAT128) + list(APPEND TARGET_LIBM_ENTRYPOINTS + # math.h C++23 mixed bfloat16 and _Float128 entrypoints + libc.src.math.bf16addf128 + libc.src.math.bf16mulf128 + libc.src.math.bf16subf128 + ) +endif() + if(LIBC_COMPILER_HAS_FIXED_POINT) list(APPEND TARGET_LIBM_ENTRYPOINTS # stdfix.h _Fract and _Accum entrypoints diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt index 00cedab..95392f7 100644 --- a/libc/config/darwin/x86_64/entrypoints.txt +++ b/libc/config/darwin/x86_64/entrypoints.txt @@ -233,7 +233,73 @@ set(TARGET_LIBM_ENTRYPOINTS list(APPEND TARGET_LIBM_ENTRYPOINTS # bfloat16 entrypoints + libc.src.math.bf16add + libc.src.math.bf16addf + libc.src.math.bf16addl + libc.src.math.bf16div + libc.src.math.bf16divf + libc.src.math.bf16divl + libc.src.math.bf16fma + libc.src.math.bf16fmaf + libc.src.math.bf16fmal + libc.src.math.bf16mul + libc.src.math.bf16mulf + libc.src.math.bf16mull + libc.src.math.bf16sub + libc.src.math.bf16subf + libc.src.math.bf16subl + libc.src.math.canonicalizebf16 + libc.src.math.ceilbf16 + libc.src.math.copysignbf16 libc.src.math.fabsbf16 + libc.src.math.fdimbf16 + libc.src.math.floorbf16 + libc.src.math.fmaxbf16 + libc.src.math.fmaximumbf16 + libc.src.math.fmaximum_magbf16 + libc.src.math.fmaximum_mag_numbf16 + libc.src.math.fmaximum_numbf16 + libc.src.math.fminbf16 + libc.src.math.fminimumbf16 + libc.src.math.fminimum_magbf16 + libc.src.math.fminimum_mag_numbf16 + libc.src.math.fminimum_numbf16 + libc.src.math.fmodbf16 + libc.src.math.frexpbf16 + libc.src.math.fromfpbf16 + libc.src.math.fromfpxbf16 + libc.src.math.getpayloadbf16 + libc.src.math.ilogbbf16 + libc.src.math.iscanonicalbf16 + libc.src.math.issignalingbf16 + libc.src.math.ldexpbf16 + libc.src.math.llogbbf16 + libc.src.math.llrintbf16 + libc.src.math.llroundbf16 + libc.src.math.logbbf16 + libc.src.math.lrintbf16 + libc.src.math.lroundbf16 + libc.src.math.modfbf16 + libc.src.math.nanbf16 + libc.src.math.nearbyintbf16 + libc.src.math.nextafterbf16 + libc.src.math.nextdownbf16 + libc.src.math.nexttowardbf16 + libc.src.math.nextupbf16 + libc.src.math.remainderbf16 + libc.src.math.remquobf16 + libc.src.math.rintbf16 + libc.src.math.roundbf16 + libc.src.math.roundevenbf16 + libc.src.math.scalblnbf16 + libc.src.math.scalbnbf16 + libc.src.math.setpayloadbf16 + libc.src.math.setpayloadsigbf16 + libc.src.math.truncbf16 + libc.src.math.totalorderbf16 + libc.src.math.totalordermagbf16 + libc.src.math.ufromfpbf16 + libc.src.math.ufromfpxbf16 ) set(TARGET_LLVMLIBC_ENTRYPOINTS diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt index 291a2d0..737d1bb 100644 --- a/libc/config/gpu/amdgpu/entrypoints.txt +++ b/libc/config/gpu/amdgpu/entrypoints.txt @@ -282,6 +282,7 @@ set(TARGET_LIBM_ENTRYPOINTS # math.h entrypoints libc.src.math.acos libc.src.math.acosf + libc.src.math.acoshf libc.src.math.asin libc.src.math.asinf libc.src.math.asinhf @@ -615,7 +616,73 @@ endif() list(APPEND TARGET_LIBM_ENTRYPOINTS # bfloat16 entrypoints + libc.src.math.bf16add + libc.src.math.bf16addf + libc.src.math.bf16addl + libc.src.math.bf16div + libc.src.math.bf16divf + libc.src.math.bf16divl + libc.src.math.bf16fma + libc.src.math.bf16fmaf + libc.src.math.bf16fmal + libc.src.math.bf16mul + libc.src.math.bf16mulf + libc.src.math.bf16mull + libc.src.math.bf16sub + libc.src.math.bf16subf + libc.src.math.bf16subl + libc.src.math.canonicalizebf16 + libc.src.math.ceilbf16 + libc.src.math.copysignbf16 libc.src.math.fabsbf16 + libc.src.math.fdimbf16 + libc.src.math.floorbf16 + libc.src.math.fmaxbf16 + libc.src.math.fmaximumbf16 + libc.src.math.fmaximum_magbf16 + libc.src.math.fmaximum_mag_numbf16 + libc.src.math.fmaximum_numbf16 + libc.src.math.fminbf16 + libc.src.math.fminimumbf16 + libc.src.math.fminimum_magbf16 + libc.src.math.fminimum_mag_numbf16 + libc.src.math.fminimum_numbf16 + libc.src.math.fmodbf16 + libc.src.math.frexpbf16 + libc.src.math.fromfpbf16 + libc.src.math.fromfpxbf16 + libc.src.math.getpayloadbf16 + libc.src.math.ilogbbf16 + libc.src.math.iscanonicalbf16 + libc.src.math.issignalingbf16 + libc.src.math.ldexpbf16 + libc.src.math.llogbbf16 + libc.src.math.llrintbf16 + libc.src.math.llroundbf16 + libc.src.math.logbbf16 + libc.src.math.lrintbf16 + libc.src.math.lroundbf16 + libc.src.math.modfbf16 + libc.src.math.nanbf16 + libc.src.math.nearbyintbf16 + libc.src.math.nextafterbf16 + libc.src.math.nextdownbf16 + libc.src.math.nexttowardbf16 + libc.src.math.nextupbf16 + libc.src.math.remainderbf16 + libc.src.math.remquobf16 + libc.src.math.rintbf16 + libc.src.math.roundbf16 + libc.src.math.roundevenbf16 + libc.src.math.scalblnbf16 + libc.src.math.scalbnbf16 + libc.src.math.setpayloadbf16 + libc.src.math.setpayloadsigbf16 + libc.src.math.truncbf16 + libc.src.math.totalorderbf16 + libc.src.math.totalordermagbf16 + libc.src.math.ufromfpbf16 + libc.src.math.ufromfpxbf16 ) set(TARGET_LLVMLIBC_ENTRYPOINTS diff --git a/libc/config/gpu/amdgpu/config.json b/libc/config/gpu/config.json index fa179b8..434ee042 100644 --- a/libc/config/gpu/amdgpu/config.json +++ b/libc/config/gpu/config.json @@ -39,7 +39,7 @@ }, "math": { "LIBC_CONF_MATH_OPTIMIZATIONS": { - "value": "(LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_SMALL_TABLES | LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)" + "value": "(LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT | LIBC_MATH_SMALL_TABLES | LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)" } } } diff --git a/libc/config/gpu/nvptx/config.json b/libc/config/gpu/nvptx/config.json deleted file mode 100644 index fa179b8..0000000 --- a/libc/config/gpu/nvptx/config.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "errno": { - "LIBC_CONF_ERRNO_MODE": { - "value": "LIBC_ERRNO_MODE_SHARED" - } - }, - "threads": { - "LIBC_CONF_THREAD_MODE": { - "value": "LIBC_THREAD_MODE_SINGLE" - } - }, - "printf": { - "LIBC_CONF_PRINTF_DISABLE_FLOAT": { - "value": true - }, - "LIBC_CONF_PRINTF_DISABLE_INDEX_MODE": { - "value": true - }, - "LIBC_CONF_PRINTF_DISABLE_WRITE_INT": { - "value": true - }, - "LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE": { - "value": false - }, - "LIBC_CONF_PRINTF_DISABLE_STRERROR": { - "value": true - }, - "LIBC_CONF_PRINTF_RUNTIME_DISPATCH": { - "value": false - } - }, - "scanf": { - "LIBC_CONF_SCANF_DISABLE_FLOAT": { - "value": true - }, - "LIBC_CONF_SCANF_DISABLE_INDEX_MODE": { - "value": true - } - }, - "math": { - "LIBC_CONF_MATH_OPTIMIZATIONS": { - "value": "(LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_SMALL_TABLES | LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)" - } - } -} diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt index 55b27e6..c06d6357 100644 --- a/libc/config/gpu/nvptx/entrypoints.txt +++ b/libc/config/gpu/nvptx/entrypoints.txt @@ -280,6 +280,7 @@ set(TARGET_LIBC_ENTRYPOINTS set(TARGET_LIBM_ENTRYPOINTS # math.h entrypoints + libc.src.math.acos libc.src.math.acosf libc.src.math.acoshf libc.src.math.asin @@ -617,7 +618,73 @@ endif() list(APPEND TARGET_LIBM_ENTRYPOINTS # bfloat16 entrypoints + libc.src.math.bf16add + libc.src.math.bf16addf + libc.src.math.bf16addl + libc.src.math.bf16div + libc.src.math.bf16divf + libc.src.math.bf16divl + libc.src.math.bf16fma + libc.src.math.bf16fmaf + libc.src.math.bf16fmal + libc.src.math.bf16mul + libc.src.math.bf16mulf + libc.src.math.bf16mull + libc.src.math.bf16sub + libc.src.math.bf16subf + libc.src.math.bf16subl + libc.src.math.canonicalizebf16 + libc.src.math.ceilbf16 + libc.src.math.copysignbf16 libc.src.math.fabsbf16 + libc.src.math.fdimbf16 + libc.src.math.floorbf16 + libc.src.math.fmaxbf16 + libc.src.math.fmaximumbf16 + libc.src.math.fmaximum_magbf16 + libc.src.math.fmaximum_mag_numbf16 + libc.src.math.fmaximum_numbf16 + libc.src.math.fminbf16 + libc.src.math.fminimumbf16 + libc.src.math.fminimum_magbf16 + libc.src.math.fminimum_mag_numbf16 + libc.src.math.fminimum_numbf16 + libc.src.math.fmodbf16 + libc.src.math.frexpbf16 + libc.src.math.fromfpbf16 + libc.src.math.fromfpxbf16 + libc.src.math.getpayloadbf16 + libc.src.math.ilogbbf16 + libc.src.math.iscanonicalbf16 + libc.src.math.issignalingbf16 + libc.src.math.ldexpbf16 + libc.src.math.llogbbf16 + libc.src.math.llrintbf16 + libc.src.math.llroundbf16 + libc.src.math.logbbf16 + libc.src.math.lrintbf16 + libc.src.math.lroundbf16 + libc.src.math.modfbf16 + libc.src.math.nanbf16 + libc.src.math.nearbyintbf16 + libc.src.math.nextafterbf16 + libc.src.math.nextdownbf16 + libc.src.math.nexttowardbf16 + libc.src.math.nextupbf16 + libc.src.math.remainderbf16 + libc.src.math.remquobf16 + libc.src.math.rintbf16 + libc.src.math.roundbf16 + libc.src.math.roundevenbf16 + libc.src.math.scalblnbf16 + libc.src.math.scalbnbf16 + libc.src.math.setpayloadbf16 + libc.src.math.setpayloadsigbf16 + libc.src.math.truncbf16 + libc.src.math.totalorderbf16 + libc.src.math.totalordermagbf16 + libc.src.math.ufromfpbf16 + libc.src.math.ufromfpxbf16 ) set(TARGET_LLVMLIBC_ENTRYPOINTS diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index d76cdc2..9aeb6a7 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -660,6 +660,7 @@ if(LIBC_TYPES_HAS_FLOAT16) list(APPEND TARGET_LIBM_ENTRYPOINTS # math.h C23 _Float16 entrypoints # libc.src.math.acoshf16 + libc.src.math.asinpif16 libc.src.math.canonicalizef16 libc.src.math.ceilf16 libc.src.math.copysignf16 @@ -844,9 +845,86 @@ endif() list(APPEND TARGET_LIBM_ENTRYPOINTS # bfloat16 entrypoints + libc.src.math.bf16add + libc.src.math.bf16addf + libc.src.math.bf16addl + libc.src.math.bf16div + libc.src.math.bf16divf + libc.src.math.bf16divl + libc.src.math.bf16fma + libc.src.math.bf16fmaf + libc.src.math.bf16fmal + libc.src.math.bf16mul + libc.src.math.bf16mulf + libc.src.math.bf16mull + libc.src.math.bf16sub + libc.src.math.bf16subf + libc.src.math.bf16subl + libc.src.math.canonicalizebf16 + libc.src.math.ceilbf16 + libc.src.math.copysignbf16 libc.src.math.fabsbf16 + libc.src.math.fdimbf16 + libc.src.math.floorbf16 + libc.src.math.fmaxbf16 + libc.src.math.fmaximumbf16 + libc.src.math.fmaximum_magbf16 + libc.src.math.fmaximum_mag_numbf16 + libc.src.math.fmaximum_numbf16 + libc.src.math.fminbf16 + libc.src.math.fminimumbf16 + libc.src.math.fminimum_magbf16 + libc.src.math.fminimum_mag_numbf16 + libc.src.math.fminimum_numbf16 + libc.src.math.fmodbf16 + libc.src.math.frexpbf16 + libc.src.math.fromfpbf16 + libc.src.math.fromfpxbf16 + libc.src.math.getpayloadbf16 + libc.src.math.ilogbbf16 + libc.src.math.iscanonicalbf16 + libc.src.math.issignalingbf16 + libc.src.math.ldexpbf16 + libc.src.math.llogbbf16 + libc.src.math.llrintbf16 + libc.src.math.llroundbf16 + libc.src.math.logbbf16 + libc.src.math.lrintbf16 + libc.src.math.lroundbf16 + libc.src.math.modfbf16 + libc.src.math.nanbf16 + libc.src.math.nearbyintbf16 + libc.src.math.nextafterbf16 + libc.src.math.nextdownbf16 + libc.src.math.nexttowardbf16 + libc.src.math.nextupbf16 + libc.src.math.remainderbf16 + libc.src.math.remquobf16 + libc.src.math.rintbf16 + libc.src.math.roundbf16 + libc.src.math.roundevenbf16 + libc.src.math.scalblnbf16 + libc.src.math.scalbnbf16 + libc.src.math.setpayloadbf16 + libc.src.math.setpayloadsigbf16 + libc.src.math.truncbf16 + libc.src.math.totalorderbf16 + libc.src.math.totalordermagbf16 + libc.src.math.ufromfpbf16 + libc.src.math.ufromfpxbf16 ) +if(LIBC_TYPES_HAS_FLOAT128) + list(APPEND TARGET_LIBM_ENTRYPOINTS + # math.h C++23 mixed bfloat16 and _Float128 entrypoints + libc.src.math.bf16addf128 + libc.src.math.bf16divf128 + libc.src.math.bf16fmaf128 + libc.src.math.bf16mulf128 + libc.src.math.bf16subf128 + ) +endif() + if(LLVM_LIBC_FULL_BUILD) list(APPEND TARGET_LIBC_ENTRYPOINTS # assert.h entrypoints diff --git a/libc/config/linux/arm/config.json b/libc/config/linux/arm/config.json new file mode 100644 index 0000000..e7ad454 --- /dev/null +++ b/libc/config/linux/arm/config.json @@ -0,0 +1,7 @@ +{ + "string": { + "LIBC_CONF_STRING_UNSAFE_WIDE_READ": { + "value": false + } + } +} diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt index 813c34d..591c57d 100644 --- a/libc/config/linux/arm/entrypoints.txt +++ b/libc/config/linux/arm/entrypoints.txt @@ -460,7 +460,73 @@ set(TARGET_LIBM_ENTRYPOINTS list(APPEND TARGET_LIBM_ENTRYPOINTS # bfloat16 entrypoints + libc.src.math.bf16add + libc.src.math.bf16addf + libc.src.math.bf16addl + libc.src.math.bf16div + libc.src.math.bf16divf + libc.src.math.bf16divl + libc.src.math.bf16fma + libc.src.math.bf16fmaf + libc.src.math.bf16fmal + libc.src.math.bf16mul + libc.src.math.bf16mulf + libc.src.math.bf16mull + libc.src.math.bf16sub + libc.src.math.bf16subf + libc.src.math.bf16subl + libc.src.math.canonicalizebf16 + libc.src.math.ceilbf16 + libc.src.math.copysignbf16 libc.src.math.fabsbf16 + libc.src.math.fdimbf16 + libc.src.math.floorbf16 + libc.src.math.fmaxbf16 + libc.src.math.fmaximumbf16 + libc.src.math.fmaximum_magbf16 + libc.src.math.fmaximum_mag_numbf16 + libc.src.math.fmaximum_numbf16 + libc.src.math.fminbf16 + libc.src.math.fminimumbf16 + libc.src.math.fminimum_magbf16 + libc.src.math.fminimum_mag_numbf16 + libc.src.math.fminimum_numbf16 + libc.src.math.fmodbf16 + libc.src.math.frexpbf16 + libc.src.math.fromfpbf16 + libc.src.math.fromfpxbf16 + libc.src.math.getpayloadbf16 + libc.src.math.ilogbbf16 + libc.src.math.iscanonicalbf16 + libc.src.math.issignalingbf16 + libc.src.math.ldexpbf16 + libc.src.math.llogbbf16 + libc.src.math.llrintbf16 + libc.src.math.llroundbf16 + libc.src.math.logbbf16 + libc.src.math.lrintbf16 + libc.src.math.lroundbf16 + libc.src.math.modfbf16 + libc.src.math.nanbf16 + libc.src.math.nearbyintbf16 + libc.src.math.nextafterbf16 + libc.src.math.nextdownbf16 + libc.src.math.nexttowardbf16 + libc.src.math.nextupbf16 + libc.src.math.remainderbf16 + libc.src.math.remquobf16 + libc.src.math.rintbf16 + libc.src.math.roundbf16 + libc.src.math.roundevenbf16 + libc.src.math.scalblnbf16 + libc.src.math.scalbnbf16 + libc.src.math.setpayloadbf16 + libc.src.math.setpayloadsigbf16 + libc.src.math.truncbf16 + libc.src.math.totalorderbf16 + libc.src.math.totalordermagbf16 + libc.src.math.ufromfpbf16 + libc.src.math.ufromfpxbf16 ) set(TARGET_LLVMLIBC_ENTRYPOINTS diff --git a/libc/config/linux/config.json b/libc/config/linux/config.json new file mode 100644 index 0000000..30e8b2c --- /dev/null +++ b/libc/config/linux/config.json @@ -0,0 +1,7 @@ +{ + "string": { + "LIBC_CONF_STRING_UNSAFE_WIDE_READ": { + "value": true + } + } +} diff --git a/libc/config/linux/riscv/config.json b/libc/config/linux/riscv/config.json new file mode 100644 index 0000000..e7ad454 --- /dev/null +++ b/libc/config/linux/riscv/config.json @@ -0,0 +1,7 @@ +{ + "string": { + "LIBC_CONF_STRING_UNSAFE_WIDE_READ": { + "value": false + } + } +} diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index 190aef7..b2cd5115 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -863,9 +863,86 @@ endif() list(APPEND TARGET_LIBM_ENTRYPOINTS # bfloat16 entrypoints + libc.src.math.bf16add + libc.src.math.bf16addf + libc.src.math.bf16addl + libc.src.math.bf16div + libc.src.math.bf16divf + libc.src.math.bf16divl + libc.src.math.bf16fma + libc.src.math.bf16fmaf + libc.src.math.bf16fmal + libc.src.math.bf16mul + libc.src.math.bf16mulf + libc.src.math.bf16mull + libc.src.math.bf16sub + libc.src.math.bf16subf + libc.src.math.bf16subl + libc.src.math.canonicalizebf16 + libc.src.math.ceilbf16 + libc.src.math.copysignbf16 libc.src.math.fabsbf16 + libc.src.math.fdimbf16 + libc.src.math.floorbf16 + libc.src.math.fmaxbf16 + libc.src.math.fmaximumbf16 + libc.src.math.fmaximum_magbf16 + libc.src.math.fmaximum_mag_numbf16 + libc.src.math.fmaximum_numbf16 + libc.src.math.fminbf16 + libc.src.math.fminimumbf16 + libc.src.math.fminimum_magbf16 + libc.src.math.fminimum_mag_numbf16 + libc.src.math.fminimum_numbf16 + libc.src.math.fmodbf16 + libc.src.math.frexpbf16 + libc.src.math.fromfpbf16 + libc.src.math.fromfpxbf16 + libc.src.math.getpayloadbf16 + libc.src.math.ilogbbf16 + libc.src.math.iscanonicalbf16 + libc.src.math.issignalingbf16 + libc.src.math.ldexpbf16 + libc.src.math.llogbbf16 + libc.src.math.llrintbf16 + libc.src.math.llroundbf16 + libc.src.math.logbbf16 + libc.src.math.lrintbf16 + libc.src.math.lroundbf16 + libc.src.math.modfbf16 + libc.src.math.nanbf16 + libc.src.math.nearbyintbf16 + libc.src.math.nextafterbf16 + libc.src.math.nextdownbf16 + libc.src.math.nexttowardbf16 + libc.src.math.nextupbf16 + libc.src.math.remainderbf16 + libc.src.math.remquobf16 + libc.src.math.rintbf16 + libc.src.math.roundbf16 + libc.src.math.roundevenbf16 + libc.src.math.scalblnbf16 + libc.src.math.scalbnbf16 + libc.src.math.setpayloadbf16 + libc.src.math.setpayloadsigbf16 + libc.src.math.truncbf16 + libc.src.math.totalorderbf16 + libc.src.math.totalordermagbf16 + libc.src.math.ufromfpbf16 + libc.src.math.ufromfpxbf16 ) +if(LIBC_TYPES_HAS_FLOAT128) + list(APPEND TARGET_LIBM_ENTRYPOINTS + # math.h C++23 mixed bfloat16 and _Float128 entrypoints + libc.src.math.bf16addf128 + libc.src.math.bf16divf128 + libc.src.math.bf16fmaf128 + libc.src.math.bf16mulf128 + libc.src.math.bf16subf128 + ) +endif() + if(LIBC_COMPILER_HAS_FIXED_POINT) list(APPEND TARGET_LIBM_ENTRYPOINTS # stdfix.h _Fract and _Accum entrypoints diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index ec41069..9a73e18 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -18,6 +18,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.ctype.toupper # dlfcn.h entrypoints + libc.src.dlfcn.dladdr libc.src.dlfcn.dlclose libc.src.dlfcn.dlerror libc.src.dlfcn.dlopen @@ -704,8 +705,10 @@ if(LIBC_TYPES_HAS_FLOAT16) libc.src.math.acospif16 libc.src.math.asinf16 libc.src.math.asinhf16 + libc.src.math.asinpif16 libc.src.math.atanf16 libc.src.math.atanhf16 + libc.src.math.atanpif16 libc.src.math.canonicalizef16 libc.src.math.ceilf16 libc.src.math.copysignf16 @@ -893,12 +896,88 @@ if(LIBC_TYPES_HAS_FLOAT128) ) endif() - list(APPEND TARGET_LIBM_ENTRYPOINTS # bfloat16 entrypoints + libc.src.math.bf16add + libc.src.math.bf16addf + libc.src.math.bf16addl + libc.src.math.bf16div + libc.src.math.bf16divf + libc.src.math.bf16divl + libc.src.math.bf16fma + libc.src.math.bf16fmaf + libc.src.math.bf16fmal + libc.src.math.bf16mul + libc.src.math.bf16mulf + libc.src.math.bf16mull + libc.src.math.bf16sub + libc.src.math.bf16subf + libc.src.math.bf16subl + libc.src.math.canonicalizebf16 + libc.src.math.ceilbf16 + libc.src.math.copysignbf16 libc.src.math.fabsbf16 + libc.src.math.fdimbf16 + libc.src.math.floorbf16 + libc.src.math.fmaxbf16 + libc.src.math.fmaximumbf16 + libc.src.math.fmaximum_magbf16 + libc.src.math.fmaximum_mag_numbf16 + libc.src.math.fmaximum_numbf16 + libc.src.math.fminbf16 + libc.src.math.fminimumbf16 + libc.src.math.fminimum_magbf16 + libc.src.math.fminimum_mag_numbf16 + libc.src.math.fminimum_numbf16 + libc.src.math.fmodbf16 + libc.src.math.frexpbf16 + libc.src.math.fromfpbf16 + libc.src.math.fromfpxbf16 + libc.src.math.getpayloadbf16 + libc.src.math.ilogbbf16 + libc.src.math.iscanonicalbf16 + libc.src.math.issignalingbf16 + libc.src.math.ldexpbf16 + libc.src.math.llogbbf16 + libc.src.math.llrintbf16 + libc.src.math.llroundbf16 + libc.src.math.logbbf16 + libc.src.math.lrintbf16 + libc.src.math.lroundbf16 + libc.src.math.modfbf16 + libc.src.math.nanbf16 + libc.src.math.nearbyintbf16 + libc.src.math.nextafterbf16 + libc.src.math.nextdownbf16 + libc.src.math.nexttowardbf16 + libc.src.math.nextupbf16 + libc.src.math.remainderbf16 + libc.src.math.remquobf16 + libc.src.math.rintbf16 + libc.src.math.roundbf16 + libc.src.math.roundevenbf16 + libc.src.math.scalblnbf16 + libc.src.math.scalbnbf16 + libc.src.math.setpayloadbf16 + libc.src.math.setpayloadsigbf16 + libc.src.math.truncbf16 + libc.src.math.totalorderbf16 + libc.src.math.totalordermagbf16 + libc.src.math.ufromfpbf16 + libc.src.math.ufromfpxbf16 ) +if(LIBC_TYPES_HAS_FLOAT128) + list(APPEND TARGET_LIBM_ENTRYPOINTS + # math.h C++23 mixed bfloat16 and _Float128 entrypoints + libc.src.math.bf16addf128 + libc.src.math.bf16divf128 + libc.src.math.bf16fmaf128 + libc.src.math.bf16mulf128 + libc.src.math.bf16subf128 + ) +endif() + if(LIBC_COMPILER_HAS_FIXED_POINT) list(APPEND TARGET_LIBM_ENTRYPOINTS # stdfix.h _Fract and _Accum entrypoints diff --git a/libc/config/windows/README.md b/libc/config/windows/README.md index 3ac058e..ee5d5fb 100644 --- a/libc/config/windows/README.md +++ b/libc/config/windows/README.md @@ -59,7 +59,7 @@ libc, and finally, build and test the libc. by Clang, so ensure Clang is specified as the C and C++ compiler. ``` - cmake -G Ninja ../llvm-project/llvm -DCMAKE_C_COMPILER=C:/src/clang-build/bin/clang-cl.exe -DCMAKE_CXX_COMPILER=C:/src/clang-build/bin/clang-cl.exe -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_FORCE_BUILD_RUNTIME=libc -DLLVM_ENABLE_PROJECTS=libc -DLLVM_NATIVE_ARCH=x86_64 -DLLVM_HOST_TRIPLE=x86_64-window-x86-gnu + cmake -G Ninja ../llvm-project/runtimes -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=C:/src/clang-build/bin/clang-cl.exe -DCMAKE_CXX_COMPILER=C:/src/clang-build/bin/clang-cl.exe -DLLVM_ENABLE_RUNTIMES=libc ``` Some LLVM libc math unittests test correctness/accuracy against results from diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt index 3160d57..2da48c3 100644 --- a/libc/config/windows/entrypoints.txt +++ b/libc/config/windows/entrypoints.txt @@ -306,7 +306,73 @@ set(TARGET_LIBM_ENTRYPOINTS list(APPEND TARGET_LIBM_ENTRYPOINTS # bfloat16 entrypoints + libc.src.math.bf16add + libc.src.math.bf16addf + libc.src.math.bf16addl + libc.src.math.bf16div + libc.src.math.bf16divf + libc.src.math.bf16divl + libc.src.math.bf16fma + libc.src.math.bf16fmaf + libc.src.math.bf16fmal + libc.src.math.bf16mul + libc.src.math.bf16mulf + libc.src.math.bf16mull + libc.src.math.bf16sub + libc.src.math.bf16subf + libc.src.math.bf16subl + libc.src.math.canonicalizebf16 + libc.src.math.ceilbf16 + libc.src.math.copysignbf16 libc.src.math.fabsbf16 + libc.src.math.fdimbf16 + libc.src.math.floorbf16 + libc.src.math.fmaxbf16 + libc.src.math.fmaximumbf16 + libc.src.math.fmaximum_magbf16 + libc.src.math.fmaximum_mag_numbf16 + libc.src.math.fmaximum_numbf16 + libc.src.math.fminbf16 + libc.src.math.fminimumbf16 + libc.src.math.fminimum_magbf16 + libc.src.math.fminimum_mag_numbf16 + libc.src.math.fminimum_numbf16 + libc.src.math.fmodbf16 + libc.src.math.frexpbf16 + libc.src.math.fromfpbf16 + libc.src.math.fromfpxbf16 + libc.src.math.getpayloadbf16 + libc.src.math.ilogbbf16 + libc.src.math.iscanonicalbf16 + libc.src.math.issignalingbf16 + libc.src.math.ldexpbf16 + libc.src.math.llogbbf16 + libc.src.math.llrintbf16 + libc.src.math.llroundbf16 + libc.src.math.logbbf16 + libc.src.math.lrintbf16 + libc.src.math.lroundbf16 + libc.src.math.modfbf16 + libc.src.math.nanbf16 + libc.src.math.nearbyintbf16 + libc.src.math.nextafterbf16 + libc.src.math.nextdownbf16 + libc.src.math.nexttowardbf16 + libc.src.math.nextupbf16 + libc.src.math.remainderbf16 + libc.src.math.remquobf16 + libc.src.math.rintbf16 + libc.src.math.roundbf16 + libc.src.math.roundevenbf16 + libc.src.math.scalblnbf16 + libc.src.math.scalbnbf16 + libc.src.math.setpayloadbf16 + libc.src.math.setpayloadsigbf16 + libc.src.math.truncbf16 + libc.src.math.totalorderbf16 + libc.src.math.totalordermagbf16 + libc.src.math.ufromfpbf16 + libc.src.math.ufromfpxbf16 ) set(TARGET_LLVMLIBC_ENTRYPOINTS diff --git a/libc/docs/configure.rst b/libc/docs/configure.rst index 95c51b8..e23fc82 100644 --- a/libc/docs/configure.rst +++ b/libc/docs/configure.rst @@ -29,7 +29,7 @@ to learn about the defaults for your platform and target. - ``LIBC_CONF_ENABLE_STRONG_STACK_PROTECTOR``: Enable -fstack-protector-strong to defend against stack smashing attack. - ``LIBC_CONF_KEEP_FRAME_POINTER``: Keep frame pointer in functions for better debugging experience. * **"errno" options** - - ``LIBC_CONF_ERRNO_MODE``: The implementation used for errno, acceptable values are LIBC_ERRNO_MODE_DEFAULT, LIBC_ERRNO_MODE_UNDEFINED, LIBC_ERRNO_MODE_THREAD_LOCAL, LIBC_ERRNO_MODE_SHARED, LIBC_ERRNO_MODE_EXTERNAL, LIBC_ERRNO_MODE_SYSTEM, and LIBC_ERRNO_MODE_SYSTEM_INLINE. + - ``LIBC_CONF_ERRNO_MODE``: The implementation used for errno, acceptable values are LIBC_ERRNO_MODE_DEFAULT, LIBC_ERRNO_MODE_UNDEFINED, LIBC_ERRNO_MODE_THREAD_LOCAL, LIBC_ERRNO_MODE_SHARED, LIBC_ERRNO_MODE_EXTERNAL, and LIBC_ERRNO_MODE_SYSTEM_INLINE. * **"general" options** - ``LIBC_ADD_NULL_CHECKS``: Add nullptr checks in the library's implementations to some functions for which passing nullptr is undefined behavior. * **"math" options** diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst index 9679c4a..b42216d 100644 --- a/libc/docs/headers/math/index.rst +++ b/libc/docs/headers/math/index.rst @@ -104,144 +104,153 @@ Implementation Status Basic Operations ================ -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| <Func> | <Func_f> (float) | <Func> (double) | <Func_l> (long double) | <Func_f16> (float16) | <Func_f128> (float128) | C23 Definition Section | C23 Error Handling Section | -+==================+==================+=================+========================+======================+========================+========================+============================+ -| ceil | |check| | |check| | |check| | |check| | |check| | 7.12.9.1 | F.10.6.1 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| canonicalize | |check| | |check| | |check| | |check| | |check| | 7.12.11.7 | F.10.8.7 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| copysign | |check| | |check| | |check| | |check| | |check| | 7.12.11.1 | F.10.8.1 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| dadd | N/A | N/A | |check| | N/A | |check|\* | 7.12.14.1 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| ddiv | N/A | N/A | |check| | N/A | |check|\* | 7.12.14.4 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| dfma | N/A | N/A | |check| | N/A | |check|\* | 7.12.14.5 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| dmul | N/A | N/A | |check| | N/A | |check|\* | 7.12.14.3 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| dsub | N/A | N/A | |check| | N/A | |check|\* | 7.12.14.2 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| f16add | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.1 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| f16div | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.4 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| f16fma | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.5 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| f16mul | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.5 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| f16sub | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.2 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fabs | |check| | |check| | |check| | |check| | |check| | 7.12.7.3 | F.10.4.3 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fadd | N/A | |check| | |check| | N/A | |check| | 7.12.14.1 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fdim | |check| | |check| | |check| | |check| | |check| | 7.12.12.1 | F.10.9.1 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fdiv | N/A | |check| | |check| | N/A | |check|\* | 7.12.14.4 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| ffma | N/A | |check| | |check| | N/A | |check|\* | 7.12.14.5 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| floor | |check| | |check| | |check| | |check| | |check| | 7.12.9.2 | F.10.6.2 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fmax | |check| | |check| | |check| | |check| | |check| | 7.12.12.2 | F.10.9.2 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fmaximum | |check| | |check| | |check| | |check| | |check| | 7.12.12.4 | F.10.9.4 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fmaximum_mag | |check| | |check| | |check| | |check| | |check| | 7.12.12.6 | F.10.9.4 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fmaximum_mag_num | |check| | |check| | |check| | |check| | |check| | 7.12.12.10 | F.10.9.5 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fmaximum_num | |check| | |check| | |check| | |check| | |check| | 7.12.12.8 | F.10.9.5 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fmin | |check| | |check| | |check| | |check| | |check| | 7.12.12.3 | F.10.9.3 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fminimum | |check| | |check| | |check| | |check| | |check| | 7.12.12.5 | F.10.9.4 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fminimum_mag | |check| | |check| | |check| | |check| | |check| | 7.12.12.7 | F.10.9.4 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fminimum_mag_num | |check| | |check| | |check| | |check| | |check| | 7.12.12.11 | F.10.9.5 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fminimum_num | |check| | |check| | |check| | |check| | |check| | 7.12.12.9 | F.10.9.5 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fmod | |check| | |check| | |check| | |check| | |check| | 7.12.10.1 | F.10.7.1 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fmul | N/A | |check| | |check| | N/A | |check|\* | 7.12.14.3 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| frexp | |check| | |check| | |check| | |check| | |check| | 7.12.6.7 | F.10.3.7 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fromfp | |check| | |check| | |check| | |check| | |check| | 7.12.9.10 | F.10.6.10 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fromfpx | |check| | |check| | |check| | |check| | |check| | 7.12.9.11 | F.10.6.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fsub | N/A | |check| | |check| | N/A | |check|\* | 7.12.14.2 | F.10.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| getpayload | |check| | |check| | |check| | |check| | |check| | F.10.13.1 | N/A | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| ilogb | |check| | |check| | |check| | |check| | |check| | 7.12.6.8 | F.10.3.8 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| iscanonical | |check| | |check| | |check| | |check| | |check| | 7.12.3.2 | N/A | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| issignaling | |check| | |check| | |check| | |check| | |check| | 7.12.3.8 | N/A | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| ldexp | |check| | |check| | |check| | |check| | |check| | 7.12.6.9 | F.10.3.9 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| llogb | |check| | |check| | |check| | |check| | |check| | 7.12.6.10 | F.10.3.10 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| llrint | |check| | |check| | |check| | |check| | |check| | 7.12.9.5 | F.10.6.5 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| llround | |check| | |check| | |check| | |check| | |check| | 7.12.9.7 | F.10.6.7 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| logb | |check| | |check| | |check| | |check| | |check| | 7.12.6.17 | F.10.3.17 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| lrint | |check| | |check| | |check| | |check| | |check| | 7.12.9.5 | F.10.6.5 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| lround | |check| | |check| | |check| | |check| | |check| | 7.12.9.7 | F.10.6.7 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| modf | |check| | |check| | |check| | |check| | |check| | 7.12.6.18 | F.10.3.18 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| nan | |check| | |check| | |check| | |check| | |check| | 7.12.11.2 | F.10.8.2 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| nearbyint | |check| | |check| | |check| | |check| | |check| | 7.12.9.3 | F.10.6.3 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| nextafter | |check| | |check| | |check| | |check| | |check| | 7.12.11.3 | F.10.8.3 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| nextdown | |check| | |check| | |check| | |check| | |check| | 7.12.11.6 | F.10.8.6 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| nexttoward | |check| | |check| | |check| | |check| | N/A | 7.12.11.4 | F.10.8.4 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| nextup | |check| | |check| | |check| | |check| | |check| | 7.12.11.5 | F.10.8.5 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| remainder | |check| | |check| | |check| | |check| | |check| | 7.12.10.2 | F.10.7.2 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| remquo | |check| | |check| | |check| | |check| | |check| | 7.12.10.3 | F.10.7.3 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| rint | |check| | |check| | |check| | |check| | |check| | 7.12.9.4 | F.10.6.4 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| round | |check| | |check| | |check| | |check| | |check| | 7.12.9.6 | F.10.6.6 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| roundeven | |check| | |check| | |check| | |check| | |check| | 7.12.9.8 | F.10.6.8 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| scalbln | |check| | |check| | |check| | |check| | |check| | 7.12.6.19 | F.10.3.19 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| scalbn | |check| | |check| | |check| | |check| | |check| | 7.12.6.19 | F.10.3.19 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| setpayload | |check| | |check| | |check| | |check| | |check| | F.10.13.2 | N/A | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| setpayloadsig | |check| | |check| | |check| | |check| | |check| | F.10.13.3 | N/A | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| totalorder | |check| | |check| | |check| | |check| | |check| | F.10.12.1 | N/A | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| totalordermag | |check| | |check| | |check| | |check| | |check| | F.10.12.2 | N/A | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| trunc | |check| | |check| | |check| | |check| | |check| | 7.12.9.9 | F.10.6.9 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| ufromfp | |check| | |check| | |check| | |check| | |check| | 7.12.9.10 | F.10.6.10 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| ufromfpx | |check| | |check| | |check| | |check| | |check| | 7.12.9.11 | F.10.6.11 | -+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ - ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| <Func> | <Func_f> (float) | <Func> (double) | <Func_l> (long double) | <Func_f16> (float16) | <Func_f128> (float128) | <Func_bf16> (bfloat16) | C23 Definition Section | C23 Error Handling Section | ++==================+==================+=================+========================+======================+========================+========================+========================+============================+ +| ceil | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.1 | F.10.6.1 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| canonicalize | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.11.7 | F.10.8.7 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| copysign | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.11.1 | F.10.8.1 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| dadd | N/A | N/A | |check| | N/A | |check|\* | N/A | 7.12.14.1 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| ddiv | N/A | N/A | |check| | N/A | |check|\* | N/A | 7.12.14.4 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| dfma | N/A | N/A | |check| | N/A | |check|\* | N/A | 7.12.14.5 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| dmul | N/A | N/A | |check| | N/A | |check|\* | N/A | 7.12.14.3 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| dsub | N/A | N/A | |check| | N/A | |check|\* | N/A | 7.12.14.2 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| f16add | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.1 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| f16div | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.4 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| f16fma | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.5 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| f16mul | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.3 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| f16sub | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.2 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| bf16add | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.1 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| bf16div | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.4 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| bf16fma | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.5 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| bf16mul | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.3 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| bf16sub | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.2 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fabs | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.7.3 | F.10.4.3 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fadd | N/A | |check| | |check| | N/A | |check| | N/A | 7.12.14.1 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fdim | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.1 | F.10.9.1 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fdiv | N/A | |check| | |check| | N/A | |check|\* | N/A | 7.12.14.4 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| ffma | N/A | |check| | |check| | N/A | |check|\* | N/A | 7.12.14.5 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| floor | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.2 | F.10.6.2 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fmax | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.2 | F.10.9.2 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fmaximum | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.4 | F.10.9.4 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fmaximum_mag | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.6 | F.10.9.4 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fmaximum_mag_num | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.10 | F.10.9.5 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fmaximum_num | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.8 | F.10.9.5 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fmin | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.3 | F.10.9.3 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fminimum | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.5 | F.10.9.4 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fminimum_mag | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.7 | F.10.9.4 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fminimum_mag_num | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.11 | F.10.9.5 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fminimum_num | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.9 | F.10.9.5 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fmod | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.10.1 | F.10.7.1 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fmul | N/A | |check| | |check| | N/A | |check|\* | N/A | 7.12.14.3 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| frexp | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.7 | F.10.3.7 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fromfp | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.10 | F.10.6.10 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fromfpx | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.11 | F.10.6.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| fsub | N/A | |check| | |check| | N/A | |check|\* | N/A | 7.12.14.2 | F.10.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| getpayload | |check| | |check| | |check| | |check| | |check| | |check| | F.10.13.1 | N/A | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| ilogb | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.8 | F.10.3.8 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| iscanonical | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.3.2 | N/A | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| issignaling | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.3.8 | N/A | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| ldexp | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.9 | F.10.3.9 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| llogb | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.10 | F.10.3.10 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| llrint | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.5 | F.10.6.5 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| llround | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.7 | F.10.6.7 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| logb | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.17 | F.10.3.17 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| lrint | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.5 | F.10.6.5 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| lround | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.7 | F.10.6.7 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| modf | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.18 | F.10.3.18 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| nan | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.11.2 | F.10.8.2 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| nearbyint | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.3 | F.10.6.3 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| nextafter | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.11.3 | F.10.8.3 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| nextdown | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.11.6 | F.10.8.6 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| nexttoward | |check| | |check| | |check| | |check| | N/A | |check| | 7.12.11.4 | F.10.8.4 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| nextup | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.11.5 | F.10.8.5 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| remainder | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.10.2 | F.10.7.2 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| remquo | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.10.3 | F.10.7.3 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| rint | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.4 | F.10.6.4 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| round | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.6 | F.10.6.6 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| roundeven | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.8 | F.10.6.8 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| scalbln | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.19 | F.10.3.19 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| scalbn | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.19 | F.10.3.19 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| setpayload | |check| | |check| | |check| | |check| | |check| | |check| | F.10.13.2 | N/A | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| setpayloadsig | |check| | |check| | |check| | |check| | |check| | |check| | F.10.13.3 | N/A | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| totalorder | |check| | |check| | |check| | |check| | |check| | |check| | F.10.12.1 | N/A | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| totalordermag | |check| | |check| | |check| | |check| | |check| | |check| | F.10.12.2 | N/A | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| trunc | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.9 | F.10.6.9 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| ufromfp | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.10 | F.10.6.10 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ +| ufromfpx | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.11 | F.10.6.11 | ++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ Higher Math Functions ===================== @@ -259,7 +268,7 @@ Higher Math Functions +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ | asinh | |check| | | | |check| | | 7.12.5.2 | F.10.2.2 | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| asinpi | | | | | | 7.12.4.9 | F.10.1.9 | +| asinpi | | | | |check| | | 7.12.4.9 | F.10.1.9 | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ | atan | |check| | 1 ULP | | |check| | | 7.12.4.3 | F.10.1.3 | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ @@ -269,7 +278,7 @@ Higher Math Functions +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ | atanh | |check| | | | |check| | | 7.12.5.3 | F.10.2.3 | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| atanpi | | | | | | 7.12.4.10 | F.10.1.10 | +| atanpi | | | | |check| | | 7.12.4.10 | F.10.1.10 | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ | cbrt | |check| | |check| | | | | 7.12.7.1 | F.10.4.1 | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ @@ -456,3 +465,5 @@ References * `The CORE-MATH Project <https://core-math.gitlabpages.inria.fr/>`_. * `The GNU C Library (glibc) <https://www.gnu.org/software/libc/>`_. * `The GNU MPFR Library <https://www.mpfr.org/>`_. +* `C++23 Standard <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4950.pdf>`_. +* `BFloat16 <https://en.wikipedia.org/wiki/Bfloat16_floating-point_format>`_.
\ No newline at end of file diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt index 02fe1ad..21971a4 100644 --- a/libc/hdr/types/CMakeLists.txt +++ b/libc/hdr/types/CMakeLists.txt @@ -461,3 +461,12 @@ add_proxy_header_library( libc.include.llvm-libc-types.struct_sched_param libc.include.sched ) + +add_proxy_header_library( + dl_info + HDRS + dl_info.h + FULL_BUILD_DEPENDS + libc.include.llvm-libc-types.dl_info + libc.include.dlfcn +) diff --git a/libc/hdr/types/dl_info.h b/libc/hdr/types/dl_info.h new file mode 100644 index 0000000..c742831 --- /dev/null +++ b/libc/hdr/types/dl_info.h @@ -0,0 +1,21 @@ +//===-- Proxy for struct timespec ----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_LIBC_HDR_TYPES_DLINFO_H +#define LLVM_LIBC_HDR_TYPES_DLINFO_H + +#ifdef LIBC_FULL_BUILD + +#include "include/llvm-libc-types/Dl_info.h" + +#else + +#include <dlfcn.h> + +#endif // LIBC_FULL_BUILD + +#endif // LLVM_LIBC_HDR_TYPES_STRUCT_TIMESPEC_H diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index 74fcea0..8fd37b0 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -70,6 +70,7 @@ add_header_macro( dlfcn.h DEPENDS .llvm_libc_common_h + .llvm-libc-types.dl_info ) add_header_macro( diff --git a/libc/include/__llvm-libc-common.h b/libc/include/__llvm-libc-common.h index c6fd33a..1fe3f4d 100644 --- a/libc/include/__llvm-libc-common.h +++ b/libc/include/__llvm-libc-common.h @@ -47,6 +47,13 @@ #define __NOEXCEPT throw() #endif +#undef _Returns_twice +#if __cplusplus >= 201103L +#define _Returns_twice [[gnu::returns_twice]] +#else +#define _Returns_twice __attribute__((returns_twice)) +#endif + // This macro serves as a generic cast implementation for use in both C and C++, // similar to `__BIONIC_CAST` in Android. #undef __LLVM_LIBC_CAST diff --git a/libc/include/dlfcn.yaml b/libc/include/dlfcn.yaml index 28be34d..bf17a11 100644 --- a/libc/include/dlfcn.yaml +++ b/libc/include/dlfcn.yaml @@ -29,6 +29,65 @@ macros: standards: - gnu macro_value: "0x01000" + - macro_name: RTLD_NEXT + standards: + - gnu + macro_value: "((void *) -1l)" + - macro_name: RTLD_DEFAULT + standards: + - gnu + macro_value: "((void *) 0)" +enums: + - name: RTLD_DI_LMID + standards: + - gnu + value: 1 + - name: RTLD_DI_LINKMAP + standards: + - gnu + value: 2 + - name: RTLD_DI_CONFIGADDR + standards: + - gnu + value: 3 + - name: RTLD_DI_SERINFO + standards: + - gnu + value: 4 + - name: RTLD_DI_SERINFOSIZE + standards: + - gnu + value: 5 + - name: RTLD_DI_ORIGIN + standards: + - gnu + value: 6 + - name: RTLD_DI_PROFILENAME + standards: + - gnu + value: 7 + - name: RTLD_DI_PROFILEOUT + standards: + - gnu + value: 8 + - name: RTLD_DI_TLS_MODID + standards: + - gnu + value: 9 + - name: RTLD_DI_TLS_DATA + standards: + - gnu + value: 10 + - name: RTLD_DI_PHDR + standards: + - gnu + value: 11 + - name: RTLD_DI_MAX + standards: + - gnu + value: 11 +types: + - type_name: Dl_info functions: - name: dlclose standards: @@ -55,3 +114,18 @@ functions: arguments: - type: void *__restrict - type: const char *__restrict + - name: dlinfo + standards: + - gnu + return_type: int + arguments: + - type: void *__restrict + - type: int + - type: void *__restrict + - name: dladdr + standards: + - POSIX + return_type: int + arguments: + - type: const void *__restrict + - type: Dl_info *__restrict diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index 451beae..fe9e4e3 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -72,6 +72,7 @@ add_header(stack_t HDR stack_t.h DEPENDS .size_t) add_header(suseconds_t HDR suseconds_t.h) add_header(struct_dirent HDR struct_dirent.h DEPENDS .ino_t .off_t) add_header(struct_dl_phdr_info HDR struct_dl_phdr_info.h DEPENDS .size_t libc.include.llvm-libc-macros.link_macros) +add_header(dl_info HDR Dl_info.h) add_header(struct_f_owner_ex HDR struct_f_owner_ex.h DEPENDS .pid_t) add_header(struct_flock HDR struct_flock.h DEPENDS .off_t .pid_t) add_header(struct_flock64 HDR struct_flock64.h DEPENDS .off64_t .pid_t) diff --git a/libc/include/llvm-libc-types/Dl_info.h b/libc/include/llvm-libc-types/Dl_info.h new file mode 100644 index 0000000..b082e30 --- /dev/null +++ b/libc/include/llvm-libc-types/Dl_info.h @@ -0,0 +1,19 @@ +//===-- Definition of Dl_info type ----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_DL_INFO_H +#define LLVM_LIBC_TYPES_DL_INFO_H + +typedef struct { + const char *dli_fname; + void *dli_fbase; + const char *dli_sname; + void *dli_saddr; +} Dl_info; + +#endif // LLVM_LIBC_TYPES_DL_INFO_H diff --git a/libc/include/math.yaml b/libc/include/math.yaml index e8ac7ee..17f26fc 100644 --- a/libc/include/math.yaml +++ b/libc/include/math.yaml @@ -79,6 +79,13 @@ functions: arguments: - type: _Float16 guard: LIBC_TYPES_HAS_FLOAT16 + - name: asinpif16 + standards: + - stdc + return_type: _Float16 + arguments: + - type: _Float16 + guard: LIBC_TYPES_HAS_FLOAT16 - name: atan standards: - stdc @@ -134,6 +141,13 @@ functions: arguments: - type: float - name: atanhf16 + standatds: + - stdc + return_type: _Float16 + arguments: + - type: _Float16 + guard: LIBC_TYPES_HAS_FLOAT16 + - name: atanpif16 standards: - stdc return_type: _Float16 @@ -303,10 +317,33 @@ functions: arguments: - type: _Float16 guard: LIBC_TYPES_HAS_FLOAT16 + - name: daddf128 + standards: + - llvm_libc_ext + return_type: double + arguments: + - type: float128 + - type: float128 + guard: LIBC_TYPES_HAS_FLOAT128 + - name: daddl + standards: + - stdc + return_type: double + arguments: + - type: long double + - type: long double + - name: ddivf128 + standards: + - llvm_libc_ext + return_type: double + arguments: + - type: float128 + - type: float128 + guard: LIBC_TYPES_HAS_FLOAT128 - name: ddivl standards: - stdc - return_type: long double + return_type: double arguments: - type: long double - type: long double @@ -325,13 +362,20 @@ functions: arguments: - type: long double - type: long double + - name: dsqrtf128 + standards: + - llvm_libc_ext + return_type: double + arguments: + - type: float128 + guard: LIBC_TYPES_HAS_FLOAT128 - name: dsqrtl standards: - stdc return_type: double arguments: - type: long double - - name: dsqrtf128 + - name: dsubf128 standards: - llvm_libc_ext return_type: double @@ -339,6 +383,13 @@ functions: - type: float128 - type: float128 guard: LIBC_TYPES_HAS_FLOAT128 + - name: dsubl + standards: + - stdc + return_type: double + arguments: + - type: long double + - type: long double - name: erff standards: - stdc @@ -363,6 +414,13 @@ functions: return_type: float arguments: - type: float + - name: exp10f16 + standards: + - stdc + return_type: _Float16 + arguments: + - type: _Float16 + guard: LIBC_TYPES_HAS_FLOAT16 - name: exp10m1f standards: - stdc @@ -388,6 +446,13 @@ functions: return_type: float arguments: - type: float + - name: exp2f16 + standards: + - stdc + return_type: _Float16 + arguments: + - type: _Float16 + guard: LIBC_TYPES_HAS_FLOAT16 - name: exp2m1f standards: - stdc @@ -407,6 +472,13 @@ functions: return_type: float arguments: - type: float + - name: expf16 + standards: + - stdc + return_type: _Float16 + arguments: + - type: _Float16 + guard: LIBC_TYPES_HAS_FLOAT16 - name: expm1 standards: - stdc @@ -419,6 +491,13 @@ functions: return_type: float arguments: - type: float + - name: expm1f16 + standards: + - stdc + return_type: _Float16 + arguments: + - type: _Float16 + guard: LIBC_TYPES_HAS_FLOAT16 - name: f16add standards: - llvm_libc_ext @@ -1132,6 +1211,13 @@ functions: - type: _Float16 - type: _Float16 guard: LIBC_TYPES_HAS_FLOAT16 + - name: fminimum_numl + standards: + - stdc + return_type: long double + arguments: + - type: long double + - type: long double - name: fminimumf standards: - stdc @@ -2425,14 +2511,6 @@ functions: return_type: double arguments: - type: double - - name: sincosf - standards: - - gnu - return_type: void - arguments: - - type: float - - type: float * - - type: float * - name: sinf standards: - stdc @@ -2446,6 +2524,22 @@ functions: arguments: - type: _Float16 guard: LIBC_TYPES_HAS_FLOAT16 + - name: sincos + standards: + - gnu + return_type: void + arguments: + - type: double + - type: double * + - type: double * + - name: sincosf + standards: + - gnu + return_type: void + arguments: + - type: float + - type: float * + - type: float * - name: sinhf standards: - stdc diff --git a/libc/include/sched.yaml b/libc/include/sched.yaml index f14799d..8014aa7 100644 --- a/libc/include/sched.yaml +++ b/libc/include/sched.yaml @@ -20,7 +20,7 @@ functions: - type: const cpu_set_t * - name: getcpu standards: - - POSIX + - Linux return_type: int arguments: - type: unsigned int * diff --git a/libc/include/sys/ioctl.yaml b/libc/include/sys/ioctl.yaml index 5f7b7f3..7eb66b6 100644 --- a/libc/include/sys/ioctl.yaml +++ b/libc/include/sys/ioctl.yaml @@ -5,4 +5,12 @@ macros: [] types: [] enums: [] objects: [] -functions: [] +functions: + - name: ioctl + standards: + - Linux + return_type: int + arguments: + - type: int + - type: unsigned long + - type: '...' diff --git a/libc/shared/math.h b/libc/shared/math.h index 3714f38..69d785b 100644 --- a/libc/shared/math.h +++ b/libc/shared/math.h @@ -31,6 +31,14 @@ #include "math/atanhf.h" #include "math/atanhf16.h" #include "math/cbrt.h" +#include "math/cbrtf.h" +#include "math/cos.h" +#include "math/cosf.h" +#include "math/cosf16.h" +#include "math/coshf.h" +#include "math/coshf16.h" +#include "math/cospif.h" +#include "math/cospif16.h" #include "math/erff.h" #include "math/exp.h" #include "math/exp10.h" diff --git a/libc/shared/math/cbrtf.h b/libc/shared/math/cbrtf.h new file mode 100644 index 0000000..09b86be --- /dev/null +++ b/libc/shared/math/cbrtf.h @@ -0,0 +1,23 @@ +//===-- Shared cbrtf function -----------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LIBC_SHARED_MATH_CBRTF_H +#define LIBC_SHARED_MATH_CBRTF_H + +#include "shared/libc_common.h" +#include "src/__support/math/cbrtf.h" + +namespace LIBC_NAMESPACE_DECL { +namespace shared { + +using math::cbrtf; + +} // namespace shared +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_SHARED_MATH_CBRTF_H diff --git a/libc/shared/math/cos.h b/libc/shared/math/cos.h new file mode 100644 index 0000000..c498550 --- /dev/null +++ b/libc/shared/math/cos.h @@ -0,0 +1,23 @@ +//===-- Shared cos function -------------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SHARED_MATH_COS_H +#define LLVM_LIBC_SHARED_MATH_COS_H + +#include "shared/libc_common.h" +#include "src/__support/math/cos.h" + +namespace LIBC_NAMESPACE_DECL { +namespace shared { + +using math::cos; + +} // namespace shared +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SHARED_MATH_COS_H diff --git a/libc/shared/math/cosf.h b/libc/shared/math/cosf.h new file mode 100644 index 0000000..0618220 --- /dev/null +++ b/libc/shared/math/cosf.h @@ -0,0 +1,23 @@ +//===-- Shared cosf function ------------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SHARED_MATH_COSF_H +#define LLVM_LIBC_SHARED_MATH_COSF_H + +#include "shared/libc_common.h" +#include "src/__support/math/cosf.h" + +namespace LIBC_NAMESPACE_DECL { +namespace shared { + +using math::cosf; + +} // namespace shared +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SHARED_MATH_COSF_H diff --git a/libc/shared/math/cosf16.h b/libc/shared/math/cosf16.h new file mode 100644 index 0000000..8a19285 --- /dev/null +++ b/libc/shared/math/cosf16.h @@ -0,0 +1,28 @@ +//===-- Shared cosf16 function ----------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SHARED_MATH_COSF16_H +#define LLVM_LIBC_SHARED_MATH_COSF16_H + +#include "shared/libc_common.h" + +#ifdef LIBC_TYPES_HAS_FLOAT16 + +#include "src/__support/math/cosf16.h" + +namespace LIBC_NAMESPACE_DECL { +namespace shared { + +using math::cosf16; + +} // namespace shared +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_TYPES_HAS_FLOAT16 + +#endif // LLVM_LIBC_SHARED_MATH_COSF16_H diff --git a/libc/shared/math/coshf.h b/libc/shared/math/coshf.h new file mode 100644 index 0000000..33c2580 --- /dev/null +++ b/libc/shared/math/coshf.h @@ -0,0 +1,23 @@ +//===-- Shared coshf function -----------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SHARED_MATH_COSHF_H +#define LLVM_LIBC_SHARED_MATH_COSHF_H + +#include "shared/libc_common.h" +#include "src/__support/math/coshf.h" + +namespace LIBC_NAMESPACE_DECL { +namespace shared { + +using math::coshf; + +} // namespace shared +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SHARED_MATH_COSHF_H diff --git a/libc/shared/math/coshf16.h b/libc/shared/math/coshf16.h new file mode 100644 index 0000000..66e8d14 --- /dev/null +++ b/libc/shared/math/coshf16.h @@ -0,0 +1,28 @@ +//===-- Shared coshf16 function ---------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SHARED_MATH_COSHF16_H +#define LLVM_LIBC_SHARED_MATH_COSHF16_H + +#include "shared/libc_common.h" + +#ifdef LIBC_TYPES_HAS_FLOAT16 + +#include "src/__support/math/coshf16.h" + +namespace LIBC_NAMESPACE_DECL { +namespace shared { + +using math::coshf16; + +} // namespace shared +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_TYPES_HAS_FLOAT16 + +#endif // LLVM_LIBC_SHARED_MATH_COSHF16_H diff --git a/libc/shared/math/cospif.h b/libc/shared/math/cospif.h new file mode 100644 index 0000000..ce664e9 --- /dev/null +++ b/libc/shared/math/cospif.h @@ -0,0 +1,23 @@ +//===-- Shared cospif function ----------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SHARED_MATH_COSPIF_H +#define LLVM_LIBC_SHARED_MATH_COSPIF_H + +#include "shared/libc_common.h" +#include "src/__support/math/cospif.h" + +namespace LIBC_NAMESPACE_DECL { +namespace shared { + +using math::cospif; + +} // namespace shared +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SHARED_MATH_COSPIF_H diff --git a/libc/shared/math/cospif16.h b/libc/shared/math/cospif16.h new file mode 100644 index 0000000..a1680b0 --- /dev/null +++ b/libc/shared/math/cospif16.h @@ -0,0 +1,28 @@ +//===-- Shared cospif16 function --------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SHARED_MATH_COSPIF16_H +#define LLVM_LIBC_SHARED_MATH_COSPIF16_H + +#include "shared/libc_common.h" + +#ifdef LIBC_TYPES_HAS_FLOAT16 + +#include "src/__support/math/cospif16.h" + +namespace LIBC_NAMESPACE_DECL { +namespace shared { + +using math::cospif16; + +} // namespace shared +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_TYPES_HAS_FLOAT16 + +#endif // LLVM_LIBC_SHARED_MATH_COSPIF_H diff --git a/libc/shared/rpc.h b/libc/shared/rpc.h index 7295efd..dac2a79 100644 --- a/libc/shared/rpc.h +++ b/libc/shared/rpc.h @@ -551,6 +551,9 @@ template <uint32_t opcode> RPC_ATTRS Client::Port Client::open() { /// port if it has a pending receive operation RPC_ATTRS rpc::optional<typename Server::Port> Server::try_open(uint32_t lane_size, uint32_t start) { + if (rpc::get_lane_id() >= lane_size) + return rpc::nullopt; + // Perform a naive linear scan for a port that has a pending request. for (uint32_t index = start; index < process.port_count; ++index) { uint64_t lane_mask = rpc::get_lane_mask(); diff --git a/libc/src/__support/CPP/CMakeLists.txt b/libc/src/__support/CPP/CMakeLists.txt index 8b65a8839..a389a6d 100644 --- a/libc/src/__support/CPP/CMakeLists.txt +++ b/libc/src/__support/CPP/CMakeLists.txt @@ -210,3 +210,9 @@ add_object_library( libc.src.__support.common libc.src.__support.macros.properties.os ) + +add_header_library( + simd + HDRS + simd.h +) diff --git a/libc/src/__support/CPP/algorithm.h b/libc/src/__support/CPP/algorithm.h index 7704b3f..de0c473 100644 --- a/libc/src/__support/CPP/algorithm.h +++ b/libc/src/__support/CPP/algorithm.h @@ -18,6 +18,12 @@ namespace LIBC_NAMESPACE_DECL { namespace cpp { +template <class T = void> struct plus {}; +template <class T = void> struct multiplies {}; +template <class T = void> struct bit_and {}; +template <class T = void> struct bit_or {}; +template <class T = void> struct bit_xor {}; + template <class T> LIBC_INLINE constexpr const T &max(const T &a, const T &b) { return (a < b) ? b : a; } diff --git a/libc/src/__support/CPP/simd.h b/libc/src/__support/CPP/simd.h new file mode 100644 index 0000000..449455c --- /dev/null +++ b/libc/src/__support/CPP/simd.h @@ -0,0 +1,276 @@ +//===-- Portable SIMD library similar to stdx::simd -------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file provides a generic interface into fixed-size SIMD instructions +// using the clang vector type. The API shares some similarities with the +// stdx::simd proposal, but instead chooses to use vectors as primitive types +// with several extra helper functions. +// +//===----------------------------------------------------------------------===// + +#include "hdr/stdint_proxy.h" +#include "src/__support/CPP/algorithm.h" +#include "src/__support/CPP/limits.h" +#include "src/__support/CPP/type_traits.h" +#include "src/__support/macros/attributes.h" +#include "src/__support/macros/config.h" + +#include <stddef.h> + +#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_SIMD_H +#define LLVM_LIBC_SRC___SUPPORT_CPP_SIMD_H + +#if LIBC_HAS_VECTOR_TYPE + +namespace LIBC_NAMESPACE_DECL { +namespace cpp { + +namespace internal { + +template <typename T> +using get_as_integer_type_t = unsigned _BitInt(sizeof(T) * CHAR_BIT); + +#if defined(LIBC_TARGET_CPU_HAS_AVX512F) +template <typename T> +inline constexpr size_t native_vector_size = 64 / sizeof(T); +#elif defined(LIBC_TARGET_CPU_HAS_AVX2) +template <typename T> +inline constexpr size_t native_vector_size = 32 / sizeof(T); +#elif defined(LIBC_TARGET_CPU_HAS_SSE2) || defined(LIBC_TARGET_CPU_HAS_ARM_NEON) +template <typename T> +inline constexpr size_t native_vector_size = 16 / sizeof(T); +#else +template <typename T> inline constexpr size_t native_vector_size = 1; +#endif + +template <typename T> LIBC_INLINE constexpr T poison() { + return __builtin_nondeterministic_value(T()); +} +} // namespace internal + +// Type aliases. +template <typename T, size_t N> +using fixed_size_simd = T [[clang::ext_vector_type(N)]]; +template <typename T, size_t N = internal::native_vector_size<T>> +using simd = T [[clang::ext_vector_type(N)]]; +template <typename T> +using simd_mask = simd<bool, internal::native_vector_size<T>>; + +// Type trait helpers. +template <typename T> +struct simd_size : cpp::integral_constant<size_t, __builtin_vectorelements(T)> { +}; +template <class T> constexpr size_t simd_size_v = simd_size<T>::value; + +template <typename T> struct is_simd : cpp::integral_constant<bool, false> {}; +template <typename T, unsigned N> +struct is_simd<simd<T, N>> : cpp::integral_constant<bool, true> {}; +template <class T> constexpr bool is_simd_v = is_simd<T>::value; + +template <typename T> +struct is_simd_mask : cpp::integral_constant<bool, false> {}; +template <unsigned N> +struct is_simd_mask<simd<bool, N>> : cpp::integral_constant<bool, true> {}; +template <class T> constexpr bool is_simd_mask_v = is_simd_mask<T>::value; + +template <typename T> struct simd_element_type; +template <typename T, size_t N> struct simd_element_type<simd<T, N>> { + using type = T; +}; +template <typename T> +using simd_element_type_t = typename simd_element_type<T>::type; + +template <typename T> +using enable_if_simd_t = cpp::enable_if_t<is_simd_v<T>, T>; + +// Casting. +template <typename To, typename From, size_t N> +LIBC_INLINE constexpr simd<To, N> simd_cast(simd<From, N> v) { + return __builtin_convertvector(v, simd<To, N>); +} + +// SIMD mask operations. +template <size_t N> LIBC_INLINE constexpr bool all_of(simd<bool, N> m) { + return __builtin_reduce_and(m); +} +template <size_t N> LIBC_INLINE constexpr bool any_of(simd<bool, N> m) { + return __builtin_reduce_or(m); +} +template <size_t N> LIBC_INLINE constexpr bool none_of(simd<bool, N> m) { + return !any_of(m); +} +template <size_t N> LIBC_INLINE constexpr bool some_of(simd<bool, N> m) { + return any_of(m) && !all_of(m); +} +template <size_t N> LIBC_INLINE constexpr int popcount(simd<bool, N> m) { + return __builtin_popcountg(m); +} +template <size_t N> LIBC_INLINE constexpr int find_first_set(simd<bool, N> m) { + return __builtin_ctzg(m); +} +template <size_t N> LIBC_INLINE constexpr int find_last_set(simd<bool, N> m) { + constexpr size_t size = simd_size_v<simd<bool, N>>; + return size - __builtin_clzg(m); +} + +// Elementwise operations. +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> min(simd<T, N> x, simd<T, N> y) { + return __builtin_elementwise_min(x, y); +} +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> max(simd<T, N> x, simd<T, N> y) { + return __builtin_elementwise_max(x, y); +} + +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> abs(simd<T, N> x) { + return __builtin_elementwise_abs(x); +} +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> fma(simd<T, N> x, simd<T, N> y, simd<T, N> z) { + return __builtin_elementwise_fma(x, y, z); +} +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> ceil(simd<T, N> x) { + return __builtin_elementwise_ceil(x); +} +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> floor(simd<T, N> x) { + return __builtin_elementwise_floor(x); +} +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> roundeven(simd<T, N> x) { + return __builtin_elementwise_roundeven(x); +} +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> round(simd<T, N> x) { + return __builtin_elementwise_round(x); +} +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> trunc(simd<T, N> x) { + return __builtin_elementwise_trunc(x); +} +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> nearbyint(simd<T, N> x) { + return __builtin_elementwise_nearbyint(x); +} +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> rint(simd<T, N> x) { + return __builtin_elementwise_rint(x); +} +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> canonicalize(simd<T, N> x) { + return __builtin_elementwise_canonicalize(x); +} +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> copysign(simd<T, N> x, simd<T, N> y) { + return __builtin_elementwise_copysign(x, y); +} +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> fmod(simd<T, N> x, simd<T, N> y) { + return __builtin_elementwise_fmod(x, y); +} + +// Reduction operations. +template <typename T, size_t N, typename Op = cpp::plus<>> +LIBC_INLINE constexpr T reduce(simd<T, N> v, Op op = {}) { + return reduce(v, op); +} +template <typename T, size_t N> +LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::plus<>) { + return __builtin_reduce_add(v); +} +template <typename T, size_t N> +LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::multiplies<>) { + return __builtin_reduce_mul(v); +} +template <typename T, size_t N> +LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::bit_and<>) { + return __builtin_reduce_and(v); +} +template <typename T, size_t N> +LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::bit_or<>) { + return __builtin_reduce_or(v); +} +template <typename T, size_t N> +LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::bit_xor<>) { + return __builtin_reduce_xor(v); +} +template <typename T, size_t N> LIBC_INLINE constexpr T hmin(simd<T, N> v) { + return __builtin_reduce_min(v); +} +template <typename T, size_t N> LIBC_INLINE constexpr T hmax(simd<T, N> v) { + return __builtin_reduce_max(v); +} + +// Accessor helpers. +template <typename T> +LIBC_INLINE enable_if_simd_t<T> load_unaligned(const void *ptr) { + T tmp; + __builtin_memcpy(&tmp, ptr, sizeof(T)); + return tmp; +} +template <typename T> +LIBC_INLINE enable_if_simd_t<T> load_aligned(const void *ptr) { + return load_unaligned<T>(__builtin_assume_aligned(ptr, alignof(T))); +} +template <typename T> +LIBC_INLINE enable_if_simd_t<T> store_unaligned(T v, void *ptr) { + __builtin_memcpy(ptr, &v, sizeof(T)); +} +template <typename T> +LIBC_INLINE enable_if_simd_t<T> store_aligned(T v, void *ptr) { + store_unaligned<T>(v, __builtin_assume_aligned(ptr, alignof(T))); +} +template <typename T> +LIBC_INLINE enable_if_simd_t<T> +masked_load(simd<bool, simd_size_v<T>> m, void *ptr, + T passthru = internal::poison<simd_element_type<T>>()) { + return __builtin_masked_load(m, ptr, passthru); +} +template <typename T> +LIBC_INLINE enable_if_simd_t<T> masked_store(simd<bool, simd_size_v<T>> m, T v, + void *ptr) { + __builtin_masked_store( + m, v, static_cast<T *>(__builtin_assume_aligned(ptr, alignof(T)))); +} + +// Construction helpers. +template <typename T, size_t N> LIBC_INLINE constexpr simd<T, N> splat(T v) { + return simd<T, N>(v); +} +template <typename T> LIBC_INLINE constexpr simd<T> splat(T v) { + return splat<T, simd_size_v<simd<T>>>(v); +} +template <typename T, unsigned N> +LIBC_INLINE constexpr simd<T, N> iota(T base = T(0), T step = T(1)) { + simd<T, N> v{}; + for (unsigned i = 0; i < N; ++i) + v[i] = base + T(i) * step; + return v; +} +template <typename T> +LIBC_INLINE constexpr simd<T> iota(T base = T(0), T step = T(1)) { + return iota<T, simd_size_v<simd<T>>>(base, step); +} + +// Conditional helpers. +template <typename T, size_t N> +LIBC_INLINE constexpr simd<T, N> select(simd<bool, N> m, simd<T, N> x, + simd<T, N> y) { + return m ? x : y; +} + +// TODO: where expressions, scalar overloads, ABI types. + +} // namespace cpp +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_HAS_VECTOR_TYPE +#endif diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h index 2357b05..ca7be66 100644 --- a/libc/src/__support/FPUtil/BasicOperations.h +++ b/libc/src/__support/FPUtil/BasicOperations.h @@ -244,7 +244,7 @@ LIBC_INLINE T fdim(T x, T y) { return y; } - return (x > y ? x - y : 0); + return (x > y ? x - y : T(0)); } // Avoid reusing `issignaling` macro. diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt index 6e447fc..e8fc539 100644 --- a/libc/src/__support/FPUtil/CMakeLists.txt +++ b/libc/src/__support/FPUtil/CMakeLists.txt @@ -231,6 +231,7 @@ add_header_library( Hypot.h DEPENDS .basic_operations + .cast .fenv_impl .fp_bits .rounding_mode @@ -285,6 +286,9 @@ add_header_library( libc.hdr.stdint_proxy libc.src.__support.CPP.bit libc.src.__support.CPP.type_traits + libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.FPUtil.generic.div + libc.src.__support.FPUtil.generic.mul libc.src.__support.macros.config libc.src.__support.macros.properties.types ) diff --git a/libc/src/__support/FPUtil/Hypot.h b/libc/src/__support/FPUtil/Hypot.h index 94da259c..e23f8b5 100644 --- a/libc/src/__support/FPUtil/Hypot.h +++ b/libc/src/__support/FPUtil/Hypot.h @@ -12,6 +12,7 @@ #include "BasicOperations.h" #include "FEnvImpl.h" #include "FPBits.h" +#include "cast.h" #include "rounding_mode.h" #include "src/__support/CPP/bit.h" #include "src/__support/CPP/type_traits.h" @@ -133,8 +134,18 @@ LIBC_INLINE T hypot(T x, T y) { uint16_t a_exp = a_bits.get_biased_exponent(); uint16_t b_exp = b_bits.get_biased_exponent(); - if ((a_exp - b_exp >= FPBits_t::FRACTION_LEN + 2) || (x == 0) || (y == 0)) - return x_abs.get_val() + y_abs.get_val(); + if ((a_exp - b_exp >= FPBits_t::FRACTION_LEN + 2) || (x == 0) || (y == 0)) { +#ifdef LIBC_TYPES_HAS_FLOAT16 + if constexpr (cpp::is_same_v<T, float16>) { + // Compiler runtime for basic operations of float16 might not be correctly + // rounded for all rounding modes. + float af = fputil::cast<float>(x_abs.get_val()); + float bf = fputil::cast<float>(y_abs.get_val()); + return fputil::cast<float16>(af + bf); + } else +#endif // LIBC_TYPES_HAS_FLOAT16 + return x_abs.get_val() + y_abs.get_val(); + } uint64_t out_exp = a_exp; StorageType a_mant = a_bits.get_mantissa(); diff --git a/libc/src/__support/FPUtil/bfloat16.h b/libc/src/__support/FPUtil/bfloat16.h index fa45d73..13e1512 100644 --- a/libc/src/__support/FPUtil/bfloat16.h +++ b/libc/src/__support/FPUtil/bfloat16.h @@ -15,6 +15,9 @@ #include "src/__support/FPUtil/cast.h" #include "src/__support/FPUtil/comparison_operations.h" #include "src/__support/FPUtil/dyadic_float.h" +#include "src/__support/FPUtil/generic/add_sub.h" +#include "src/__support/FPUtil/generic/div.h" +#include "src/__support/FPUtil/generic/mul.h" #include "src/__support/macros/config.h" #include "src/__support/macros/properties/types.h" @@ -26,9 +29,9 @@ struct BFloat16 { LIBC_INLINE BFloat16() = default; - LIBC_INLINE constexpr explicit BFloat16(uint16_t bits) : bits(bits) {} - - template <typename T> LIBC_INLINE constexpr explicit BFloat16(T value) { + template <typename T> + LIBC_INLINE constexpr explicit BFloat16(T value) + : bits(static_cast<uint16_t>(0U)) { if constexpr (cpp::is_floating_point_v<T>) { bits = fputil::cast<bfloat16>(value).bits; } else if constexpr (cpp::is_integral_v<T>) { @@ -45,6 +48,8 @@ struct BFloat16 { xd(sign, 0, value); bits = xd.template as<bfloat16, /*ShouldSignalExceptions=*/true>().bits; + } else if constexpr (cpp::is_convertible_v<T, BFloat16>) { + bits = value.operator BFloat16().bits; } else { bits = fputil::cast<bfloat16>(static_cast<float>(value)).bits; } @@ -58,6 +63,11 @@ struct BFloat16 { return cpp::bit_cast<float>(x_bits); } + template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0> + LIBC_INLINE constexpr explicit operator T() const { + return static_cast<T>(static_cast<float>(*this)); + } + LIBC_INLINE bool operator==(BFloat16 other) const { return fputil::equals(*this, other); } @@ -81,6 +91,28 @@ struct BFloat16 { LIBC_INLINE bool operator>=(BFloat16 other) const { return fputil::greater_than_or_equals(*this, other); } + + LIBC_INLINE constexpr BFloat16 operator-() const { + fputil::FPBits<bfloat16> result(*this); + result.set_sign(result.is_pos() ? Sign::NEG : Sign::POS); + return result.get_val(); + } + + LIBC_INLINE BFloat16 operator+(BFloat16 other) const { + return fputil::generic::add<BFloat16>(*this, other); + } + + LIBC_INLINE BFloat16 operator-(BFloat16 other) const { + return fputil::generic::sub<BFloat16>(*this, other); + } + + LIBC_INLINE BFloat16 operator*(BFloat16 other) const { + return fputil::generic::mul<bfloat16>(*this, other); + } + + LIBC_INLINE BFloat16 operator/(BFloat16 other) const { + return fputil::generic::div<bfloat16>(*this, other); + } }; // struct BFloat16 } // namespace fputil diff --git a/libc/src/__support/FPUtil/cast.h b/libc/src/__support/FPUtil/cast.h index e999ece..54c80e8 100644 --- a/libc/src/__support/FPUtil/cast.h +++ b/libc/src/__support/FPUtil/cast.h @@ -27,47 +27,47 @@ LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<OutType> && OutType> cast(InType x) { // Casting to the same type is a no-op. - if constexpr (cpp::is_same_v<InType, OutType>) + if constexpr (cpp::is_same_v<InType, OutType>) { return x; - - // bfloat16 is always defined (for now) - if constexpr (cpp::is_same_v<OutType, bfloat16> || - cpp::is_same_v<InType, bfloat16> + } else { + if constexpr (cpp::is_same_v<OutType, bfloat16> || + cpp::is_same_v<InType, bfloat16> #if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION) - || cpp::is_same_v<OutType, float16> || - cpp::is_same_v<InType, float16> + || cpp::is_same_v<OutType, float16> || + cpp::is_same_v<InType, float16> #endif - ) { - using InFPBits = FPBits<InType>; - using InStorageType = typename InFPBits::StorageType; - using OutFPBits = FPBits<OutType>; - using OutStorageType = typename OutFPBits::StorageType; + ) { + using InFPBits = FPBits<InType>; + using InStorageType = typename InFPBits::StorageType; + using OutFPBits = FPBits<OutType>; + using OutStorageType = typename OutFPBits::StorageType; - InFPBits x_bits(x); + InFPBits x_bits(x); - if (x_bits.is_nan()) { - if (x_bits.is_signaling_nan()) { - raise_except_if_required(FE_INVALID); - return OutFPBits::quiet_nan().get_val(); - } + if (x_bits.is_nan()) { + if (x_bits.is_signaling_nan()) { + raise_except_if_required(FE_INVALID); + return OutFPBits::quiet_nan().get_val(); + } - InStorageType x_mant = x_bits.get_mantissa(); - if (InFPBits::FRACTION_LEN > OutFPBits::FRACTION_LEN) - x_mant >>= InFPBits::FRACTION_LEN - OutFPBits::FRACTION_LEN; - return OutFPBits::quiet_nan(x_bits.sign(), - static_cast<OutStorageType>(x_mant)) - .get_val(); - } + InStorageType x_mant = x_bits.get_mantissa(); + if (InFPBits::FRACTION_LEN > OutFPBits::FRACTION_LEN) + x_mant >>= InFPBits::FRACTION_LEN - OutFPBits::FRACTION_LEN; + return OutFPBits::quiet_nan(x_bits.sign(), + static_cast<OutStorageType>(x_mant)) + .get_val(); + } - if (x_bits.is_inf()) - return OutFPBits::inf(x_bits.sign()).get_val(); + if (x_bits.is_inf()) + return OutFPBits::inf(x_bits.sign()).get_val(); - constexpr size_t MAX_FRACTION_LEN = - cpp::max(OutFPBits::FRACTION_LEN, InFPBits::FRACTION_LEN); - DyadicFloat<cpp::bit_ceil(MAX_FRACTION_LEN)> xd(x); - return xd.template as<OutType, /*ShouldSignalExceptions=*/true>(); - } else { - return static_cast<OutType>(x); + constexpr size_t MAX_FRACTION_LEN = + cpp::max(OutFPBits::FRACTION_LEN, InFPBits::FRACTION_LEN); + DyadicFloat<cpp::bit_ceil(MAX_FRACTION_LEN)> xd(x); + return xd.template as<OutType, /*ShouldSignalExceptions=*/true>(); + } else { + return static_cast<OutType>(x); + } } } diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h index 3464e4a..cc0710f 100644 --- a/libc/src/__support/FPUtil/dyadic_float.h +++ b/libc/src/__support/FPUtil/dyadic_float.h @@ -576,7 +576,7 @@ LIBC_INLINE constexpr DyadicFloat<Bits> quick_mul(const DyadicFloat<Bits> &a, // Check the leading bit directly, should be faster than using clz in // normalize(). if (result.mantissa.val[DyadicFloat<Bits>::MantissaType::WORD_COUNT - 1] >> - 63 == + (DyadicFloat<Bits>::MantissaType::WORD_SIZE - 1) == 0) result.shift_left(1); } else { diff --git a/libc/src/__support/FPUtil/generic/CMakeLists.txt b/libc/src/__support/FPUtil/generic/CMakeLists.txt index 117213f..b75efc8 100644 --- a/libc/src/__support/FPUtil/generic/CMakeLists.txt +++ b/libc/src/__support/FPUtil/generic/CMakeLists.txt @@ -68,6 +68,7 @@ add_header_library( libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.attributes libc.src.__support.macros.optimization + libc.src.__support.macros.properties.types ) add_header_library( @@ -77,6 +78,7 @@ add_header_library( DEPENDS libc.hdr.errno_macros libc.hdr.fenv_macros + libc.src.__support.CPP.algorithm libc.src.__support.CPP.bit libc.src.__support.CPP.type_traits libc.src.__support.FPUtil.basic_operations diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h index 7205d8d..b2e9d81 100644 --- a/libc/src/__support/FPUtil/generic/add_sub.h +++ b/libc/src/__support/FPUtil/generic/add_sub.h @@ -87,8 +87,12 @@ add_or_sub(InType x, InType y) { return OutFPBits::inf(x_bits.sign()).get_val(); } - if (y_bits.is_inf()) - return OutFPBits::inf(y_bits.sign()).get_val(); + if (y_bits.is_inf()) { + if constexpr (IsSub) + return OutFPBits::inf(y_bits.sign().negate()).get_val(); + else + return OutFPBits::inf(y_bits.sign()).get_val(); + } if (x_bits.is_zero()) { if (y_bits.is_zero()) { @@ -100,13 +104,22 @@ add_or_sub(InType x, InType y) { } } - // volatile prevents Clang from converting tmp to OutType and then - // immediately back to InType before negating it, resulting in double - // rounding. - volatile InType tmp = y; - if constexpr (IsSub) - tmp = -tmp; - return cast<OutType>(tmp); + if constexpr (cpp::is_same_v<InType, bfloat16> && + cpp::is_same_v<OutType, bfloat16>) { + OutFPBits y_bits(y); + if constexpr (IsSub) + y_bits.set_sign(y_bits.sign().negate()); + return y_bits.get_val(); + } else { + + // volatile prevents Clang from converting tmp to OutType and then + // immediately back to InType before negating it, resulting in double + // rounding. + volatile InType tmp = y; + if constexpr (IsSub) + tmp = -tmp; + return cast<OutType>(tmp); + } } if (y_bits.is_zero()) @@ -161,8 +174,8 @@ add_or_sub(InType x, InType y) { int alignment = (max_bits.get_biased_exponent() - max_bits.is_normal()) - (min_bits.get_biased_exponent() - min_bits.is_normal()); - InStorageType aligned_min_mant = - min_mant >> cpp::min(alignment, RESULT_MANTISSA_LEN); + InStorageType aligned_min_mant = static_cast<InStorageType>( + min_mant >> cpp::min(alignment, RESULT_MANTISSA_LEN)); bool aligned_min_mant_sticky; if (alignment <= GUARD_BITS_LEN) diff --git a/libc/src/__support/FPUtil/generic/div.h b/libc/src/__support/FPUtil/generic/div.h index f0e4057..bf7d0b7 100644 --- a/libc/src/__support/FPUtil/generic/div.h +++ b/libc/src/__support/FPUtil/generic/div.h @@ -11,6 +11,7 @@ #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" +#include "src/__support/CPP/algorithm.h" #include "src/__support/CPP/bit.h" #include "src/__support/CPP/type_traits.h" #include "src/__support/FPUtil/BasicOperations.h" @@ -34,8 +35,9 @@ div(InType x, InType y) { using OutStorageType = typename OutFPBits::StorageType; using InFPBits = FPBits<InType>; using InStorageType = typename InFPBits::StorageType; - using DyadicFloat = - DyadicFloat<cpp::bit_ceil(static_cast<size_t>(InFPBits::SIG_LEN + 1))>; + using DyadicFloat = DyadicFloat<cpp::max( + static_cast<size_t>(16), + cpp::bit_ceil(static_cast<size_t>(InFPBits::SIG_LEN + 1)))>; InFPBits x_bits(x); InFPBits y_bits(y); @@ -78,7 +80,7 @@ div(InType x, InType y) { } if (y_bits.is_inf()) - return OutFPBits::inf(result_sign).get_val(); + return OutFPBits::zero(result_sign).get_val(); if (y_bits.is_zero()) { if (x_bits.is_zero()) { diff --git a/libc/src/__support/FPUtil/rounding_mode.h b/libc/src/__support/FPUtil/rounding_mode.h index 4ee0a0b..fdc8498 100644 --- a/libc/src/__support/FPUtil/rounding_mode.h +++ b/libc/src/__support/FPUtil/rounding_mode.h @@ -17,30 +17,24 @@ namespace LIBC_NAMESPACE_DECL { namespace fputil { +namespace generic { + // Quick free-standing test whether fegetround() == FE_UPWARD. // Using the following observation: // 1.0f + 2^-25 = 1.0f for FE_TONEAREST, FE_DOWNWARD, FE_TOWARDZERO // = 0x1.000002f for FE_UPWARD. -LIBC_INLINE static constexpr bool fenv_is_round_up() { - if (cpp::is_constant_evaluated()) { - return false; - } else { - volatile float x = 0x1.0p-25f; - return (1.0f + x != 1.0f); - } +LIBC_INLINE bool fenv_is_round_up() { + static volatile float x = 0x1.0p-25f; + return (1.0f + x != 1.0f); } // Quick free-standing test whether fegetround() == FE_DOWNWARD. // Using the following observation: // -1.0f - 2^-25 = -1.0f for FE_TONEAREST, FE_UPWARD, FE_TOWARDZERO // = -0x1.000002f for FE_DOWNWARD. -LIBC_INLINE static constexpr bool fenv_is_round_down() { - if (cpp::is_constant_evaluated()) { - return false; - } else { - volatile float x = 0x1.0p-25f; - return (-1.0f - x != -1.0f); - } +LIBC_INLINE bool fenv_is_round_down() { + static volatile float x = 0x1.0p-25f; + return (-1.0f - x != -1.0f); } // Quick free-standing test whether fegetround() == FE_TONEAREST. @@ -49,14 +43,10 @@ LIBC_INLINE static constexpr bool fenv_is_round_down() { // = 0x1.100002p0f for FE_UPWARD, // 1.5f - 2^-24 = 1.5f for FE_TONEAREST, FE_UPWARD // = 0x1.0ffffep-1f for FE_DOWNWARD, FE_TOWARDZERO -LIBC_INLINE static constexpr bool fenv_is_round_to_nearest() { - if (cpp::is_constant_evaluated()) { - return true; - } else { - volatile float x = 0x1.0p-24f; - float y = 1.5f + x; - return (y == 1.5f - x); - } +LIBC_INLINE bool fenv_is_round_to_nearest() { + static volatile float x = 0x1.0p-24f; + float y = 1.5f + x; + return (y == 1.5f - x); } // Quick free-standing test whether fegetround() == FE_TOWARDZERO. @@ -69,13 +59,56 @@ LIBC_INLINE static constexpr bool fenv_is_round_to_nearest() { // (0x1.000002p0f + 2^-24) + (-1.0f - 2^-24) = 2^-23 for FE_TOWARDZERO // = 2^-22 for FE_TONEAREST, FE_UPWARD // = 0 for FE_DOWNWARD +LIBC_INLINE bool fenv_is_round_to_zero() { + static volatile float x = 0x1.0p-24f; + float y = x; + return ((0x1.000002p0f + y) + (-1.0f - y) == 0x1.0p-23f); +} + +// Quick free standing get rounding mode based on the above observations. +LIBC_INLINE int quick_get_round() { + static volatile float x = 0x1.0p-24f; + float y = x; + float z = (0x1.000002p0f + y) + (-1.0f - y); + + if (z == 0.0f) + return FE_DOWNWARD; + if (z == 0x1.0p-23f) + return FE_TOWARDZERO; + return (2.0f + y == 2.0f) ? FE_TONEAREST : FE_UPWARD; +} + +} // namespace generic + +LIBC_INLINE static constexpr bool fenv_is_round_up() { + if (cpp::is_constant_evaluated()) { + return false; + } else { + return generic::fenv_is_round_up(); + } +} + +LIBC_INLINE static constexpr bool fenv_is_round_down() { + if (cpp::is_constant_evaluated()) { + return false; + } else { + return generic::fenv_is_round_down(); + } +} + +LIBC_INLINE static constexpr bool fenv_is_round_to_nearest() { + if (cpp::is_constant_evaluated()) { + return true; + } else { + return generic::fenv_is_round_to_nearest(); + } +} + LIBC_INLINE static constexpr bool fenv_is_round_to_zero() { if (cpp::is_constant_evaluated()) { return false; } else { - volatile float x = 0x1.0p-24f; - volatile float y = 0x1.000002p0f + x; - return (y + (-1.0f - x) == 0x1.0p-23f); + return generic::fenv_is_round_to_zero(); } } @@ -84,15 +117,7 @@ LIBC_INLINE static constexpr int quick_get_round() { if (cpp::is_constant_evaluated()) { return FE_TONEAREST; } else { - volatile float x = 0x1.0p-24f; - volatile float y = 0x1.000002p0f + x; - float z = y + (-1.0f - x); - - if (z == 0.0f) - return FE_DOWNWARD; - if (z == 0x1.0p-23f) - return FE_TOWARDZERO; - return (2.0f + x == 2.0f) ? FE_TONEAREST : FE_UPWARD; + return generic::quick_get_round(); } } diff --git a/libc/src/__support/File/file.cpp b/libc/src/__support/File/file.cpp index 303852d..4217e73 100644 --- a/libc/src/__support/File/file.cpp +++ b/libc/src/__support/File/file.cpp @@ -123,7 +123,7 @@ FileIOResult File::write_unlocked_fbf(const uint8_t *data, size_t len) { FileIOResult result = platform_write(this, remainder.data(), remainder.size()); - size_t bytes_written = buf_result.value; + size_t bytes_written = result.value; // If less bytes were written than expected, then an error occurred. Return // the number of bytes that have been written from |data|. diff --git a/libc/src/__support/GPU/CMakeLists.txt b/libc/src/__support/GPU/CMakeLists.txt index f8fdfeb..72a7879 100644 --- a/libc/src/__support/GPU/CMakeLists.txt +++ b/libc/src/__support/GPU/CMakeLists.txt @@ -9,6 +9,12 @@ add_header_library( utils.h ) +add_header_library( + fixedstack + HDRS + fixedstack.h +) + add_object_library( allocator SRCS @@ -23,4 +29,5 @@ add_object_library( libc.src.__support.CPP.bit libc.src.__support.CPP.new .utils + .fixedstack ) diff --git a/libc/src/__support/GPU/allocator.cpp b/libc/src/__support/GPU/allocator.cpp index 250bebd..3da339c 100644 --- a/libc/src/__support/GPU/allocator.cpp +++ b/libc/src/__support/GPU/allocator.cpp @@ -20,6 +20,7 @@ #include "src/__support/CPP/atomic.h" #include "src/__support/CPP/bit.h" #include "src/__support/CPP/new.h" +#include "src/__support/GPU/fixedstack.h" #include "src/__support/GPU/utils.h" #include "src/__support/RPC/rpc_client.h" #include "src/__support/threads/sleep.h" @@ -39,6 +40,9 @@ constexpr static uint32_t MIN_ALIGNMENT = MIN_SIZE - 1; // The number of times to attempt claiming an in-progress slab allocation. constexpr static uint32_t MAX_TRIES = 1024; +// The number of previously allocated slabs we will keep in memory. +constexpr static uint32_t CACHED_SLABS = 8; + static_assert(!(ARRAY_SIZE & (ARRAY_SIZE - 1)), "Must be a power of two"); namespace impl { @@ -162,7 +166,11 @@ static inline uint32_t get_leader_id(uint64_t ballot, uint32_t id) { // We use a sentinal value to indicate a failed or in-progress allocation. template <typename T> bool is_sentinel(const T &x) { - return x == cpp::numeric_limits<T>::max(); + if constexpr (cpp::is_pointer_v<T>) + return reinterpret_cast<uintptr_t>(x) == + cpp::numeric_limits<uintptr_t>::max(); + else + return x == cpp::numeric_limits<T>::max(); } } // namespace impl @@ -185,20 +193,35 @@ struct Slab { struct alignas(MIN_SIZE) Header { uint32_t chunk_size; uint32_t global_index; + uint32_t cached_chunk_size; }; // Initialize the slab with its chunk size and index in the global table for // use when freeing. Slab(uint32_t chunk_size, uint32_t global_index) { Header *header = reinterpret_cast<Header *>(memory); + header->cached_chunk_size = cpp::numeric_limits<uint32_t>::max(); + header->chunk_size = chunk_size; + header->global_index = global_index; + } + + // Reset the memory with a new index and chunk size, not thread safe. + Slab *reset(uint32_t chunk_size, uint32_t global_index) { + Header *header = reinterpret_cast<Header *>(memory); + header->cached_chunk_size = header->chunk_size; header->chunk_size = chunk_size; header->global_index = global_index; + return this; } // Set the necessary bitfield bytes to zero in parallel using many lanes. This // must be called before the bitfield can be accessed safely, memory is not // guaranteed to be zero initialized in the current implementation. void initialize(uint64_t uniform) { + // If this is a re-used slab the memory is already set to zero. + if (get_cached_chunk_size() <= get_chunk_size()) + return; + uint32_t size = (bitfield_bytes(get_chunk_size()) + sizeof(uint32_t) - 1) / sizeof(uint32_t); impl::uniform_memset(get_bitfield(), 0, size, uniform); @@ -236,6 +259,11 @@ struct Slab { return reinterpret_cast<const Header *>(memory)->chunk_size; } + // Get the chunk size that was previously used. + uint32_t get_cached_chunk_size() const { + return reinterpret_cast<const Header *>(memory)->cached_chunk_size; + } + // Get the location in the memory where we will store the global index. uint32_t get_global_index() const { return reinterpret_cast<const Header *>(memory)->global_index; @@ -337,6 +365,9 @@ struct Slab { uint8_t memory[SLAB_SIZE]; }; +// A global cache of previously allocated slabs for efficient reuse. +static FixedStack<Slab *, CACHED_SLABS> slab_cache; + /// A wait-free guard around a pointer resource to be created dynamically if /// space is available and freed once there are no more users. struct GuardPtr { @@ -408,13 +439,24 @@ private: reinterpret_cast<Slab *>(cpp::numeric_limits<uintptr_t>::max()), cpp::MemoryOrder::RELAXED, cpp::MemoryOrder::RELAXED)) { count = cpp::numeric_limits<uint32_t>::max(); + + Slab *cached = nullptr; + if (slab_cache.pop(cached)) + return cached->reset(cpp::forward<Args>(args)...); + void *raw = impl::rpc_allocate(sizeof(Slab)); if (!raw) return nullptr; return new (raw) Slab(cpp::forward<Args>(args)...); } - if (!expected || impl::is_sentinel(reinterpret_cast<uintptr_t>(expected))) + // If there is a slab allocation in progress we retry a few times. + for (uint32_t t = 0; impl::is_sentinel(expected) && t < MAX_TRIES; ++t) { + sleep_briefly(); + expected = ptr.load(cpp::MemoryOrder::RELAXED); + } + + if (!expected || impl::is_sentinel(expected)) return nullptr; if (!ref.acquire(n, count)) @@ -475,8 +517,10 @@ public: if (gpu::get_lane_id() == uint32_t(cpp::countr_zero(mask)) && ref.release(cpp::popcount(mask))) { Slab *p = ptr.load(cpp::MemoryOrder::RELAXED); - p->~Slab(); - impl::rpc_free(p); + if (!slab_cache.push(p)) { + p->~Slab(); + impl::rpc_free(p); + } cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE); ptr.store(nullptr, cpp::MemoryOrder::RELAXED); } @@ -523,16 +567,6 @@ static Slab *find_slab(uint32_t chunk_size, uint64_t &uniform, Slab *slab = slots[index].try_lock(lane_mask, uniform & lane_mask, reserved, chunk_size, index); - // If there is a slab allocation in progress we retry a few times. - for (uint32_t retries = 0; - !slab && !impl::is_sentinel(reserved) && retries < MAX_TRIES; - retries++) { - uint64_t lane_mask = gpu::get_lane_mask(); - slab = slots[index].try_lock(lane_mask, uniform & lane_mask, reserved, - chunk_size, index); - sleep_briefly(); - } - // If we find a slab with a matching chunk size then we store the result. // Otherwise, we need to free the claimed lock and continue. In the case // of out-of-memory we receive a sentinel value and return a failure. diff --git a/libc/src/__support/GPU/fixedstack.h b/libc/src/__support/GPU/fixedstack.h new file mode 100644 index 0000000..6ceaa2f --- /dev/null +++ b/libc/src/__support/GPU/fixedstack.h @@ -0,0 +1,111 @@ +//===-- A lock-free data structure for a fixed capacity stack ---*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_GPU_FIXEDSTACK_H +#define LLVM_LIBC_SRC___SUPPORT_GPU_FIXEDSTACK_H + +#include "src/__support/CPP/atomic.h" +#include "src/__support/threads/sleep.h" + +#include <stdint.h> + +namespace LIBC_NAMESPACE_DECL { + +// A lock-free fixed size stack backed by an underlying array of data. It +// supports push and pop operations in a completely lock-free manner. +template <typename T, uint32_t CAPACITY> struct alignas(16) FixedStack { + // The index is stored as a 20-bit value and cannot index into any more. + static_assert(CAPACITY < 1024 * 1024, "Invalid buffer size"); + + // The head of the free and used stacks. Represents as a 20-bit index combined + // with a 44-bit ABA tag that is updated in a single atomic operation. + uint64_t free; + uint64_t used; + + // The stack is a linked list of indices into the underlying data + uint32_t next[CAPACITY]; + T data[CAPACITY]; + + // Get the 20-bit index into the underlying array from the head. + LIBC_INLINE static constexpr uint32_t get_node(uint64_t head) { + return static_cast<uint32_t>(head & 0xfffff); + } + + // Increment the old ABA tag and merge it into the new index. + LIBC_INLINE static constexpr uint64_t make_head(uint64_t orig, + uint32_t node) { + return static_cast<uint64_t>(node) | (((orig >> 20ul) + 1ul) << 20ul); + } + + // Attempts to pop data from the given stack by making it point to the next + // node. We repeatedly attempt to write to the head using compare-and-swap, + // expecting that it has not been changed by any other thread. + LIBC_INLINE uint32_t pop_impl(cpp::AtomicRef<uint64_t> head) { + uint64_t orig = head.load(cpp::MemoryOrder::RELAXED); + + for (;;) { + if (get_node(orig) == CAPACITY) + return CAPACITY; + + uint32_t node = + cpp::AtomicRef(next[get_node(orig)]).load(cpp::MemoryOrder::RELAXED); + if (head.compare_exchange_strong(orig, make_head(orig, node), + cpp::MemoryOrder::ACQUIRE, + cpp::MemoryOrder::RELAXED)) + break; + } + return get_node(orig); + } + + // Attempts to push data to the given stack by making it point to the new + // node. We repeatedly attempt to write to the head using compare-and-swap, + // expecting that it has not been changed by any other thread. + LIBC_INLINE uint32_t push_impl(cpp::AtomicRef<uint64_t> head, uint32_t node) { + uint64_t orig = head.load(cpp::MemoryOrder::RELAXED); + for (;;) { + next[node] = get_node(orig); + if (head.compare_exchange_strong(orig, make_head(orig, node), + cpp::MemoryOrder::RELEASE, + cpp::MemoryOrder::RELAXED)) + break; + } + return get_node(head.load(cpp::MemoryOrder::RELAXED)); + } + +public: + // Initialize the free stack to be full and the used stack to be empty. We use + // the capacity of the stack as a sentinel value. + LIBC_INLINE constexpr FixedStack() : free(0), used(CAPACITY), data{} { + for (uint32_t i = 0; i < CAPACITY; ++i) + next[i] = i + 1; + } + + LIBC_INLINE bool push(const T &val) { + uint32_t node = pop_impl(cpp::AtomicRef(free)); + if (node == CAPACITY) + return false; + + data[node] = val; + push_impl(cpp::AtomicRef(used), node); + return true; + } + + LIBC_INLINE bool pop(T &val) { + uint32_t node = pop_impl(cpp::AtomicRef(used)); + if (node == CAPACITY) + return false; + + val = data[node]; + push_impl(cpp::AtomicRef(free), node); + return true; + } +}; + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_GPU_FIXEDSTACK_H diff --git a/libc/src/__support/OSUtil/linux/aarch64/vdso.h b/libc/src/__support/OSUtil/linux/aarch64/vdso.h index 3c4c620..ee5777a 100644 --- a/libc/src/__support/OSUtil/linux/aarch64/vdso.h +++ b/libc/src/__support/OSUtil/linux/aarch64/vdso.h @@ -23,6 +23,8 @@ LIBC_INLINE constexpr cpp::string_view symbol_name(VDSOSym sym) { return "__kernel_clock_gettime"; case VDSOSym::ClockGetRes: return "__kernel_clock_getres"; + case VDSOSym::GetRandom: + return "__kernel_getrandom"; default: return ""; } diff --git a/libc/src/__support/OSUtil/linux/vdso_sym.h b/libc/src/__support/OSUtil/linux/vdso_sym.h index 968e153..01f0b72 100644 --- a/libc/src/__support/OSUtil/linux/vdso_sym.h +++ b/libc/src/__support/OSUtil/linux/vdso_sym.h @@ -35,7 +35,8 @@ enum class VDSOSym { RTSigReturn, FlushICache, RiscvHwProbe, - VDSOSymCount + GetRandom, + VDSOSymCount, }; template <VDSOSym sym> LIBC_INLINE constexpr auto dispatcher() { @@ -60,6 +61,9 @@ template <VDSOSym sym> LIBC_INLINE constexpr auto dispatcher() { else if constexpr (sym == VDSOSym::RiscvHwProbe) return static_cast<int (*)(riscv_hwprobe *, size_t, size_t, cpu_set_t *, unsigned)>(nullptr); + else if constexpr (sym == VDSOSym::GetRandom) + return static_cast<int (*)(void *, size_t, unsigned int, void *, size_t)>( + nullptr); else return static_cast<void *>(nullptr); } diff --git a/libc/src/__support/OSUtil/linux/x86_64/vdso.h b/libc/src/__support/OSUtil/linux/x86_64/vdso.h index abe7c33..f46fcb0 100644 --- a/libc/src/__support/OSUtil/linux/x86_64/vdso.h +++ b/libc/src/__support/OSUtil/linux/x86_64/vdso.h @@ -29,6 +29,8 @@ LIBC_INLINE constexpr cpp::string_view symbol_name(VDSOSym sym) { return "__vdso_time"; case VDSOSym::ClockGetRes: return "__vdso_clock_getres"; + case VDSOSym::GetRandom: + return "__vdso_getrandom"; default: return ""; } diff --git a/libc/src/__support/libc_errno.h b/libc/src/__support/libc_errno.h index ab5f6a9..3720cde 100644 --- a/libc/src/__support/libc_errno.h +++ b/libc/src/__support/libc_errno.h @@ -37,18 +37,11 @@ // libc doesn't maintain any internal state, instead the embedder must define // `int *__llvm_libc_errno(void);` C function. #define LIBC_ERRNO_MODE_EXTERNAL 4 -// libc uses system `<errno.h>` `errno` macro directly in the overlay mode; in -// fullbuild mode, effectively the same as `LIBC_ERRNO_MODE_EXTERNAL`. -// In this mode, the public C++ symbol `LIBC_NAMESPACE::libc_errno ` is still -// exported and get redirected to the system `errno` inside its implementation. - -// TODO: Investigate deprecating LIBC_ERRNO_MODE_SYSTEM in favor of -// LIBC_ERRNO_MODE_SYSTEM_INLINE. -// https://github.com/llvm/llvm-project/issues/143454 -#define LIBC_ERRNO_MODE_SYSTEM 5 +// DEPRECATED: #define LIBC_ERRNO_MODE_SYSTEM 5 // In this mode, the libc_errno is simply a macro resolved to `errno` from the // system header <errno.h>. There is no need to link against the -// `libc.src.errno.errno` object. +// `libc.src.errno.errno` object, and public C++ symbol +// `LIBC_NAMESPACE::libc_errno` doesn't exist. #define LIBC_ERRNO_MODE_SYSTEM_INLINE 6 #if !defined(LIBC_ERRNO_MODE) || LIBC_ERRNO_MODE == LIBC_ERRNO_MODE_DEFAULT @@ -56,7 +49,7 @@ #if defined(LIBC_FULL_BUILD) || !defined(LIBC_COPT_PUBLIC_PACKAGING) #define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_THREAD_LOCAL #else -#define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_SYSTEM +#define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_SYSTEM_INLINE #endif #endif // LIBC_ERRNO_MODE @@ -65,7 +58,6 @@ LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_THREAD_LOCAL && \ LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SHARED && \ LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_EXTERNAL && \ - LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SYSTEM && \ LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SYSTEM_INLINE #error LIBC_ERRNO_MODE must be one of the following values: \ LIBC_ERRNO_MODE_DEFAULT, \ @@ -73,7 +65,6 @@ LIBC_ERRNO_MODE_UNDEFINED, \ LIBC_ERRNO_MODE_THREAD_LOCAL, \ LIBC_ERRNO_MODE_SHARED, \ LIBC_ERRNO_MODE_EXTERNAL, \ -LIBC_ERRNO_MODE_SYSTEM, \ LIBC_ERRNO_MODE_SYSTEM_INLINE. #endif diff --git a/libc/src/__support/macros/attributes.h b/libc/src/__support/macros/attributes.h index c647467..145aa3b 100644 --- a/libc/src/__support/macros/attributes.h +++ b/libc/src/__support/macros/attributes.h @@ -17,6 +17,7 @@ #ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_ATTRIBUTES_H #define LLVM_LIBC_SRC___SUPPORT_MACROS_ATTRIBUTES_H +#include "config.h" #include "properties/architectures.h" #ifndef __has_attribute @@ -28,7 +29,32 @@ #define LIBC_INLINE_ASM __asm__ __volatile__ #define LIBC_UNUSED __attribute__((unused)) -#ifdef LIBC_TARGET_ARCH_IS_GPU +// Uses the platform specific specialization +#define LIBC_THREAD_MODE_PLATFORM 0 + +// Mutex guards nothing, used in single-threaded implementations +#define LIBC_THREAD_MODE_SINGLE 1 + +// Vendor provides implementation +#define LIBC_THREAD_MODE_EXTERNAL 2 + +// libcxx doesn't define LIBC_THREAD_MODE, unless that is passed in the command +// line in the CMake invocation. This defaults to the original implementation +// (before changes in https://github.com/llvm/llvm-project/pull/145358) +#ifndef LIBC_THREAD_MODE +#define LIBC_THREAD_MODE LIBC_THREAD_MODE_PLATFORM +#endif // LIBC_THREAD_MODE + +#if LIBC_THREAD_MODE != LIBC_THREAD_MODE_PLATFORM && \ + LIBC_THREAD_MODE != LIBC_THREAD_MODE_SINGLE && \ + LIBC_THREAD_MODE != LIBC_THREAD_MODE_EXTERNAL +#error LIBC_THREAD_MODE must be one of the following values: \ +LIBC_THREAD_MODE_PLATFORM, \ +LIBC_THREAD_MODE_SINGLE, \ +LIBC_THREAD_MODE_EXTERNAL. +#endif + +#if LIBC_THREAD_MODE == LIBC_THREAD_MODE_SINGLE #define LIBC_THREAD_LOCAL #else #define LIBC_THREAD_LOCAL thread_local @@ -48,4 +74,11 @@ #define LIBC_PREFERED_TYPE(TYPE) #endif +#if __has_attribute(ext_vector_type) && \ + LIBC_HAS_FEATURE(ext_vector_type_boolean) +#define LIBC_HAS_VECTOR_TYPE 1 +#else +#define LIBC_HAS_VECTOR_TYPE 0 +#endif + #endif // LLVM_LIBC_SRC___SUPPORT_MACROS_ATTRIBUTES_H diff --git a/libc/src/__support/macros/properties/cpu_features.h b/libc/src/__support/macros/properties/cpu_features.h index fde30ea..fc6099c 100644 --- a/libc/src/__support/macros/properties/cpu_features.h +++ b/libc/src/__support/macros/properties/cpu_features.h @@ -59,6 +59,10 @@ #endif // LIBC_TARGET_CPU_HAS_ARM_FPU_DOUBLE #endif // __ARM_FP +#if defined(__ARM_NEON) +#define LIBC_TARGET_CPU_HAS_ARM_NEON +#endif + #if defined(__riscv_flen) // https://github.com/riscv-non-isa/riscv-c-api-doc/blob/main/src/c-api.adoc #if defined(__riscv_zfhmin) diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt index e1076ed..39dc0e5 100644 --- a/libc/src/__support/math/CMakeLists.txt +++ b/libc/src/__support/math/CMakeLists.txt @@ -347,6 +347,117 @@ add_header_library( ) add_header_library( + cbrtf + HDRS + cbrtf.h + DEPENDS + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.multiply_add + libc.src.__support.macros.optimization +) + +add_header_library( + cos + HDRS + cos.h + DEPENDS + libc.hdr.errno_macros + libc.src.errno.errno + libc.src.__support.FPUtil.double_double + libc.src.__support.FPUtil.dyadic_float + libc.src.__support.FPUtil.except_value_utils + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.math.range_reduction_double + libc.src.__support.math.sincos_eval + libc.src.__support.macros.optimization +) + +add_header_library( + cosf + HDRS + cosf.h + DEPENDS + .sincosf_utils + libc.src.errno.errno + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.except_value_utils + libc.src.__support.FPUtil.fma + libc.src.__support.FPUtil.polyeval + libc.src.__support.macros.optimization +) + +add_header_library( + cosf16 + HDRS + cosf16.h + DEPENDS + .sincosf16_utils + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.__support.FPUtil.cast + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.except_value_utils + libc.src.__support.FPUtil.multiply_add + libc.src.__support.macros.optimization + libc.src.__support.macros.properties.types +) + +add_header_library( + coshf + HDRS + coshf.h + DEPENDS + .sinhfcoshf_utils + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.multiply_add + libc.src.__support.FPUtil.rounding_mode + libc.src.__support.macros.optimization +) + +add_header_library( + coshf16 + HDRS + coshf16.h + DEPENDS + .expxf16_utils + libc.src.__support.FPUtil.except_value_utils + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.rounding_mode + libc.src.__support.macros.optimization +) + +add_header_library( + cospif + HDRS + cospif.h + DEPENDS + .sincosf_utils + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.multiply_add + libc.src.__support.macros.optimization +) + +add_header_library( + cospif16 + HDRS + cospif16.h + DEPENDS + .sincosf16_utils + libc.src.__support.FPUtil.cast + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.multiply_add + libc.src.__support.macros.optimization +) + +add_header_library( erff HDRS erff.h @@ -417,6 +528,21 @@ add_header_library( ) add_header_library( + expxf16_utils + HDRS + expxf16_utils.h + DEPENDS + libc.hdr.stdint_proxy + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.cast + libc.src.__support.FPUtil.multiply_add + libc.src.__support.FPUtil.nearest_integer + libc.src.__support.macros.attributes + libc.src.__support.math.expf16_utils + libc.src.__support.math.exp10_float16_constants +) + +add_header_library( frexpf128 HDRS frexpf128.h @@ -602,3 +728,75 @@ add_header_library( libc.src.__support.macros.optimization libc.src.__support.macros.properties.cpu_features ) + +add_header_library( + range_reduction_double + HDRS + range_reduction_double_common.h + range_reduction_double_fma.h + range_reduction_double_nofma.h + DEPENDS + libc.src.__support.FPUtil.double_double + libc.src.__support.FPUtil.dyadic_float + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.fma + libc.src.__support.FPUtil.multiply_add + libc.src.__support.FPUtil.nearest_integer + libc.src.__support.common + libc.src.__support.integer_literals +) + +add_header_library( + range_reduction + HDRS + range_reduction.h + range_reduction_fma.h + DEPENDS + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.fma + libc.src.__support.FPUtil.multiply_add + libc.src.__support.FPUtil.nearest_integer + libc.src.__support.common +) + +add_header_library( + sincos_eval + HDRS + sincos_eval.h + DEPENDS + libc.src.__support.FPUtil.double_double + libc.src.__support.FPUtil.dyadic_float + libc.src.__support.FPUtil.multiply_add + libc.src.__support.FPUtil.polyeval + libc.src.__support.integer_literals +) + +add_header_library( + sincosf_utils + HDRS + sincosf_utils.h + DEPENDS + .range_reduction + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.polyeval + libc.src.__support.common +) + +add_header_library( + sincosf16_utils + HDRS + sincosf16_utils.h + DEPENDS + libc.src.__support.FPUtil.polyeval + libc.src.__support.FPUtil.nearest_integer + libc.src.__support.common +) + +add_header_library( + sinhfcoshf_utils + HDRS + sinhfcoshf_utils.h + DEPENDS + .exp10f_utils + libc.src.__support.FPUtil.multiply_add +) diff --git a/libc/src/__support/math/cbrtf.h b/libc/src/__support/math/cbrtf.h new file mode 100644 index 0000000..f82892b --- /dev/null +++ b/libc/src/__support/math/cbrtf.h @@ -0,0 +1,161 @@ +//===-- Implementation header for cbrtf -------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LIBC_SRC___SUPPORT_MATH_CBRTF_H +#define LIBC_SRC___SUPPORT_MATH_CBRTF_H + +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/macros/config.h" +#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY + +namespace LIBC_NAMESPACE_DECL { + +namespace math { + +LIBC_INLINE static constexpr float cbrtf(float x) { + // Look up table for 2^(i/3) for i = 0, 1, 2. + constexpr double CBRT2[3] = {1.0, 0x1.428a2f98d728bp0, 0x1.965fea53d6e3dp0}; + + // Degree-7 polynomials approximation of ((1 + x)^(1/3) - 1)/x for 0 <= x <= 1 + // generated by Sollya with: + // > for i from 0 to 15 do { + // P = fpminimax(((1 + x)^(1/3) - 1)/x, 6, [|D...|], [i/16, (i + 1)/16]); + // print("{", coeff(P, 0), ",", coeff(P, 1), ",", coeff(P, 2), ",", + // coeff(P, 3), ",", coeff(P, 4), ",", coeff(P, 5), ",", + // coeff(P, 6), "},"); + // }; + // Then (1 + x)^(1/3) ~ 1 + x * P(x). + constexpr double COEFFS[16][7] = { + {0x1.55555555554ebp-2, -0x1.c71c71c678c0cp-4, 0x1.f9add2776de81p-5, + -0x1.511e10aa964a7p-5, 0x1.ee44165937fa2p-6, -0x1.7c5c9e059345dp-6, + 0x1.047f75e0aff14p-6}, + {0x1.5555554d1149ap-2, -0x1.c71c676fcb5bp-4, 0x1.f9ab127dc57ebp-5, + -0x1.50ea8fd1d4c15p-5, 0x1.e9d68f28ced43p-6, -0x1.60e0e1e661311p-6, + 0x1.716eca1d6e3bcp-7}, + {0x1.5555546377d45p-2, -0x1.c71bc1c6d49d2p-4, 0x1.f9924cc0ed24dp-5, + -0x1.4fea3beb53b3bp-5, 0x1.de028a9a07b1bp-6, -0x1.3b090d2233524p-6, + 0x1.0aeca34893785p-7}, + {0x1.55554dce9f649p-2, -0x1.c7188b34b98f8p-4, 0x1.f93e1af34af49p-5, + -0x1.4d9a06be75c63p-5, 0x1.cb943f4f68992p-6, -0x1.139a685a5e3c4p-6, + 0x1.88410674c6a5dp-8}, + {0x1.5555347d211c3p-2, -0x1.c70f2a4b1a5fap-4, 0x1.f88420e8602c3p-5, + -0x1.49becfa4ed3ep-5, 0x1.b475cd9013162p-6, -0x1.dcfee1dd2f8efp-7, + 0x1.249bb51a1c498p-8}, + {0x1.5554f01b33dbap-2, -0x1.c6facb929dbf1p-4, 0x1.f73fb7861252ep-5, + -0x1.4459a4a0071fap-5, 0x1.9a8df2b504fc2p-6, -0x1.9a7ce3006d06ep-7, + 0x1.ba9230918fa2ep-9}, + {0x1.55545c695db5fp-2, -0x1.c6d6089f20275p-4, 0x1.f556e0ea80efp-5, + -0x1.3d91372d083f4p-5, 0x1.7f66cff331f4p-6, -0x1.606a562491737p-7, + 0x1.52e3e17c71069p-9}, + {0x1.55534a879232ap-2, -0x1.c69b836998b84p-4, 0x1.f2bb26dac0e4cp-5, + -0x1.359eed43716d7p-5, 0x1.64218cd824fbcp-6, -0x1.2e703e2e091e8p-7, + 0x1.0677d9af6aad4p-9}, + {0x1.5551836bb5494p-2, -0x1.c64658c15353bp-4, 0x1.ef68517451a6ep-5, + -0x1.2cc20a980dceep-5, 0x1.49843e0fad93ap-6, -0x1.03c59ccb68e54p-7, + 0x1.9ad325dc7adcbp-10}, + {0x1.554ecacb0d035p-2, -0x1.c5d2664026ffcp-4, 0x1.eb624796ba809p-5, + -0x1.233803d19a535p-5, 0x1.300decb1c3c28p-6, -0x1.befe18031ec3dp-8, + 0x1.449f5ee175c69p-10}, + {0x1.554ae1f5ae815p-2, -0x1.c53c6b14ff6b2p-4, 0x1.e6b2d5127bb5bp-5, + -0x1.19387336788a3p-5, 0x1.180955a6ab255p-6, -0x1.81696703ba369p-8, + 0x1.02cb36389bd79p-10}, + {0x1.55458a59f356ep-2, -0x1.c4820dd631ae9p-4, 0x1.e167af818bd15p-5, + -0x1.0ef35f6f72e52p-5, 0x1.019c33b65e4ebp-6, -0x1.4d25bdd52d3a5p-8, + 0x1.a008ae91f5936p-11}, + {0x1.553e878eafee1p-2, -0x1.c3a1d0b2a3db2p-4, 0x1.db90d8ed9f89bp-5, + -0x1.0490e20f1ae91p-5, 0x1.d9a5d1fc42fe3p-7, -0x1.20bf8227c2abfp-8, + 0x1.50f8174cdb6e9p-11}, + {0x1.5535a0dedf1b1p-2, -0x1.c29afb8bd01a1p-4, 0x1.d53f6371c1e27p-5, + -0x1.f463209b433e2p-6, 0x1.b35222a17e44p-7, -0x1.f5efbf505e133p-9, + 0x1.12e0e94e8586dp-11}, + {0x1.552aa25e57bfdp-2, -0x1.c16d811e4acadp-4, 0x1.ce8489b47aa51p-5, + -0x1.dfde7ff758ea8p-6, 0x1.901f43aac38c8p-7, -0x1.b581d07df5ad5p-9, + 0x1.c3726535f1fc6p-12}, + {0x1.551d5d9b204d3p-2, -0x1.c019e328f8db1p-4, 0x1.c7710f44fc3cep-5, + -0x1.cbbbe25ea8ba4p-6, 0x1.6fe270088623dp-7, -0x1.7e6fc79733761p-9, + 0x1.75077abf18d84p-12}, + }; + + using FloatBits = typename fputil::FPBits<float>; + using DoubleBits = typename fputil::FPBits<double>; + + FloatBits x_bits(x); + + uint32_t x_abs = x_bits.uintval() & 0x7fff'ffff; + uint32_t sign_bit = (x_bits.uintval() >> 31) << DoubleBits::EXP_LEN; + + if (LIBC_UNLIKELY(x == 0.0f || x_abs >= 0x7f80'0000)) { + // x is 0, Inf, or NaN. + // Make sure it works for FTZ/DAZ modes. + return x + x; + } + + double xd = static_cast<double>(x); + DoubleBits xd_bits(xd); + + // When using biased exponent of x in double precision, + // x_e = real_exponent_of_x + 1023 + // Then: + // x_e / 3 = real_exponent_of_x / 3 + 1023/3 + // = real_exponent_of_x / 3 + 341 + // So to make it the correct biased exponent of x^(1/3), we add + // 1023 - 341 = 682 + // to the quotient x_e / 3. + unsigned x_e = static_cast<unsigned>(xd_bits.get_biased_exponent()); + unsigned out_e = (x_e / 3 + 682) | sign_bit; + unsigned shift_e = x_e % 3; + + // Set x_m = 2^(x_e % 3) * (1.mantissa) + uint64_t x_m = xd_bits.get_mantissa(); + // Use the leading 4 bits for look up table + unsigned idx = static_cast<unsigned>(x_m >> (DoubleBits::FRACTION_LEN - 4)); + + x_m |= static_cast<uint64_t>(DoubleBits::EXP_BIAS) + << DoubleBits::FRACTION_LEN; + + double x_reduced = DoubleBits(x_m).get_val(); + double dx = x_reduced - 1.0; + + double dx_sq = dx * dx; + double c0 = fputil::multiply_add(dx, COEFFS[idx][0], 1.0); + double c1 = fputil::multiply_add(dx, COEFFS[idx][2], COEFFS[idx][1]); + double c2 = fputil::multiply_add(dx, COEFFS[idx][4], COEFFS[idx][3]); + double c3 = fputil::multiply_add(dx, COEFFS[idx][6], COEFFS[idx][5]); + + double dx_4 = dx_sq * dx_sq; + double p0 = fputil::multiply_add(dx_sq, c1, c0); + double p1 = fputil::multiply_add(dx_sq, c3, c2); + + double r = fputil::multiply_add(dx_4, p1, p0) * CBRT2[shift_e]; + + uint64_t r_m = DoubleBits(r).get_mantissa(); + // Check if the output is exact. To be exact, the smallest 1-bit of the + // output has to be at least 2^-7 or higher. So we check the lowest 44 bits + // to see if they are within 2^(-52 + 3) errors from all zeros, then the + // result cube root is exact. + if (LIBC_UNLIKELY(((r_m + 8) & 0xfffffffffff) <= 16)) { + if ((r_m & 0xfffffffffff) <= 8) + r_m &= 0xffff'ffff'ffff'ffe0; + else + r_m = (r_m & 0xffff'ffff'ffff'ffe0) + 0x20; + fputil::clear_except_if_required(FE_INEXACT); + } + // Adjust exponent and sign. + uint64_t r_bits = + r_m | (static_cast<uint64_t>(out_e) << DoubleBits::FRACTION_LEN); + + return static_cast<float>(DoubleBits(r_bits).get_val()); +} + +} // namespace math + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_SRC___SUPPORT_MATH_CBRTF_H diff --git a/libc/src/__support/math/cos.h b/libc/src/__support/math/cos.h new file mode 100644 index 0000000..0802f9e --- /dev/null +++ b/libc/src/__support/math/cos.h @@ -0,0 +1,173 @@ +//===-- Implementation header for cos ---------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LIBC_SRC___SUPPORT_MATH_COS_H +#define LIBC_SRC___SUPPORT_MATH_COS_H + +#include "range_reduction_double_common.h" +#include "sincos_eval.h" +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/double_double.h" +#include "src/__support/FPUtil/dyadic_float.h" +#include "src/__support/FPUtil/except_value_utils.h" +#include "src/__support/macros/config.h" +#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY +#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA + +#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE +#include "range_reduction_double_fma.h" +#else +#include "range_reduction_double_nofma.h" +#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE + +namespace LIBC_NAMESPACE_DECL { + +namespace math { + +LIBC_INLINE static constexpr double cos(double x) { + using namespace range_reduction_double_internal; + using DoubleDouble = fputil::DoubleDouble; + using FPBits = typename fputil::FPBits<double>; + FPBits xbits(x); + + uint16_t x_e = xbits.get_biased_exponent(); + + DoubleDouble y; + unsigned k = 0; + LargeRangeReduction range_reduction_large; + + // |x| < 2^16. + if (LIBC_LIKELY(x_e < FPBits::EXP_BIAS + FAST_PASS_EXPONENT)) { + // |x| < 2^-7 + if (LIBC_UNLIKELY(x_e < FPBits::EXP_BIAS - 7)) { + // |x| < 2^-27 + if (LIBC_UNLIKELY(x_e < FPBits::EXP_BIAS - 27)) { + // Signed zeros. + if (LIBC_UNLIKELY(x == 0.0)) + return 1.0; + + // For |x| < 2^-27, |cos(x) - 1| < |x|^2/2 < 2^-54 = ulp(1 - 2^-53)/2. + return fputil::round_result_slightly_down(1.0); + } + // No range reduction needed. + k = 0; + y.lo = 0.0; + y.hi = x; + } else { + // Small range reduction. + k = range_reduction_small(x, y); + } + } else { + // Inf or NaN + if (LIBC_UNLIKELY(x_e > 2 * FPBits::EXP_BIAS)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + // cos(+-Inf) = NaN + if (xbits.get_mantissa() == 0) { + fputil::set_errno_if_required(EDOM); + fputil::raise_except_if_required(FE_INVALID); + } + return x + FPBits::quiet_nan().get_val(); + } + + // Large range reduction. + k = range_reduction_large.fast(x, y); + } + + DoubleDouble sin_y, cos_y; + + [[maybe_unused]] double err = + math::sincos_eval_internal::sincos_eval(y, sin_y, cos_y); + + // Look up sin(k * pi/128) and cos(k * pi/128) +#ifdef LIBC_MATH_HAS_SMALL_TABLES + // Memory saving versions. Use 65-entry table. + auto get_idx_dd = [](unsigned kk) -> DoubleDouble { + unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63); + DoubleDouble ans = SIN_K_PI_OVER_128[idx]; + if (kk & 128) { + ans.hi = -ans.hi; + ans.lo = -ans.lo; + } + return ans; + }; + DoubleDouble msin_k = get_idx_dd(k + 128); + DoubleDouble cos_k = get_idx_dd(k + 64); +#else + // Fast look up version, but needs 256-entry table. + // -sin(k * pi/128) = sin((k + 128) * pi/128) + // cos(k * pi/128) = sin(k * pi/128 + pi/2) = sin((k + 64) * pi/128). + DoubleDouble msin_k = SIN_K_PI_OVER_128[(k + 128) & 255]; + DoubleDouble cos_k = SIN_K_PI_OVER_128[(k + 64) & 255]; +#endif // LIBC_MATH_HAS_SMALL_TABLES + + // After range reduction, k = round(x * 128 / pi) and y = x - k * (pi / 128). + // So k is an integer and -pi / 256 <= y <= pi / 256. + // Then cos(x) = cos((k * pi/128 + y) + // = cos(y) * cos(k*pi/128) - sin(y) * sin(k*pi/128) + DoubleDouble cos_k_cos_y = fputil::quick_mult(cos_y, cos_k); + DoubleDouble msin_k_sin_y = fputil::quick_mult(sin_y, msin_k); + + DoubleDouble rr = fputil::exact_add<false>(cos_k_cos_y.hi, msin_k_sin_y.hi); + rr.lo += msin_k_sin_y.lo + cos_k_cos_y.lo; + +#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS + return rr.hi + rr.lo; +#else + using Float128 = typename fputil::DyadicFloat<128>; + double rlp = rr.lo + err; + double rlm = rr.lo - err; + + double r_upper = rr.hi + rlp; // (rr.lo + ERR); + double r_lower = rr.hi + rlm; // (rr.lo - ERR); + + // Ziv's rounding test. + if (LIBC_LIKELY(r_upper == r_lower)) + return r_upper; + + Float128 u_f128, sin_u, cos_u; + if (LIBC_LIKELY(x_e < FPBits::EXP_BIAS + FAST_PASS_EXPONENT)) + u_f128 = range_reduction_small_f128(x); + else + u_f128 = range_reduction_large.accurate(); + + math::sincos_eval_internal::sincos_eval(u_f128, sin_u, cos_u); + + auto get_sin_k = [](unsigned kk) -> Float128 { + unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63); + Float128 ans = SIN_K_PI_OVER_128_F128[idx]; + if (kk & 128) + ans.sign = Sign::NEG; + return ans; + }; + + // -sin(k * pi/128) = sin((k + 128) * pi/128) + // cos(k * pi/128) = sin(k * pi/128 + pi/2) = sin((k + 64) * pi/128). + Float128 msin_k_f128 = get_sin_k(k + 128); + Float128 cos_k_f128 = get_sin_k(k + 64); + + // cos(x) = cos((k * pi/128 + u) + // = cos(u) * cos(k*pi/128) - sin(u) * sin(k*pi/128) + Float128 r = fputil::quick_add(fputil::quick_mul(cos_k_f128, cos_u), + fputil::quick_mul(msin_k_f128, sin_u)); + + // TODO: Add assertion if Ziv's accuracy tests fail in debug mode. + // https://github.com/llvm/llvm-project/issues/96452. + + return static_cast<double>(r); +#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS +} + +} // namespace math + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_SRC___SUPPORT_MATH_COS_H diff --git a/libc/src/__support/math/cosf.h b/libc/src/__support/math/cosf.h new file mode 100644 index 0000000..074be0b --- /dev/null +++ b/libc/src/__support/math/cosf.h @@ -0,0 +1,152 @@ +//===-- Implementation header for cosf --------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LIBC_SRC___SUPPORT_MATH_COSF_H +#define LIBC_SRC___SUPPORT_MATH_COSF_H + +#include "sincosf_utils.h" +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/except_value_utils.h" +#include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/macros/config.h" +#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY +#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA + +namespace LIBC_NAMESPACE_DECL { + +namespace math { + +LIBC_INLINE static constexpr float cosf(float x) { + +#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS + // Exceptional cases for cosf. + constexpr size_t N_EXCEPTS = 6; + + constexpr fputil::ExceptValues<float, N_EXCEPTS> COSF_EXCEPTS{{ + // (inputs, RZ output, RU offset, RD offset, RN offset) + // x = 0x1.64a032p43, cos(x) = 0x1.9d4ba4p-1 (RZ) + {0x55325019, 0x3f4ea5d2, 1, 0, 0}, + // x = 0x1.4555p51, cos(x) = 0x1.115d7cp-1 (RZ) + {0x5922aa80, 0x3f08aebe, 1, 0, 1}, + // x = 0x1.48a858p54, cos(x) = 0x1.f48148p-2 (RZ) + {0x5aa4542c, 0x3efa40a4, 1, 0, 0}, + // x = 0x1.3170fp63, cos(x) = 0x1.fe2976p-1 (RZ) + {0x5f18b878, 0x3f7f14bb, 1, 0, 0}, + // x = 0x1.2b9622p67, cos(x) = 0x1.f0285cp-1 (RZ) + {0x6115cb11, 0x3f78142e, 1, 0, 1}, + // x = 0x1.ddebdep120, cos(x) = 0x1.114438p-1 (RZ) + {0x7beef5ef, 0x3f08a21c, 1, 0, 0}, + }}; +#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS + + using FPBits = typename fputil::FPBits<float>; + + FPBits xbits(x); + xbits.set_sign(Sign::POS); + + uint32_t x_abs = xbits.uintval(); + double xd = static_cast<double>(xbits.get_val()); + + // Range reduction: + // For |x| > pi/16, we perform range reduction as follows: + // Find k and y such that: + // x = (k + y) * pi/32 + // k is an integer + // |y| < 0.5 + // For small range (|x| < 2^45 when FMA instructions are available, 2^22 + // otherwise), this is done by performing: + // k = round(x * 32/pi) + // y = x * 32/pi - k + // For large range, we will omit all the higher parts of 16/pi such that the + // least significant bits of their full products with x are larger than 63, + // since cos((k + y + 64*i) * pi/32) = cos(x + i * 2pi) = cos(x). + // + // When FMA instructions are not available, we store the digits of 32/pi in + // chunks of 28-bit precision. This will make sure that the products: + // x * THIRTYTWO_OVER_PI_28[i] are all exact. + // When FMA instructions are available, we simply store the digits of 32/pi in + // chunks of doubles (53-bit of precision). + // So when multiplying by the largest values of single precision, the + // resulting output should be correct up to 2^(-208 + 128) ~ 2^-80. By the + // worst-case analysis of range reduction, |y| >= 2^-38, so this should give + // us more than 40 bits of accuracy. For the worst-case estimation of range + // reduction, see for instances: + // Elementary Functions by J-M. Muller, Chapter 11, + // Handbook of Floating-Point Arithmetic by J-M. Muller et. al., + // Chapter 10.2. + // + // Once k and y are computed, we then deduce the answer by the cosine of sum + // formula: + // cos(x) = cos((k + y)*pi/32) + // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32) + // The values of sin(k*pi/32) and cos(k*pi/32) for k = 0..63 are precomputed + // and stored using a vector of 32 doubles. Sin(y*pi/32) and cos(y*pi/32) are + // computed using degree-7 and degree-6 minimax polynomials generated by + // Sollya respectively. + + // |x| < 0x1.0p-12f + if (LIBC_UNLIKELY(x_abs < 0x3980'0000U)) { + // When |x| < 2^-12, the relative error of the approximation cos(x) ~ 1 + // is: + // |cos(x) - 1| < |x^2 / 2| = 2^-25 < epsilon(1)/2. + // So the correctly rounded values of cos(x) are: + // = 1 - eps(x) if rounding mode = FE_TOWARDZERO or FE_DOWWARD, + // = 1 otherwise. + // To simplify the rounding decision and make it more efficient and to + // prevent compiler to perform constant folding, we use + // fma(x, -2^-25, 1) instead. + // Note: to use the formula 1 - 2^-25*x to decide the correct rounding, we + // do need fma(x, -2^-25, 1) to prevent underflow caused by -2^-25*x when + // |x| < 2^-125. For targets without FMA instructions, we simply use + // double for intermediate results as it is more efficient than using an + // emulated version of FMA. +#if defined(LIBC_TARGET_CPU_HAS_FMA_FLOAT) + return fputil::multiply_add(xbits.get_val(), -0x1.0p-25f, 1.0f); +#else + return static_cast<float>(fputil::multiply_add(xd, -0x1.0p-25, 1.0)); +#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT + } + +#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS + if (auto r = COSF_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value())) + return r.value(); +#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS + + // x is inf or nan. + if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + + if (x_abs == 0x7f80'0000U) { + fputil::set_errno_if_required(EDOM); + fputil::raise_except_if_required(FE_INVALID); + } + return x + FPBits::quiet_nan().get_val(); + } + + // Combine the results with the sine of sum formula: + // cos(x) = cos((k + y)*pi/32) + // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32) + // = cosm1_y * cos_k + sin_y * sin_k + // = (cosm1_y * cos_k + cos_k) + sin_y * sin_k + double sin_k = 0, cos_k = 0, sin_y = 0, cosm1_y = 0; + + sincosf_eval(xd, x_abs, sin_k, cos_k, sin_y, cosm1_y); + + return static_cast<float>(fputil::multiply_add( + sin_y, -sin_k, fputil::multiply_add(cosm1_y, cos_k, cos_k))); +} + +} // namespace math + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_SRC___SUPPORT_MATH_COSF_H diff --git a/libc/src/__support/math/cosf16.h b/libc/src/__support/math/cosf16.h new file mode 100644 index 0000000..50c9a8f --- /dev/null +++ b/libc/src/__support/math/cosf16.h @@ -0,0 +1,106 @@ +//===-- Implementation header for cosf16 ------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_COSF16_H +#define LLVM_LIBC_SRC___SUPPORT_MATH_COSF16_H + +#include "include/llvm-libc-macros/float16-macros.h" + +#ifdef LIBC_TYPES_HAS_FLOAT16 + +#include "sincosf16_utils.h" +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/cast.h" +#include "src/__support/FPUtil/except_value_utils.h" +#include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/macros/optimization.h" + +namespace LIBC_NAMESPACE_DECL { + +namespace math { + +LIBC_INLINE static constexpr float16 cosf16(float16 x) { +#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS + constexpr size_t N_EXCEPTS = 4; + + constexpr fputil::ExceptValues<float16, N_EXCEPTS> COSF16_EXCEPTS{{ + // (input, RZ output, RU offset, RD offset, RN offset) + {0x2b7c, 0x3bfc, 1, 0, 1}, + {0x4ac1, 0x38b5, 1, 0, 0}, + {0x5c49, 0xb8c6, 0, 1, 0}, + {0x7acc, 0xa474, 0, 1, 0}, + }}; +#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS + + using namespace sincosf16_internal; + using FPBits = fputil::FPBits<float16>; + FPBits xbits(x); + + uint16_t x_u = xbits.uintval(); + uint16_t x_abs = x_u & 0x7fff; + float xf = x; + + // Range reduction: + // For |x| > pi/32, we perform range reduction as follows: + // Find k and y such that: + // x = (k + y) * pi/32 + // k is an integer, |y| < 0.5 + // + // This is done by performing: + // k = round(x * 32/pi) + // y = x * 32/pi - k + // + // Once k and y are computed, we then deduce the answer by the cosine of sum + // formula: + // cos(x) = cos((k + y) * pi/32) + // = cos(k * pi/32) * cos(y * pi/32) - + // sin(k * pi/32) * sin(y * pi/32) + +#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS + // Handle exceptional values + if (auto r = COSF16_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value())) + return r.value(); +#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS + + // cos(+/-0) = 1 + if (LIBC_UNLIKELY(x_abs == 0U)) + return fputil::cast<float16>(1.0f); + + // cos(+/-inf) = NaN, and cos(NaN) = NaN + if (xbits.is_inf_or_nan()) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + + if (xbits.is_inf()) { + fputil::set_errno_if_required(EDOM); + fputil::raise_except_if_required(FE_INVALID); + } + + return x + FPBits::quiet_nan().get_val(); + } + + float sin_k = 0.0f, cos_k = 0.0f, sin_y = 0.0f, cosm1_y = 0.0f; + sincosf16_eval(xf, sin_k, cos_k, sin_y, cosm1_y); + // Since, cosm1_y = cos_y - 1, therefore: + // cos(x) = cos_k * cos_y - sin_k * sin_y + // = cos_k * (cos_y - 1 + 1) - sin_k * sin_y + // = cos_k * cosm1_y - sin_k * sin_y + cos_k + return fputil::cast<float16>(fputil::multiply_add( + cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k))); +} + +} // namespace math + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_TYPES_HAS_FLOAT16 + +#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSF16_H diff --git a/libc/src/__support/math/coshf.h b/libc/src/__support/math/coshf.h new file mode 100644 index 0000000..0f233b8 --- /dev/null +++ b/libc/src/__support/math/coshf.h @@ -0,0 +1,65 @@ +//===-- Implementation header for coshf -------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_COSHF_H +#define LLVM_LIBC_SRC___SUPPORT_MATH_COSHF_H + +#include "sinhfcoshf_utils.h" +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/rounding_mode.h" +#include "src/__support/macros/config.h" +#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY + +namespace LIBC_NAMESPACE_DECL { + +namespace math { + +LIBC_INLINE static constexpr float coshf(float x) { + using namespace sinhfcoshf_internal; + using FPBits = typename fputil::FPBits<float>; + + FPBits xbits(x); + xbits.set_sign(Sign::POS); + x = xbits.get_val(); + + uint32_t x_u = xbits.uintval(); + + // When |x| >= 90, or x is inf or nan + if (LIBC_UNLIKELY(x_u >= 0x42b4'0000U || x_u <= 0x3280'0000U)) { + // |x| <= 2^-26 + if (x_u <= 0x3280'0000U) { + return 1.0f + x; + } + + if (xbits.is_inf_or_nan()) + return x + FPBits::inf().get_val(); + + int rounding = fputil::quick_get_round(); + if (LIBC_UNLIKELY(rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)) + return FPBits::max_normal().get_val(); + + fputil::set_errno_if_required(ERANGE); + fputil::raise_except_if_required(FE_OVERFLOW); + + return x + FPBits::inf().get_val(); + } + + // TODO: We should be able to reduce the latency and reciprocal throughput + // further by using a low degree (maybe 3-7 ?) minimax polynomial for small + // but not too small inputs, such as |x| < 2^-2, or |x| < 2^-3. + + // cosh(x) = (e^x + e^(-x)) / 2. + return static_cast<float>(exp_pm_eval</*is_sinh*/ false>(x)); +} + +} // namespace math + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSHF_H diff --git a/libc/src/__support/math/coshf16.h b/libc/src/__support/math/coshf16.h new file mode 100644 index 0000000..4c96a78 --- /dev/null +++ b/libc/src/__support/math/coshf16.h @@ -0,0 +1,124 @@ +//===-- Implementation header for coshf16 -----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_COSHF16_H +#define LLVM_LIBC_SRC___SUPPORT_MATH_COSHF16_H + +#include "include/llvm-libc-macros/float16-macros.h" + +#ifdef LIBC_TYPES_HAS_FLOAT16 + +#include "expxf16_utils.h" +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/except_value_utils.h" +#include "src/__support/FPUtil/rounding_mode.h" +#include "src/__support/macros/config.h" +#include "src/__support/macros/optimization.h" + +namespace LIBC_NAMESPACE_DECL { + +namespace math { + +LIBC_INLINE static constexpr float16 coshf16(float16 x) { + +#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS + constexpr fputil::ExceptValues<float16, 9> COSHF16_EXCEPTS_POS = {{ + // x = 0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ) + {0x29a8U, 0x3c00U, 1U, 0U, 1U}, + // x = 0x1.8c4p+0, coshf16(x) = 0x1.3a8p+1 (RZ) + {0x3e31U, 0x40eaU, 1U, 0U, 0U}, + // x = 0x1.994p+0, coshf16(x) = 0x1.498p+1 (RZ) + {0x3e65U, 0x4126U, 1U, 0U, 0U}, + // x = 0x1.b6p+0, coshf16(x) = 0x1.6d8p+1 (RZ) + {0x3ed8U, 0x41b6U, 1U, 0U, 1U}, + // x = 0x1.aap+1, coshf16(x) = 0x1.be8p+3 (RZ) + {0x42a8U, 0x4afaU, 1U, 0U, 1U}, + // x = 0x1.cc4p+1, coshf16(x) = 0x1.23cp+4 (RZ) + {0x4331U, 0x4c8fU, 1U, 0U, 0U}, + // x = 0x1.288p+2, coshf16(x) = 0x1.9b4p+5 (RZ) + {0x44a2U, 0x526dU, 1U, 0U, 0U}, + // x = 0x1.958p+2, coshf16(x) = 0x1.1a4p+8 (RZ) + {0x4656U, 0x5c69U, 1U, 0U, 0U}, + // x = 0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ) + {0x497cU, 0x7715U, 1U, 0U, 1U}, + }}; + + constexpr fputil::ExceptValues<float16, 6> COSHF16_EXCEPTS_NEG = {{ + // x = -0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ) + {0xa9a8U, 0x3c00U, 1U, 0U, 1U}, + // x = -0x1.b6p+0, coshf16(x) = 0x1.6d8p+1 (RZ) + {0xbed8U, 0x41b6U, 1U, 0U, 1U}, + // x = -0x1.288p+2, coshf16(x) = 0x1.9b4p+5 (RZ) + {0xc4a2U, 0x526dU, 1U, 0U, 0U}, + // x = -0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ) + {0xc97cU, 0x7715U, 1U, 0U, 1U}, + // x = -0x1.8c4p+0, coshf16(x) = 0x1.3a8p+1 (RZ) + {0xbe31U, 0x40eaU, 1U, 0U, 0U}, + // x = -0x1.994p+0, coshf16(x) = 0x1.498p+1 (RZ) + {0xbe65U, 0x4126U, 1U, 0U, 0U}, + }}; +#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS + + using namespace expxf16_internal; + using FPBits = fputil::FPBits<float16>; + FPBits x_bits(x); + + uint16_t x_u = x_bits.uintval(); + uint16_t x_abs = x_u & 0x7fffU; + + // When |x| >= acosh(2^16), or x is NaN. + if (LIBC_UNLIKELY(x_abs >= 0x49e5U)) { + // cosh(NaN) = NaN + if (x_bits.is_nan()) { + if (x_bits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + + return x; + } + + // When |x| >= acosh(2^16). + if (x_abs >= 0x49e5U) { + // cosh(+/-inf) = +inf + if (x_bits.is_inf()) + return FPBits::inf().get_val(); + + switch (fputil::quick_get_round()) { + case FE_TONEAREST: + case FE_UPWARD: + fputil::set_errno_if_required(ERANGE); + fputil::raise_except_if_required(FE_OVERFLOW | FE_INEXACT); + return FPBits::inf().get_val(); + default: + return FPBits::max_normal().get_val(); + } + } + } + +#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS + if (x_bits.is_pos()) { + if (auto r = COSHF16_EXCEPTS_POS.lookup(x_u); LIBC_UNLIKELY(r.has_value())) + return r.value(); + } else { + if (auto r = COSHF16_EXCEPTS_NEG.lookup(x_u); LIBC_UNLIKELY(r.has_value())) + return r.value(); + } +#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS + + return eval_sinh_or_cosh</*IsSinh=*/false>(x); +} + +} // namespace math + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_TYPES_HAS_FLOAT16 + +#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSHF16_H diff --git a/libc/src/__support/math/cospif.h b/libc/src/__support/math/cospif.h new file mode 100644 index 0000000..e921090 --- /dev/null +++ b/libc/src/__support/math/cospif.h @@ -0,0 +1,109 @@ +//===-- Implementation header for cospif ------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_COSPIF_H +#define LLVM_LIBC_SRC___SUPPORT_MATH_COSPIF_H + +#include "sincosf_utils.h" +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" +#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY +#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA + +namespace LIBC_NAMESPACE_DECL { + +namespace math { + +LIBC_INLINE static constexpr float cospif(float x) { + using FPBits = typename fputil::FPBits<float>; + + FPBits xbits(x); + xbits.set_sign(Sign::POS); + + uint32_t x_abs = xbits.uintval(); + double xd = static_cast<double>(xbits.get_val()); + + // Range reduction: + // For |x| > 1/32, we perform range reduction as follows: + // Find k and y such that: + // x = (k + y) * 1/32 + // k is an integer + // |y| < 0.5 + // + // This is done by performing: + // k = round(x * 32) + // y = x * 32 - k + // + // Once k and y are computed, we then deduce the answer by the cosine of sum + // formula: + // cospi(x) = cos((k + y)*pi/32) + // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32) + // The values of sin(k*pi/32) and cos(k*pi/32) for k = 0..63 are precomputed + // and stored using a vector of 32 doubles. Sin(y*pi/32) and cos(y*pi/32) are + // computed using degree-7 and degree-6 minimax polynomials generated by + // Sollya respectively. + + // The exhautive test passes for smaller values + if (LIBC_UNLIKELY(x_abs < 0x38A2'F984U)) { + +#if defined(LIBC_TARGET_CPU_HAS_FMA_FLOAT) + return fputil::multiply_add(xbits.get_val(), -0x1.0p-25f, 1.0f); +#else + return static_cast<float>(fputil::multiply_add(xd, -0x1.0p-25, 1.0)); +#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT + } + + // Numbers greater or equal to 2^23 are always integers or NaN + if (LIBC_UNLIKELY(x_abs >= 0x4B00'0000)) { + + if (LIBC_UNLIKELY(x_abs < 0x4B80'0000)) { + return (x_abs & 0x1) ? -1.0f : 1.0f; + } + + // x is inf or nan. + if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + + if (x_abs == 0x7f80'0000U) { + fputil::set_errno_if_required(EDOM); + fputil::raise_except_if_required(FE_INVALID); + } + return x + FPBits::quiet_nan().get_val(); + } + + return 1.0f; + } + + // Combine the results with the sine of sum formula: + // cos(pi * x) = cos((k + y)*pi/32) + // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32) + // = (cosm1_y + 1) * cos_k - sin_y * sin_k + // = (cosm1_y * cos_k + cos_k) - sin_y * sin_k + double sin_k = 0, cos_k = 0, sin_y = 0, cosm1_y = 0; + + sincospif_eval(xd, sin_k, cos_k, sin_y, cosm1_y); + + if (LIBC_UNLIKELY(sin_y == 0 && cos_k == 0)) { + return 0.0f; + } + + return static_cast<float>(fputil::multiply_add( + sin_y, -sin_k, fputil::multiply_add(cosm1_y, cos_k, cos_k))); +} + +} // namespace math + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSHF_H diff --git a/libc/src/__support/math/cospif16.h b/libc/src/__support/math/cospif16.h new file mode 100644 index 0000000..d07236c --- /dev/null +++ b/libc/src/__support/math/cospif16.h @@ -0,0 +1,99 @@ +//===-- Implementation header for cospif16 ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_COSPIF16_H +#define LLVM_LIBC_SRC___SUPPORT_MATH_COSPIF16_H + +#include "include/llvm-libc-macros/float16-macros.h" + +#ifdef LIBC_TYPES_HAS_FLOAT16 + +#include "sincosf16_utils.h" +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/cast.h" +#include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/macros/optimization.h" + +namespace LIBC_NAMESPACE_DECL { + +namespace math { + +LIBC_INLINE static constexpr float16 cospif16(float16 x) { + + using namespace sincosf16_internal; + using FPBits = typename fputil::FPBits<float16>; + FPBits xbits(x); + + uint16_t x_u = xbits.uintval(); + uint16_t x_abs = x_u & 0x7fff; + float xf = x; + + // Range reduction: + // For |x| > 1/32, we perform range reduction as follows: + // Find k and y such that: + // x = (k + y) * 1/32 + // k is an integer + // |y| < 0.5 + // + // This is done by performing: + // k = round(x * 32) + // y = x * 32 - k + // + // Once k and y are computed, we then deduce the answer by the cosine of sum + // formula: + // cos(x * pi) = cos((k + y) * pi/32) + // = cos(k * pi/32) * cos(y * pi/32) + + // sin(y * pi/32) * sin(k * pi/32) + + // For signed zeros + if (LIBC_UNLIKELY(x_abs == 0U)) + return fputil::cast<float16>(1.0f); + + // Numbers greater or equal to 2^10 are integers, or infinity, or NaN + if (LIBC_UNLIKELY(x_abs >= 0x6400)) { + if (LIBC_UNLIKELY(x_abs <= 0x67FF)) + return fputil::cast<float16>((x_abs & 0x1) ? -1.0f : 1.0f); + + // Check for NaN or infintiy values + if (LIBC_UNLIKELY(x_abs >= 0x7c00)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + // If value is equal to infinity + if (x_abs == 0x7c00) { + fputil::set_errno_if_required(EDOM); + fputil::raise_except_if_required(FE_INVALID); + } + + return x + FPBits::quiet_nan().get_val(); + } + + return fputil::cast<float16>(1.0f); + } + + float sin_k = 0, cos_k = 0, sin_y = 0, cosm1_y = 0; + sincospif16_eval(xf, sin_k, cos_k, sin_y, cosm1_y); + + if (LIBC_UNLIKELY(sin_y == 0 && cos_k == 0)) + return fputil::cast<float16>(0.0f); + + // Since, cosm1_y = cos_y - 1, therefore: + // cos(x * pi) = cos_k(cosm1_y) + cos_k - sin_k * sin_y + return fputil::cast<float16>(fputil::multiply_add( + cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k))); +} + +} // namespace math + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_TYPES_HAS_FLOAT16 + +#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSHF16_H diff --git a/libc/src/math/generic/expxf16.h b/libc/src/__support/math/expxf16_utils.h index 562a427..5d3bd38 100644 --- a/libc/src/math/generic/expxf16.h +++ b/libc/src/__support/math/expxf16_utils.h @@ -21,7 +21,11 @@ namespace LIBC_NAMESPACE_DECL { -LIBC_INLINE ExpRangeReduction exp2_range_reduction(float16 x) { +namespace math { + +namespace expxf16_internal { + +LIBC_INLINE static ExpRangeReduction exp2_range_reduction(float16 x) { // For -25 < x < 16, to compute 2^x, we perform the following range reduction: // find hi, mid, lo, such that: // x = hi + mid + lo, in which @@ -117,7 +121,8 @@ static constexpr cpp::array<uint32_t, 32> EXP2_MID_5_BITS = { // The main point of these formulas is that the expensive part of calculating // the polynomials approximating lower parts of e^x and e^(-x) is shared and // only done once. -template <bool IsSinh> LIBC_INLINE float16 eval_sinh_or_cosh(float16 x) { +template <bool IsSinh> +LIBC_INLINE static constexpr float16 eval_sinh_or_cosh(float16 x) { float xf = x; float kf = fputil::nearest_integer(xf * (LOG2F_E * 0x1.0p+5f)); int x_hi_mid_p = static_cast<int>(kf); @@ -174,7 +179,7 @@ template <bool IsSinh> LIBC_INLINE float16 eval_sinh_or_cosh(float16 x) { // Generated by Sollya with the following commands: // > display = hexadecimal; // > for i from 0 to 31 do print(round(log(1 + i * 2^-5), SG, RN)); -constexpr cpp::array<float, 32> LOGF_F = { +static constexpr cpp::array<float, 32> LOGF_F = { 0x0p+0f, 0x1.f829bp-6f, 0x1.f0a30cp-5f, 0x1.6f0d28p-4f, 0x1.e27076p-4f, 0x1.29553p-3f, 0x1.5ff308p-3f, 0x1.9525aap-3f, 0x1.c8ff7cp-3f, 0x1.fb9186p-3f, 0x1.1675cap-2f, 0x1.2e8e2cp-2f, @@ -188,7 +193,7 @@ constexpr cpp::array<float, 32> LOGF_F = { // Generated by Sollya with the following commands: // > display = hexadecimal; // > for i from 0 to 31 do print(round(log2(1 + i * 2^-5), SG, RN)); -constexpr cpp::array<float, 32> LOG2F_F = { +static constexpr cpp::array<float, 32> LOG2F_F = { 0x0p+0f, 0x1.6bad38p-5f, 0x1.663f7p-4f, 0x1.08c588p-3f, 0x1.5c01a4p-3f, 0x1.acf5e2p-3f, 0x1.fbc16cp-3f, 0x1.24407ap-2f, 0x1.49a784p-2f, 0x1.6e221cp-2f, 0x1.91bba8p-2f, 0x1.b47ecp-2f, @@ -202,7 +207,7 @@ constexpr cpp::array<float, 32> LOG2F_F = { // Generated by Sollya with the following commands: // > display = hexadecimal; // > for i from 0 to 31 do print(round(log10(1 + i * 2^-5), SG, RN)); -constexpr cpp::array<float, 32> LOG10F_F = { +static constexpr cpp::array<float, 32> LOG10F_F = { 0x0p+0f, 0x1.b5e908p-7f, 0x1.af5f92p-6f, 0x1.3ed11ap-5f, 0x1.a30a9ep-5f, 0x1.02428cp-4f, 0x1.31b306p-4f, 0x1.5fe804p-4f, 0x1.8cf184p-4f, 0x1.b8de4ep-4f, 0x1.e3bc1ap-4f, 0x1.06cbd6p-3f, @@ -216,7 +221,7 @@ constexpr cpp::array<float, 32> LOG10F_F = { // Generated by Sollya with the following commands: // > display = hexadecimal; // > for i from 0 to 31 do print(round(1 / (1 + i * 2^-5), SG, RN)); -constexpr cpp::array<float, 32> ONE_OVER_F_F = { +static constexpr cpp::array<float, 32> ONE_OVER_F_F = { 0x1p+0f, 0x1.f07c2p-1f, 0x1.e1e1e2p-1f, 0x1.d41d42p-1f, 0x1.c71c72p-1f, 0x1.bacf92p-1f, 0x1.af286cp-1f, 0x1.a41a42p-1f, 0x1.99999ap-1f, 0x1.8f9c18p-1f, 0x1.861862p-1f, 0x1.7d05f4p-1f, @@ -227,6 +232,10 @@ constexpr cpp::array<float, 32> ONE_OVER_F_F = { 0x1.111112p-1f, 0x1.0c9714p-1f, 0x1.08421p-1f, 0x1.041042p-1f, }; +} // namespace expxf16_internal + +} // namespace math + } // namespace LIBC_NAMESPACE_DECL #endif // LLVM_LIBC_SRC_MATH_GENERIC_EXPXF16_H diff --git a/libc/src/math/generic/range_reduction.h b/libc/src/__support/math/range_reduction.h index 9ea446d..e3f25e4 100644 --- a/libc/src/math/generic/range_reduction.h +++ b/libc/src/__support/math/range_reduction.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_H -#define LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_H +#ifndef LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_H +#define LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_H #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/multiply_add.h" @@ -87,4 +87,4 @@ LIBC_INLINE int64_t large_range_reduction(double x, int x_exp, double &y) { } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_H +#endif // LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_H diff --git a/libc/src/math/generic/range_reduction_double_common.h b/libc/src/__support/math/range_reduction_double_common.h index a93ee25..a12c25d 100644 --- a/libc/src/math/generic/range_reduction_double_common.h +++ b/libc/src/__support/math/range_reduction_double_common.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_COMMON_H -#define LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_COMMON_H +#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_COMMON_H +#define LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_COMMON_H #include "src/__support/FPUtil/double_double.h" #include "src/__support/FPUtil/dyadic_float.h" @@ -20,6 +20,10 @@ namespace LIBC_NAMESPACE_DECL { +namespace math { + +namespace range_reduction_double_internal { + #ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE static constexpr unsigned SPLIT = fputil::DefaultSplit<double>::VALUE; #else @@ -40,7 +44,7 @@ using Float128 = LIBC_NAMESPACE::fputil::DyadicFloat<128>; // Error bound: // |(x - k * pi/128) - (u_hi + u_lo)| <= max(ulp(ulp(u_hi)), 2^-119) // <= 2^-111. -LIBC_INLINE unsigned range_reduction_small(double x, DoubleDouble &u) { +LIBC_INLINE static unsigned range_reduction_small(double x, DoubleDouble &u) { // Values of -pi/128 used for inputs with absolute value <= 2^16. // The first 3 parts are generated with (53 - 21 = 32)-bit precision, so that // the product k * MPI_OVER_128[i] is exact. @@ -267,13 +271,15 @@ struct LargeRangeReduction { } #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS + LIBC_INLINE LargeRangeReduction() = default; + private: // Index of x in the look-up table ONE_TWENTY_EIGHT_OVER_PI. - unsigned idx; + unsigned idx = 0; // x scaled down by 2^(-16 *(idx - 3))). - double x_reduced; + double x_reduced = 0; // Parts of (x * 128/pi) mod 1. - double y_hi, y_lo; + double y_hi = 0, y_lo = 0; DoubleDouble y_mid; }; @@ -369,6 +375,10 @@ static constexpr Float128 SIN_K_PI_OVER_128_F128[65] = { }; #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS +} // namespace range_reduction_double_internal + +} // namespace math + } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_COMMON_H +#endif // LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_COMMON_H diff --git a/libc/src/math/generic/range_reduction_double_fma.h b/libc/src/__support/math/range_reduction_double_fma.h index 160fb24..7fa3e40 100644 --- a/libc/src/math/generic/range_reduction_double_fma.h +++ b/libc/src/__support/math/range_reduction_double_fma.h @@ -6,20 +6,22 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_FMA_H -#define LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_FMA_H +#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_FMA_H +#define LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_FMA_H #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/double_double.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/FPUtil/nearest_integer.h" -#include "src/__support/common.h" #include "src/__support/macros/config.h" -#include "src/__support/macros/optimization.h" -#include "src/math/generic/range_reduction_double_common.h" +#include "src/__support/math/range_reduction_double_common.h" namespace LIBC_NAMESPACE_DECL { +namespace math { + +namespace range_reduction_double_internal { + using LIBC_NAMESPACE::fputil::DoubleDouble; LIBC_INLINE unsigned LargeRangeReduction::fast(double x, DoubleDouble &u) { @@ -341,6 +343,10 @@ LIBC_INLINE constexpr DoubleDouble SIN_K_PI_OVER_128[] = { #endif // !LIBC_MATH_HAS_SMALL_TABLES }; +} // namespace range_reduction_double_internal + +} // namespace math + } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_FMA_H +#endif // LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_FMA_H diff --git a/libc/src/math/generic/range_reduction_double_nofma.h b/libc/src/__support/math/range_reduction_double_nofma.h index 9d13d24..3990b9b 100644 --- a/libc/src/math/generic/range_reduction_double_nofma.h +++ b/libc/src/__support/math/range_reduction_double_nofma.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_NOFMA_H -#define LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_NOFMA_H +#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_NOFMA_H +#define LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_NOFMA_H #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/double_double.h" @@ -16,10 +16,14 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" -#include "src/math/generic/range_reduction_double_common.h" +#include "src/__support/math/range_reduction_double_common.h" namespace LIBC_NAMESPACE_DECL { +namespace math { + +namespace range_reduction_double_internal { + using fputil::DoubleDouble; LIBC_INLINE unsigned LargeRangeReduction::fast(double x, DoubleDouble &u) { @@ -342,6 +346,10 @@ LIBC_INLINE constexpr DoubleDouble SIN_K_PI_OVER_128[] = { #endif // !LIBC_MATH_HAS_SMALL_TABLES }; +} // namespace range_reduction_double_internal + +} // namespace math + } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_NOFMA_H +#endif // LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_NOFMA_H diff --git a/libc/src/math/generic/range_reduction_fma.h b/libc/src/__support/math/range_reduction_fma.h index 537d572..c06a1d8 100644 --- a/libc/src/math/generic/range_reduction_fma.h +++ b/libc/src/__support/math/range_reduction_fma.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_FMA_H -#define LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_FMA_H +#ifndef LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_FMA_H +#define LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_FMA_H #include "src/__support/FPUtil/FMA.h" #include "src/__support/FPUtil/FPBits.h" @@ -89,4 +89,4 @@ LIBC_INLINE int64_t large_range_reduction(double x, int x_exp, double &y) { } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_FMA_H +#endif // LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_FMA_H diff --git a/libc/src/math/generic/sincos_eval.h b/libc/src/__support/math/sincos_eval.h index 41a4c75..fc741af 100644 --- a/libc/src/math/generic/sincos_eval.h +++ b/libc/src/__support/math/sincos_eval.h @@ -18,7 +18,9 @@ namespace LIBC_NAMESPACE_DECL { -namespace generic { +namespace math { + +namespace sincos_eval_internal { using fputil::DoubleDouble; using Float128 = fputil::DyadicFloat<128>; @@ -131,7 +133,9 @@ LIBC_INLINE void sincos_eval(const Float128 &u, Float128 &sin_u, COS_COEFFS[6]); } -} // namespace generic +} // namespace sincos_eval_internal + +} // namespace math } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/sincosf16_utils.h b/libc/src/__support/math/sincosf16_utils.h index 05cab09d..74f21fd 100644 --- a/libc/src/math/generic/sincosf16_utils.h +++ b/libc/src/__support/math/sincosf16_utils.h @@ -16,6 +16,8 @@ namespace LIBC_NAMESPACE_DECL { +namespace sincosf16_internal { + // Lookup table for sin(k * pi / 32) with k = 0, ..., 63. // Table is generated with Sollya as follows: // > display = hexadecimmal; @@ -66,7 +68,7 @@ LIBC_INLINE int32_t range_reduction_sincosf16(float x, float &y) { return static_cast<int32_t>(kd); } -static LIBC_INLINE void sincosf16_poly_eval(int32_t k, float y, float &sin_k, +LIBC_INLINE static void sincosf16_poly_eval(int32_t k, float y, float &sin_k, float &cos_k, float &sin_y, float &cosm1_y) { @@ -107,6 +109,8 @@ LIBC_INLINE void sincospif16_eval(float xf, float &sin_k, float &cos_k, sincosf16_poly_eval(k, y, sin_k, cos_k, sin_y, cosm1_y); } +} // namespace sincosf16_internal + } // namespace LIBC_NAMESPACE_DECL #endif // LLVM_LIBC_SRC_MATH_GENERIC_SINCOSF16_UTILS_H diff --git a/libc/src/math/generic/sincosf_utils.h b/libc/src/__support/math/sincosf_utils.h index 6eaf820..ed9d9f6 100644 --- a/libc/src/math/generic/sincosf_utils.h +++ b/libc/src/__support/math/sincosf_utils.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_MATH_GENERIC_SINCOSF_UTILS_H -#define LLVM_LIBC_SRC_MATH_GENERIC_SINCOSF_UTILS_H +#ifndef LIBC_SRC___SUPPORT_MATH_SINCOSF_UTILS_H +#define LIBC_SRC___SUPPORT_MATH_SINCOSF_UTILS_H #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/PolyEval.h" @@ -122,4 +122,4 @@ LIBC_INLINE void sincospif_eval(double xd, double &sin_k, double &cos_k, } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_MATH_GENERIC_SINCOSF_UTILS_H +#endif // LIBC_SRC___SUPPORT_MATH_SINCOSF_UTILS_H diff --git a/libc/src/math/generic/explogxf.h b/libc/src/__support/math/sinhfcoshf_utils.h index 72f8da8..5f19b81 100644 --- a/libc/src/math/generic/explogxf.h +++ b/libc/src/__support/math/sinhfcoshf_utils.h @@ -1,4 +1,4 @@ -//===-- Single-precision general exp/log functions ------------------------===// +//===-- Single-precision general sinhf/coshf functions --------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,21 +6,17 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_MATH_GENERIC_EXPLOGXF_H -#define LLVM_LIBC_SRC_MATH_GENERIC_EXPLOGXF_H +#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_SINHFCOSHF_UTILS_H +#define LLVM_LIBC_SRC___SUPPORT_MATH_SINHFCOSHF_UTILS_H -#include "common_constants.h" - -#include "src/__support/common.h" -#include "src/__support/macros/properties/cpu_features.h" -#include "src/__support/math/acoshf_utils.h" -#include "src/__support/math/exp10f_utils.h" -#include "src/__support/math/exp_utils.h" +#include "exp10f_utils.h" +#include "src/__support/FPUtil/multiply_add.h" namespace LIBC_NAMESPACE_DECL { -constexpr int LOG_P1_BITS = 6; -constexpr int LOG_P1_SIZE = 1 << LOG_P1_BITS; +namespace math { + +namespace sinhfcoshf_internal { // The function correctly calculates sinh(x) and cosh(x) by calculating exp(x) // and exp(-x) simultaneously. @@ -121,6 +117,10 @@ template <bool is_sinh> LIBC_INLINE double exp_pm_eval(float x) { return r; } +} // namespace sinhfcoshf_internal + +} // namespace math + } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_MATH_GENERIC_EXPLOGXF_H +#endif // LLVM_LIBC_SRC___SUPPORT_MATH_SINHFCOSHF_UTILS_H diff --git a/libc/src/__support/math_extras.h b/libc/src/__support/math_extras.h index 47df2a4..954bcb1b 100644 --- a/libc/src/__support/math_extras.h +++ b/libc/src/__support/math_extras.h @@ -66,7 +66,7 @@ template <typename T> #define RETURN_IF(TYPE, BUILTIN) \ if constexpr (cpp::is_same_v<T, TYPE>) \ - return BUILTIN(a, b, carry_in, carry_out); + return BUILTIN(a, b, carry_in, &carry_out); // Returns the result of 'a + b' taking into account 'carry_in'. // The carry out is stored in 'carry_out' it not 'nullptr', dropped otherwise. @@ -74,7 +74,7 @@ template <typename T> template <typename T> [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T> add_with_carry(T a, T b, T carry_in, T &carry_out) { - if constexpr (!cpp::is_constant_evaluated()) { + if (!cpp::is_constant_evaluated()) { #if __has_builtin(__builtin_addcb) RETURN_IF(unsigned char, __builtin_addcb) #elif __has_builtin(__builtin_addcs) @@ -100,7 +100,7 @@ add_with_carry(T a, T b, T carry_in, T &carry_out) { template <typename T> [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T> sub_with_borrow(T a, T b, T carry_in, T &carry_out) { - if constexpr (!cpp::is_constant_evaluated()) { + if (!cpp::is_constant_evaluated()) { #if __has_builtin(__builtin_subcb) RETURN_IF(unsigned char, __builtin_subcb) #elif __has_builtin(__builtin_subcs) diff --git a/libc/src/__support/threads/linux/barrier.h b/libc/src/__support/threads/linux/barrier.h index f0655bf..a632aa4 100644 --- a/libc/src/__support/threads/linux/barrier.h +++ b/libc/src/__support/threads/linux/barrier.h @@ -36,14 +36,19 @@ public: int wait(); }; -static_assert( - sizeof(Barrier) == sizeof(pthread_barrier_t), - "The public pthread_barrier_t type cannot accommodate the internal " - "barrier type."); - -static_assert(alignof(Barrier) == alignof(pthread_barrier_t), - "The public pthread_barrier_t type has a different alignment " - "than the internal barrier type."); +static_assert(sizeof(Barrier) <= sizeof(pthread_barrier_t), + "The public pthread_barrier_t type cannot accommodate the " + "internal barrier type."); + +static_assert(alignof(Barrier) <= alignof(pthread_barrier_t), + "The public pthread_barrier_t type has insufficient alignment " + "for the internal barrier type."); + +static_assert(sizeof(CndVar) <= 24, + "CndVar size exceeds the size in __barrier_type.h"); + +static_assert(sizeof(Mutex) <= 24, + "Mutex size exceeds the size in __barrier_type.h"); } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/__support/threads/mutex.h b/libc/src/__support/threads/mutex.h index cbef0d0..f64f7e7 100644 --- a/libc/src/__support/threads/mutex.h +++ b/libc/src/__support/threads/mutex.h @@ -12,28 +12,6 @@ #include "src/__support/macros/attributes.h" #include "src/__support/macros/config.h" -// Uses the platform specific specialization -#define LIBC_THREAD_MODE_PLATFORM 0 - -// Mutex guards nothing, used in single-threaded implementations -#define LIBC_THREAD_MODE_SINGLE 1 - -// Vendor provides implementation -#define LIBC_THREAD_MODE_EXTERNAL 2 - -#if !defined(LIBC_THREAD_MODE) -#error LIBC_THREAD_MODE is undefined -#endif // LIBC_THREAD_MODE - -#if LIBC_THREAD_MODE != LIBC_THREAD_MODE_PLATFORM && \ - LIBC_THREAD_MODE != LIBC_THREAD_MODE_SINGLE && \ - LIBC_THREAD_MODE != LIBC_THREAD_MODE_EXTERNAL -#error LIBC_THREAD_MODE must be one of the following values: \ -LIBC_THREAD_MODE_PLATFORM, \ -LIBC_THREAD_MODE_SINGLE, \ -LIBC_THREAD_MODE_EXTERNAL. -#endif - #if LIBC_THREAD_MODE == LIBC_THREAD_MODE_PLATFORM // Platform independent code will include this header file which pulls diff --git a/libc/src/__support/threads/thread.cpp b/libc/src/__support/threads/thread.cpp index 6f6b75b..9618d78 100644 --- a/libc/src/__support/threads/thread.cpp +++ b/libc/src/__support/threads/thread.cpp @@ -163,6 +163,8 @@ void call_atexit_callbacks(ThreadAttributes *attrib) { } } +extern "C" void __cxa_thread_finalize() { call_atexit_callbacks(self.attrib); } + } // namespace internal cpp::optional<unsigned int> new_tss_key(TSSDtor *dtor) { diff --git a/libc/src/__support/threads/thread.h b/libc/src/__support/threads/thread.h index 114ab49..6806098 100644 --- a/libc/src/__support/threads/thread.h +++ b/libc/src/__support/threads/thread.h @@ -110,7 +110,7 @@ struct alignas(STACK_ALIGNMENT) ThreadAttributes { ThreadAtExitCallbackMgr *atexit_callback_mgr; void *platform_data; - constexpr ThreadAttributes() + LIBC_INLINE constexpr ThreadAttributes() : detach_state(uint32_t(DetachState::DETACHED)), stack(nullptr), stacksize(0), guardsize(0), tls(0), tls_size(0), owned_stack(false), tid(-1), style(ThreadStyle::POSIX), retval(), diff --git a/libc/src/__support/wchar/character_converter.cpp b/libc/src/__support/wchar/character_converter.cpp index 15d0f47..2667288 100644 --- a/libc/src/__support/wchar/character_converter.cpp +++ b/libc/src/__support/wchar/character_converter.cpp @@ -132,12 +132,6 @@ ErrorOr<char32_t> CharacterConverter::pop_utf32() { return utf32; } -size_t CharacterConverter::sizeAsUTF32() { - return 1; // a single utf-32 value can fit an entire character -} - -size_t CharacterConverter::sizeAsUTF8() { return state->total_bytes; } - ErrorOr<char8_t> CharacterConverter::pop_utf8() { if (isEmpty()) return Error(-1); @@ -170,5 +164,13 @@ ErrorOr<char8_t> CharacterConverter::pop_utf8() { return static_cast<char8_t>(output); } +template <> ErrorOr<char8_t> CharacterConverter::pop() { return pop_utf8(); } +template <> ErrorOr<char32_t> CharacterConverter::pop() { return pop_utf32(); } + +template <> size_t CharacterConverter::sizeAs<char8_t>() { + return state->total_bytes; +} +template <> size_t CharacterConverter::sizeAs<char32_t>() { return 1; } + } // namespace internal } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/__support/wchar/character_converter.h b/libc/src/__support/wchar/character_converter.h index b6d918f..2cc28ab 100644 --- a/libc/src/__support/wchar/character_converter.h +++ b/libc/src/__support/wchar/character_converter.h @@ -12,6 +12,7 @@ #include "hdr/types/char32_t.h" #include "hdr/types/char8_t.h" #include "hdr/types/size_t.h" +#include "src/__support/CPP/type_traits.h" #include "src/__support/common.h" #include "src/__support/error_or.h" #include "src/__support/wchar/mbstate.h" @@ -31,14 +32,14 @@ public: bool isEmpty(); bool isValidState(); - size_t sizeAsUTF32(); - size_t sizeAsUTF8(); + template <typename CharType> size_t sizeAs(); int push(char8_t utf8_byte); int push(char32_t utf32); ErrorOr<char8_t> pop_utf8(); ErrorOr<char32_t> pop_utf32(); + template <typename CharType> ErrorOr<CharType> pop(); }; } // namespace internal diff --git a/libc/src/__support/wchar/mbrtowc.cpp b/libc/src/__support/wchar/mbrtowc.cpp index 0f730d6..66cc68e 100644 --- a/libc/src/__support/wchar/mbrtowc.cpp +++ b/libc/src/__support/wchar/mbrtowc.cpp @@ -8,7 +8,6 @@ #include "src/__support/wchar/mbrtowc.h" #include "hdr/errno_macros.h" -#include "hdr/types/mbstate_t.h" #include "hdr/types/size_t.h" #include "hdr/types/wchar_t.h" #include "src/__support/common.h" diff --git a/libc/src/__support/wchar/mbsnrtowcs.h b/libc/src/__support/wchar/mbsnrtowcs.h index 54e3152..6abb836 100644 --- a/libc/src/__support/wchar/mbsnrtowcs.h +++ b/libc/src/__support/wchar/mbsnrtowcs.h @@ -36,7 +36,7 @@ LIBC_INLINE static ErrorOr<size_t> mbsnrtowcs(wchar_t *__restrict dst, StringConverter<char8_t> str_conv(reinterpret_cast<const char8_t *>(*src), ps, len, nmc); size_t dst_idx = 0; - ErrorOr<char32_t> converted = str_conv.popUTF32(); + ErrorOr<char32_t> converted = str_conv.pop<char32_t>(); while (converted.has_value()) { if (dst != nullptr) dst[dst_idx] = converted.value(); @@ -47,7 +47,7 @@ LIBC_INLINE static ErrorOr<size_t> mbsnrtowcs(wchar_t *__restrict dst, return dst_idx; } dst_idx++; - converted = str_conv.popUTF32(); + converted = str_conv.pop<char32_t>(); } if (converted.error() == -1) { // if we hit conversion limit diff --git a/libc/src/__support/wchar/string_converter.h b/libc/src/__support/wchar/string_converter.h index 869ebdf..ba628bd 100644 --- a/libc/src/__support/wchar/string_converter.h +++ b/libc/src/__support/wchar/string_converter.h @@ -12,6 +12,7 @@ #include "hdr/types/char32_t.h" #include "hdr/types/char8_t.h" #include "hdr/types/size_t.h" +#include "src/__support/CPP/type_traits.h" #include "src/__support/common.h" #include "src/__support/error_or.h" #include "src/__support/wchar/character_converter.h" @@ -53,9 +54,7 @@ public: size_t srclen = SIZE_MAX) : cr(ps), src(s), src_len(srclen), src_idx(0), num_to_write(dstlen) {} - // TODO: following functions are almost identical - // look into templating CharacterConverter pop functions - ErrorOr<char32_t> popUTF32() { + template <typename CharType> ErrorOr<CharType> pop() { if (num_to_write == 0) return Error(-1); @@ -64,7 +63,7 @@ public: if (!src_elements_read.has_value()) return Error(src_elements_read.error()); - if (cr.sizeAsUTF32() > num_to_write) { + if (cr.sizeAs<CharType>() > num_to_write) { cr.clear(); return Error(-1); } @@ -72,34 +71,9 @@ public: src_idx += src_elements_read.value(); } - auto out = cr.pop_utf32(); - if (out.has_value() && out.value() == L'\0') - src_len = src_idx; - - num_to_write--; - - return out; - } - - ErrorOr<char8_t> popUTF8() { - if (num_to_write == 0) - return Error(-1); - - if (cr.isEmpty() || src_idx == 0) { - auto src_elements_read = pushFullCharacter(); - if (!src_elements_read.has_value()) - return Error(src_elements_read.error()); - - if (cr.sizeAsUTF8() > num_to_write) { - cr.clear(); - return Error(-1); - } - - src_idx += src_elements_read.value(); - } - - auto out = cr.pop_utf8(); - if (out.has_value() && out.value() == '\0') + ErrorOr<CharType> out = cr.pop<CharType>(); + // if out isn't null terminator or an error + if (out.has_value() && out.value() == 0) src_len = src_idx; num_to_write--; diff --git a/libc/src/__support/wchar/wcsnrtombs.h b/libc/src/__support/wchar/wcsnrtombs.h index 433097c..f593a0e 100644 --- a/libc/src/__support/wchar/wcsnrtombs.h +++ b/libc/src/__support/wchar/wcsnrtombs.h @@ -39,7 +39,7 @@ wcsnrtombs(char *__restrict dest, const wchar_t **__restrict ptr_to_src, reinterpret_cast<const char32_t *>(*ptr_to_src), ps, dest_len, num_src_widechars); size_t dst_idx = 0; - ErrorOr<char8_t> converted = str_conv.popUTF8(); + ErrorOr<char8_t> converted = str_conv.pop<char8_t>(); while (converted.has_value()) { if (dest != nullptr) dest[dst_idx] = converted.value(); @@ -51,7 +51,7 @@ wcsnrtombs(char *__restrict dest, const wchar_t **__restrict ptr_to_src, } dst_idx++; - converted = str_conv.popUTF8(); + converted = str_conv.pop<char8_t>(); } if (dest != nullptr) diff --git a/libc/src/dlfcn/CMakeLists.txt b/libc/src/dlfcn/CMakeLists.txt index e3a51ba..876d915 100644 --- a/libc/src/dlfcn/CMakeLists.txt +++ b/libc/src/dlfcn/CMakeLists.txt @@ -14,7 +14,6 @@ add_entrypoint_object( dlerror.h DEPENDS libc.include.dlfcn - libc.src.errno.errno ) add_entrypoint_object( @@ -25,7 +24,6 @@ add_entrypoint_object( dlopen.h DEPENDS libc.include.dlfcn - libc.src.errno.errno ) add_entrypoint_object( @@ -36,5 +34,25 @@ add_entrypoint_object( dlsym.h DEPENDS libc.include.dlfcn - libc.src.errno.errno +) + +add_entrypoint_object( + dlinfo + SRCS + dlinfo.cpp + HDRS + dlinfo.h + DEPENDS + libc.include.dlfcn +) + +add_entrypoint_object( + dladdr + SRCS + dladdr.cpp + HDRS + dladdr.h + DEPENDS + libc.include.dlfcn + libc.hdr.types.dl_info ) diff --git a/libc/src/dlfcn/dladdr.cpp b/libc/src/dlfcn/dladdr.cpp new file mode 100644 index 0000000..7e2a154 --- /dev/null +++ b/libc/src/dlfcn/dladdr.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of dladdr ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "dladdr.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +// TODO: https:// github.com/llvm/llvm-project/issues/97929 +LLVM_LIBC_FUNCTION(int, dladdr, + ([[maybe_unused]] const void *__restrict addr, + [[maybe_unused]] Dl_info *__restrict info)) { + return -1; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/dlfcn/dladdr.h b/libc/src/dlfcn/dladdr.h new file mode 100644 index 0000000..1fabe81 --- /dev/null +++ b/libc/src/dlfcn/dladdr.h @@ -0,0 +1,22 @@ +//===-- Implementation header of dladdr -------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_DLFCN_DLADDR_H +#define LLVM_LIBC_SRC_DLFCN_DLADDR_H + +#include "src/__support/macros/config.h" + +#include "hdr/types/dl_info.h" + +namespace LIBC_NAMESPACE_DECL { + +int dladdr(const void *__restrict, Dl_info *__restrict); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_DLFCN_DLADDR_H diff --git a/libc/src/dlfcn/dlinfo.cpp b/libc/src/dlfcn/dlinfo.cpp new file mode 100644 index 0000000..e1938d1 --- /dev/null +++ b/libc/src/dlfcn/dlinfo.cpp @@ -0,0 +1,24 @@ + +//===-- Implementation of dlinfo ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "dlinfo.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +// TODO: https://github.com/llvm/llvm-project/issues/149911 +LLVM_LIBC_FUNCTION(int, dlinfo, + (void *__restrict handle, int request, + void *__restrict info)) { + return -1; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/dlfcn/dlinfo.h b/libc/src/dlfcn/dlinfo.h new file mode 100644 index 0000000..bc13152 --- /dev/null +++ b/libc/src/dlfcn/dlinfo.h @@ -0,0 +1,20 @@ +//===-- Implementation header of dlinfo -------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_DLFCN_DLINFO_H +#define LLVM_LIBC_SRC_DLFCN_DLINFO_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int dlinfo(void *__restrict, int, void *__restrict); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_DLFCN_DLINFO_H diff --git a/libc/src/dlfcn/dlsym.cpp b/libc/src/dlfcn/dlsym.cpp index c075c20..dc0da7d 100644 --- a/libc/src/dlfcn/dlsym.cpp +++ b/libc/src/dlfcn/dlsym.cpp @@ -14,6 +14,8 @@ namespace LIBC_NAMESPACE_DECL { // TODO(@izaakschroeder): https://github.com/llvm/llvm-project/issues/97920 -LLVM_LIBC_FUNCTION(void *, dlsym, (void *, const char *)) { return nullptr; } +LLVM_LIBC_FUNCTION(void *, dlsym, (void *__restrict, const char *__restrict)) { + return nullptr; +} } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/dlfcn/dlsym.h b/libc/src/dlfcn/dlsym.h index 70c6ab3..f879792 100644 --- a/libc/src/dlfcn/dlsym.h +++ b/libc/src/dlfcn/dlsym.h @@ -13,7 +13,7 @@ namespace LIBC_NAMESPACE_DECL { -void *dlsym(void *, const char *); +void *dlsym(void *__restrict, const char *__restrict); } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/errno/libc_errno.cpp b/libc/src/errno/libc_errno.cpp index 8ff1eec..e8960fc 100644 --- a/libc/src/errno/libc_errno.cpp +++ b/libc/src/errno/libc_errno.cpp @@ -46,11 +46,6 @@ Errno::operator int() { return shared_errno; } void Errno::operator=(int a) { *__llvm_libc_errno() = a; } Errno::operator int() { return *__llvm_libc_errno(); } -#elif LIBC_ERRNO_MODE == LIBC_ERRNO_MODE_SYSTEM - -void Errno::operator=(int a) { errno = a; } -Errno::operator int() { return errno; } - #endif // Define the global `libc_errno` instance. diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt index 0522e0e..3e7d9ec 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -58,6 +58,8 @@ add_math_entrypoint_object(asinh) add_math_entrypoint_object(asinhf) add_math_entrypoint_object(asinhf16) +add_math_entrypoint_object(asinpif16) + add_math_entrypoint_object(atan) add_math_entrypoint_object(atanf) add_math_entrypoint_object(atanf16) @@ -71,17 +73,21 @@ add_math_entrypoint_object(atanh) add_math_entrypoint_object(atanhf) add_math_entrypoint_object(atanhf16) +add_math_entrypoint_object(atanpif16) + add_math_entrypoint_object(canonicalize) add_math_entrypoint_object(canonicalizef) add_math_entrypoint_object(canonicalizel) add_math_entrypoint_object(canonicalizef16) add_math_entrypoint_object(canonicalizef128) +add_math_entrypoint_object(canonicalizebf16) add_math_entrypoint_object(iscanonical) add_math_entrypoint_object(iscanonicalf) add_math_entrypoint_object(iscanonicall) add_math_entrypoint_object(iscanonicalf16) add_math_entrypoint_object(iscanonicalf128) +add_math_entrypoint_object(iscanonicalbf16) add_math_entrypoint_object(cbrt) add_math_entrypoint_object(cbrtf) @@ -91,12 +97,14 @@ add_math_entrypoint_object(ceilf) add_math_entrypoint_object(ceill) add_math_entrypoint_object(ceilf16) add_math_entrypoint_object(ceilf128) +add_math_entrypoint_object(ceilbf16) add_math_entrypoint_object(copysign) add_math_entrypoint_object(copysignf) add_math_entrypoint_object(copysignl) add_math_entrypoint_object(copysignf16) add_math_entrypoint_object(copysignf128) +add_math_entrypoint_object(copysignbf16) add_math_entrypoint_object(cos) add_math_entrypoint_object(cosf) @@ -200,6 +208,7 @@ add_math_entrypoint_object(fdimf) add_math_entrypoint_object(fdiml) add_math_entrypoint_object(fdimf16) add_math_entrypoint_object(fdimf128) +add_math_entrypoint_object(fdimbf16) add_math_entrypoint_object(fdiv) add_math_entrypoint_object(fdivl) @@ -214,6 +223,7 @@ add_math_entrypoint_object(floorf) add_math_entrypoint_object(floorl) add_math_entrypoint_object(floorf16) add_math_entrypoint_object(floorf128) +add_math_entrypoint_object(floorbf16) add_math_entrypoint_object(fma) add_math_entrypoint_object(fmaf) @@ -224,60 +234,70 @@ add_math_entrypoint_object(fmaxf) add_math_entrypoint_object(fmaxl) add_math_entrypoint_object(fmaxf128) add_math_entrypoint_object(fmaxf16) +add_math_entrypoint_object(fmaxbf16) add_math_entrypoint_object(fmin) add_math_entrypoint_object(fminf) add_math_entrypoint_object(fminl) add_math_entrypoint_object(fminf128) add_math_entrypoint_object(fminf16) +add_math_entrypoint_object(fminbf16) add_math_entrypoint_object(fmaximum) add_math_entrypoint_object(fmaximumf) add_math_entrypoint_object(fmaximuml) add_math_entrypoint_object(fmaximumf16) add_math_entrypoint_object(fmaximumf128) +add_math_entrypoint_object(fmaximumbf16) add_math_entrypoint_object(fmaximum_num) add_math_entrypoint_object(fmaximum_numf) add_math_entrypoint_object(fmaximum_numl) add_math_entrypoint_object(fmaximum_numf16) add_math_entrypoint_object(fmaximum_numf128) +add_math_entrypoint_object(fmaximum_numbf16) add_math_entrypoint_object(fmaximum_mag) add_math_entrypoint_object(fmaximum_magf) add_math_entrypoint_object(fmaximum_magl) add_math_entrypoint_object(fmaximum_magf16) add_math_entrypoint_object(fmaximum_magf128) +add_math_entrypoint_object(fmaximum_magbf16) add_math_entrypoint_object(fmaximum_mag_num) add_math_entrypoint_object(fmaximum_mag_numf) add_math_entrypoint_object(fmaximum_mag_numl) add_math_entrypoint_object(fmaximum_mag_numf16) add_math_entrypoint_object(fmaximum_mag_numf128) +add_math_entrypoint_object(fmaximum_mag_numbf16) add_math_entrypoint_object(fminimum) add_math_entrypoint_object(fminimumf) add_math_entrypoint_object(fminimuml) add_math_entrypoint_object(fminimumf16) add_math_entrypoint_object(fminimumf128) +add_math_entrypoint_object(fminimumbf16) add_math_entrypoint_object(fminimum_num) add_math_entrypoint_object(fminimum_numf) add_math_entrypoint_object(fminimum_numl) add_math_entrypoint_object(fminimum_numf16) add_math_entrypoint_object(fminimum_numf128) +add_math_entrypoint_object(fminimum_numbf16) add_math_entrypoint_object(fminimum_mag) add_math_entrypoint_object(fminimum_magf) add_math_entrypoint_object(fminimum_magl) add_math_entrypoint_object(fminimum_magf16) add_math_entrypoint_object(fminimum_magf128) +add_math_entrypoint_object(fminimum_magbf16) add_math_entrypoint_object(fminimum_mag_num) add_math_entrypoint_object(fminimum_mag_numf) add_math_entrypoint_object(fminimum_mag_numl) add_math_entrypoint_object(fminimum_mag_numf16) add_math_entrypoint_object(fminimum_mag_numf128) +add_math_entrypoint_object(fminimum_mag_numbf16) add_math_entrypoint_object(fmul) add_math_entrypoint_object(fmull) @@ -288,24 +308,28 @@ add_math_entrypoint_object(fmodf) add_math_entrypoint_object(fmodl) add_math_entrypoint_object(fmodf16) add_math_entrypoint_object(fmodf128) +add_math_entrypoint_object(fmodbf16) add_math_entrypoint_object(frexp) add_math_entrypoint_object(frexpf) add_math_entrypoint_object(frexpl) add_math_entrypoint_object(frexpf16) add_math_entrypoint_object(frexpf128) +add_math_entrypoint_object(frexpbf16) add_math_entrypoint_object(fromfp) add_math_entrypoint_object(fromfpf) add_math_entrypoint_object(fromfpl) add_math_entrypoint_object(fromfpf16) add_math_entrypoint_object(fromfpf128) +add_math_entrypoint_object(fromfpbf16) add_math_entrypoint_object(fromfpx) add_math_entrypoint_object(fromfpxf) add_math_entrypoint_object(fromfpxl) add_math_entrypoint_object(fromfpxf16) add_math_entrypoint_object(fromfpxf128) +add_math_entrypoint_object(fromfpxbf16) add_math_entrypoint_object(fsub) add_math_entrypoint_object(fsubl) @@ -316,6 +340,7 @@ add_math_entrypoint_object(getpayloadf) add_math_entrypoint_object(getpayloadl) add_math_entrypoint_object(getpayloadf16) add_math_entrypoint_object(getpayloadf128) +add_math_entrypoint_object(getpayloadbf16) add_math_entrypoint_object(hypot) add_math_entrypoint_object(hypotf) @@ -326,6 +351,7 @@ add_math_entrypoint_object(ilogbf) add_math_entrypoint_object(ilogbl) add_math_entrypoint_object(ilogbf16) add_math_entrypoint_object(ilogbf128) +add_math_entrypoint_object(ilogbbf16) add_math_entrypoint_object(isnan) add_math_entrypoint_object(isnanf) @@ -336,18 +362,21 @@ add_math_entrypoint_object(issignalingf) add_math_entrypoint_object(issignalingl) add_math_entrypoint_object(issignalingf16) add_math_entrypoint_object(issignalingf128) +add_math_entrypoint_object(issignalingbf16) add_math_entrypoint_object(llogb) add_math_entrypoint_object(llogbf) add_math_entrypoint_object(llogbl) add_math_entrypoint_object(llogbf16) add_math_entrypoint_object(llogbf128) +add_math_entrypoint_object(llogbbf16) add_math_entrypoint_object(ldexp) add_math_entrypoint_object(ldexpf) add_math_entrypoint_object(ldexpl) add_math_entrypoint_object(ldexpf16) add_math_entrypoint_object(ldexpf128) +add_math_entrypoint_object(ldexpbf16) add_math_entrypoint_object(log10) add_math_entrypoint_object(log10f) @@ -369,71 +398,83 @@ add_math_entrypoint_object(logbf) add_math_entrypoint_object(logbl) add_math_entrypoint_object(logbf16) add_math_entrypoint_object(logbf128) +add_math_entrypoint_object(logbbf16) add_math_entrypoint_object(llrint) add_math_entrypoint_object(llrintf) add_math_entrypoint_object(llrintl) add_math_entrypoint_object(llrintf16) add_math_entrypoint_object(llrintf128) +add_math_entrypoint_object(llrintbf16) add_math_entrypoint_object(llround) add_math_entrypoint_object(llroundf) add_math_entrypoint_object(llroundl) add_math_entrypoint_object(llroundf16) add_math_entrypoint_object(llroundf128) +add_math_entrypoint_object(llroundbf16) add_math_entrypoint_object(lrint) add_math_entrypoint_object(lrintf) add_math_entrypoint_object(lrintl) add_math_entrypoint_object(lrintf16) add_math_entrypoint_object(lrintf128) +add_math_entrypoint_object(lrintbf16) add_math_entrypoint_object(lround) add_math_entrypoint_object(lroundf) add_math_entrypoint_object(lroundl) add_math_entrypoint_object(lroundf16) add_math_entrypoint_object(lroundf128) +add_math_entrypoint_object(lroundbf16) add_math_entrypoint_object(modf) add_math_entrypoint_object(modff) add_math_entrypoint_object(modfl) add_math_entrypoint_object(modff16) add_math_entrypoint_object(modff128) +add_math_entrypoint_object(modfbf16) add_math_entrypoint_object(nan) add_math_entrypoint_object(nanf) add_math_entrypoint_object(nanl) add_math_entrypoint_object(nanf16) add_math_entrypoint_object(nanf128) +add_math_entrypoint_object(nanbf16) add_math_entrypoint_object(nearbyint) add_math_entrypoint_object(nearbyintf) add_math_entrypoint_object(nearbyintl) add_math_entrypoint_object(nearbyintf16) add_math_entrypoint_object(nearbyintf128) +add_math_entrypoint_object(nearbyintbf16) add_math_entrypoint_object(nextafter) add_math_entrypoint_object(nextafterf) add_math_entrypoint_object(nextafterl) add_math_entrypoint_object(nextafterf16) add_math_entrypoint_object(nextafterf128) +add_math_entrypoint_object(nextafterbf16) add_math_entrypoint_object(nexttoward) add_math_entrypoint_object(nexttowardf) add_math_entrypoint_object(nexttowardl) add_math_entrypoint_object(nexttowardf16) +add_math_entrypoint_object(nexttowardbf16) add_math_entrypoint_object(nextdown) add_math_entrypoint_object(nextdownf) add_math_entrypoint_object(nextdownl) add_math_entrypoint_object(nextdownf16) add_math_entrypoint_object(nextdownf128) +add_math_entrypoint_object(nextdownbf16) add_math_entrypoint_object(nextup) add_math_entrypoint_object(nextupf) add_math_entrypoint_object(nextupl) add_math_entrypoint_object(nextupf16) add_math_entrypoint_object(nextupf128) +add_math_entrypoint_object(nextupbf16) add_math_entrypoint_object(pow) add_math_entrypoint_object(powf) @@ -445,54 +486,63 @@ add_math_entrypoint_object(remainderf) add_math_entrypoint_object(remainderl) add_math_entrypoint_object(remainderf16) add_math_entrypoint_object(remainderf128) +add_math_entrypoint_object(remainderbf16) add_math_entrypoint_object(remquo) add_math_entrypoint_object(remquof) -add_math_entrypoint_object(remquof128) add_math_entrypoint_object(remquol) add_math_entrypoint_object(remquof16) +add_math_entrypoint_object(remquof128) +add_math_entrypoint_object(remquobf16) add_math_entrypoint_object(rint) add_math_entrypoint_object(rintf) add_math_entrypoint_object(rintl) add_math_entrypoint_object(rintf16) add_math_entrypoint_object(rintf128) +add_math_entrypoint_object(rintbf16) add_math_entrypoint_object(round) add_math_entrypoint_object(roundf) add_math_entrypoint_object(roundl) add_math_entrypoint_object(roundf16) add_math_entrypoint_object(roundf128) +add_math_entrypoint_object(roundbf16) add_math_entrypoint_object(roundeven) add_math_entrypoint_object(roundevenf) add_math_entrypoint_object(roundevenl) add_math_entrypoint_object(roundevenf16) add_math_entrypoint_object(roundevenf128) +add_math_entrypoint_object(roundevenbf16) add_math_entrypoint_object(scalbln) add_math_entrypoint_object(scalblnf) add_math_entrypoint_object(scalblnl) add_math_entrypoint_object(scalblnf16) add_math_entrypoint_object(scalblnf128) +add_math_entrypoint_object(scalblnbf16) add_math_entrypoint_object(scalbn) add_math_entrypoint_object(scalbnf) add_math_entrypoint_object(scalbnl) add_math_entrypoint_object(scalbnf16) add_math_entrypoint_object(scalbnf128) +add_math_entrypoint_object(scalbnbf16) add_math_entrypoint_object(setpayload) add_math_entrypoint_object(setpayloadf) add_math_entrypoint_object(setpayloadl) add_math_entrypoint_object(setpayloadf16) add_math_entrypoint_object(setpayloadf128) +add_math_entrypoint_object(setpayloadbf16) add_math_entrypoint_object(setpayloadsig) add_math_entrypoint_object(setpayloadsigf) add_math_entrypoint_object(setpayloadsigl) add_math_entrypoint_object(setpayloadsigf16) add_math_entrypoint_object(setpayloadsigf128) +add_math_entrypoint_object(setpayloadsigbf16) add_math_entrypoint_object(sincos) add_math_entrypoint_object(sincosf) @@ -534,27 +584,57 @@ add_math_entrypoint_object(totalorderf) add_math_entrypoint_object(totalorderl) add_math_entrypoint_object(totalorderf16) add_math_entrypoint_object(totalorderf128) +add_math_entrypoint_object(totalorderbf16) add_math_entrypoint_object(totalordermag) add_math_entrypoint_object(totalordermagf) add_math_entrypoint_object(totalordermagl) add_math_entrypoint_object(totalordermagf16) add_math_entrypoint_object(totalordermagf128) +add_math_entrypoint_object(totalordermagbf16) add_math_entrypoint_object(trunc) add_math_entrypoint_object(truncf) add_math_entrypoint_object(truncl) add_math_entrypoint_object(truncf16) add_math_entrypoint_object(truncf128) +add_math_entrypoint_object(truncbf16) add_math_entrypoint_object(ufromfp) add_math_entrypoint_object(ufromfpf) add_math_entrypoint_object(ufromfpl) add_math_entrypoint_object(ufromfpf16) add_math_entrypoint_object(ufromfpf128) +add_math_entrypoint_object(ufromfpbf16) add_math_entrypoint_object(ufromfpx) add_math_entrypoint_object(ufromfpxf) add_math_entrypoint_object(ufromfpxl) add_math_entrypoint_object(ufromfpxf16) add_math_entrypoint_object(ufromfpxf128) +add_math_entrypoint_object(ufromfpxbf16) + +add_math_entrypoint_object(bf16add) +add_math_entrypoint_object(bf16addf) +add_math_entrypoint_object(bf16addl) +add_math_entrypoint_object(bf16addf128) + +add_math_entrypoint_object(bf16div) +add_math_entrypoint_object(bf16divf) +add_math_entrypoint_object(bf16divl) +add_math_entrypoint_object(bf16divf128) + +add_math_entrypoint_object(bf16fma) +add_math_entrypoint_object(bf16fmaf) +add_math_entrypoint_object(bf16fmal) +add_math_entrypoint_object(bf16fmaf128) + +add_math_entrypoint_object(bf16mul) +add_math_entrypoint_object(bf16mulf) +add_math_entrypoint_object(bf16mull) +add_math_entrypoint_object(bf16mulf128) + +add_math_entrypoint_object(bf16sub) +add_math_entrypoint_object(bf16subf) +add_math_entrypoint_object(bf16subl) +add_math_entrypoint_object(bf16subf128) diff --git a/libc/src/math/asinpif16.h b/libc/src/math/asinpif16.h new file mode 100644 index 0000000..b97166a --- /dev/null +++ b/libc/src/math/asinpif16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for asinpif16 ---------------------*- C++ -*-===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_ASINPIF16_H +#define LLVM_LIBC_SRC_MATH_ASINPIF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +float16 asinpif16(float16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_ASINPIF16_H diff --git a/libc/src/math/atanpif16.h b/libc/src/math/atanpif16.h new file mode 100644 index 0000000..8f2391a --- /dev/null +++ b/libc/src/math/atanpif16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for atanpif16 ---------------------*- C++ -*-===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_ATANPIF16_H +#define LLVM_LIBC_SRC_MATH_ATANPIF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +float16 atanpif16(float16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_ASINF16_H diff --git a/libc/src/math/bf16add.h b/libc/src/math/bf16add.h new file mode 100644 index 0000000..a29970e --- /dev/null +++ b/libc/src/math/bf16add.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16add -----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16ADD_H +#define LLVM_LIBC_SRC_MATH_BF16ADD_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16add(double x, double y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16ADD_H diff --git a/libc/src/math/bf16addf.h b/libc/src/math/bf16addf.h new file mode 100644 index 0000000..80a5e2a --- /dev/null +++ b/libc/src/math/bf16addf.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16addf ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16ADDF_H +#define LLVM_LIBC_SRC_MATH_BF16ADDF_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16addf(float x, float y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16ADDF_H diff --git a/libc/src/math/bf16addf128.h b/libc/src/math/bf16addf128.h new file mode 100644 index 0000000..3c2f3a1 --- /dev/null +++ b/libc/src/math/bf16addf128.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16addf128 -------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16ADDF128_H +#define LLVM_LIBC_SRC_MATH_BF16ADDF128_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16addf128(float128 x, float128 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16ADDF128_H diff --git a/libc/src/math/bf16addl.h b/libc/src/math/bf16addl.h new file mode 100644 index 0000000..a9e7d68 --- /dev/null +++ b/libc/src/math/bf16addl.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16addl ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16ADDL_H +#define LLVM_LIBC_SRC_MATH_BF16ADDL_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16addl(long double x, long double y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16ADDL_H diff --git a/libc/src/math/bf16div.h b/libc/src/math/bf16div.h new file mode 100644 index 0000000..ade9c06 --- /dev/null +++ b/libc/src/math/bf16div.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16div -----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16DIV_H +#define LLVM_LIBC_SRC_MATH_BF16DIV_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16div(double x, double y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16DIV_H diff --git a/libc/src/math/bf16divf.h b/libc/src/math/bf16divf.h new file mode 100644 index 0000000..481b176 --- /dev/null +++ b/libc/src/math/bf16divf.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16divf ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16DIVF_H +#define LLVM_LIBC_SRC_MATH_BF16DIVF_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16divf(float x, float y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16DIVF_H diff --git a/libc/src/math/bf16divf128.h b/libc/src/math/bf16divf128.h new file mode 100644 index 0000000..d990066 --- /dev/null +++ b/libc/src/math/bf16divf128.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16divf128 -------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16DIVF128_H +#define LLVM_LIBC_SRC_MATH_BF16DIVF128_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16divf128(float128 x, float128 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16DIVF128_H diff --git a/libc/src/math/bf16divl.h b/libc/src/math/bf16divl.h new file mode 100644 index 0000000..b19ac873 --- /dev/null +++ b/libc/src/math/bf16divl.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16divl ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16DIVL_H +#define LLVM_LIBC_SRC_MATH_BF16DIVL_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16divl(long double x, long double y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16DIVL_H diff --git a/libc/src/math/bf16fma.h b/libc/src/math/bf16fma.h new file mode 100644 index 0000000..aa54956 --- /dev/null +++ b/libc/src/math/bf16fma.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16fma -----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16FMA_H +#define LLVM_LIBC_SRC_MATH_BF16FMA_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16fma(double x, double y, double z); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16FMA_H diff --git a/libc/src/math/bf16fmaf.h b/libc/src/math/bf16fmaf.h new file mode 100644 index 0000000..e8582bd --- /dev/null +++ b/libc/src/math/bf16fmaf.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16fmaf ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16FMAF_H +#define LLVM_LIBC_SRC_MATH_BF16FMAF_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16fmaf(float x, float y, float z); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16FMAF_H diff --git a/libc/src/math/bf16fmaf128.h b/libc/src/math/bf16fmaf128.h new file mode 100644 index 0000000..4215e54 --- /dev/null +++ b/libc/src/math/bf16fmaf128.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16fmaf128 -------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16FMAF128_H +#define LLVM_LIBC_SRC_MATH_BF16FMAF128_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16fmaf128(float128 x, float128 y, float128 z); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16FMAF128_H diff --git a/libc/src/math/bf16fmal.h b/libc/src/math/bf16fmal.h new file mode 100644 index 0000000..b92f17b --- /dev/null +++ b/libc/src/math/bf16fmal.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16fmal ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16FMAL_H +#define LLVM_LIBC_SRC_MATH_BF16FMAL_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16fmal(long double x, long double y, long double z); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16FMAL_H diff --git a/libc/src/math/bf16mul.h b/libc/src/math/bf16mul.h new file mode 100644 index 0000000..14e8a30 --- /dev/null +++ b/libc/src/math/bf16mul.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16mul -----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16MUL_H +#define LLVM_LIBC_SRC_MATH_BF16MUL_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16mul(double x, double y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16MUL_H diff --git a/libc/src/math/bf16mulf.h b/libc/src/math/bf16mulf.h new file mode 100644 index 0000000..1d02c8e --- /dev/null +++ b/libc/src/math/bf16mulf.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16mulf ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16MULF_H +#define LLVM_LIBC_SRC_MATH_BF16MULF_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16mulf(float x, float y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16MULF_H diff --git a/libc/src/math/bf16mulf128.h b/libc/src/math/bf16mulf128.h new file mode 100644 index 0000000..6ba7cef --- /dev/null +++ b/libc/src/math/bf16mulf128.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16mulf128 -------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16MULF128_H +#define LLVM_LIBC_SRC_MATH_BF16MULF128_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16mulf128(float128 x, float128 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16MULF128_H diff --git a/libc/src/math/bf16mull.h b/libc/src/math/bf16mull.h new file mode 100644 index 0000000..dad6523 --- /dev/null +++ b/libc/src/math/bf16mull.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16mull ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16MULL_H +#define LLVM_LIBC_SRC_MATH_BF16MULL_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16mull(long double x, long double y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16MULL_H diff --git a/libc/src/math/bf16sub.h b/libc/src/math/bf16sub.h new file mode 100644 index 0000000..8108e914 --- /dev/null +++ b/libc/src/math/bf16sub.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16sub -----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16SUB_H +#define LLVM_LIBC_SRC_MATH_BF16SUB_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16sub(double x, double y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16SUB_H diff --git a/libc/src/math/bf16subf.h b/libc/src/math/bf16subf.h new file mode 100644 index 0000000..1bd79bf --- /dev/null +++ b/libc/src/math/bf16subf.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16subf ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16SUBF_H +#define LLVM_LIBC_SRC_MATH_BF16SUBF_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16subf(float x, float y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16SUBF_H diff --git a/libc/src/math/bf16subf128.h b/libc/src/math/bf16subf128.h new file mode 100644 index 0000000..19590e8 --- /dev/null +++ b/libc/src/math/bf16subf128.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16subf128 -------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16SUBF128_H +#define LLVM_LIBC_SRC_MATH_BF16SUBF128_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16subf128(float128 x, float128 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16SUBF128_H diff --git a/libc/src/math/bf16subl.h b/libc/src/math/bf16subl.h new file mode 100644 index 0000000..13b2093 --- /dev/null +++ b/libc/src/math/bf16subl.h @@ -0,0 +1,21 @@ +//===-- Implementation header for bf16subl ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_BF16SUBL_H +#define LLVM_LIBC_SRC_MATH_BF16SUBL_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 bf16subl(long double x, long double y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_BF16SUBL_H diff --git a/libc/src/math/canonicalizebf16.h b/libc/src/math/canonicalizebf16.h new file mode 100644 index 0000000..858fa32 --- /dev/null +++ b/libc/src/math/canonicalizebf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for canonicalizebf16 --------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_CANONICALIZEBF16_H +#define LLVM_LIBC_SRC_MATH_CANONICALIZEBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +int canonicalizebf16(bfloat16 *cx, const bfloat16 *x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_CANONICALIZEBF16_H diff --git a/libc/src/math/ceilbf16.h b/libc/src/math/ceilbf16.h new file mode 100644 index 0000000..bf70f25 --- /dev/null +++ b/libc/src/math/ceilbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for ceilbf16 ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_CEILBF16_H +#define LLVM_LIBC_SRC_MATH_CEILBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 ceilbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_CEILBF16_H diff --git a/libc/src/math/copysignbf16.h b/libc/src/math/copysignbf16.h new file mode 100644 index 0000000..6369616 --- /dev/null +++ b/libc/src/math/copysignbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for copysignbf16 ------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_COPYSIGNBF16_H +#define LLVM_LIBC_SRC_MATH_COPYSIGNBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 copysignbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_COPYSIGNBF16_H diff --git a/libc/src/math/fdimbf16.h b/libc/src/math/fdimbf16.h new file mode 100644 index 0000000..75bec34 --- /dev/null +++ b/libc/src/math/fdimbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for fdimbf16 ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FDIMBF16_H +#define LLVM_LIBC_SRC_MATH_FDIMBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 fdimbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FDIMBF16_H diff --git a/libc/src/math/floorbf16.h b/libc/src/math/floorbf16.h new file mode 100644 index 0000000..9b5a30a --- /dev/null +++ b/libc/src/math/floorbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for floorbf16 ---------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FLOORBF16_H +#define LLVM_LIBC_SRC_MATH_FLOORBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 floorbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FLOORBF16_H diff --git a/libc/src/math/fmaxbf16.h b/libc/src/math/fmaxbf16.h new file mode 100644 index 0000000..bdbd14c --- /dev/null +++ b/libc/src/math/fmaxbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for fmaxbf16 ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FMAXBF16_H +#define LLVM_LIBC_SRC_MATH_FMAXBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 fmaxbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FMAXBF16_H diff --git a/libc/src/math/fmaximum_mag_numbf16.h b/libc/src/math/fmaximum_mag_numbf16.h new file mode 100644 index 0000000..7663525 --- /dev/null +++ b/libc/src/math/fmaximum_mag_numbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for fmaximum_mag_numbf16 ----------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUMBF16_H +#define LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUMBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 fmaximum_mag_numbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUMBF16_H diff --git a/libc/src/math/fmaximum_magbf16.h b/libc/src/math/fmaximum_magbf16.h new file mode 100644 index 0000000..ff0ff1a --- /dev/null +++ b/libc/src/math/fmaximum_magbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for fmaximum_magbf16 --------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FMAXIMUM_MAGBF16_H +#define LLVM_LIBC_SRC_MATH_FMAXIMUM_MAGBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 fmaximum_magbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_MAGBF16_H diff --git a/libc/src/math/fmaximum_numbf16.h b/libc/src/math/fmaximum_numbf16.h new file mode 100644 index 0000000..f23bc52 --- /dev/null +++ b/libc/src/math/fmaximum_numbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for fmaximum_numbf16 --------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FMAXIMUM_NUMBF16_H +#define LLVM_LIBC_SRC_MATH_FMAXIMUM_NUMBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 fmaximum_numbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_NUMBF16_H diff --git a/libc/src/math/fmaximumbf16.h b/libc/src/math/fmaximumbf16.h new file mode 100644 index 0000000..9842e99 --- /dev/null +++ b/libc/src/math/fmaximumbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for fmaximumbf16 ------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FMAXIMUMBF16_H +#define LLVM_LIBC_SRC_MATH_FMAXIMUMBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 fmaximumbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FMAXIMUMBF16_H diff --git a/libc/src/math/fminbf16.h b/libc/src/math/fminbf16.h new file mode 100644 index 0000000..4c1ada9 --- /dev/null +++ b/libc/src/math/fminbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for fminbf16 ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FMINBF16_H +#define LLVM_LIBC_SRC_MATH_FMINBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 fminbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FMINBF16_H diff --git a/libc/src/math/fminimum_mag_numbf16.h b/libc/src/math/fminimum_mag_numbf16.h new file mode 100644 index 0000000..2773381 --- /dev/null +++ b/libc/src/math/fminimum_mag_numbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for fminimum_mag_numbf16 ----------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUMBF16_H +#define LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUMBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 fminimum_mag_numbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUMBF16_H diff --git a/libc/src/math/fminimum_magbf16.h b/libc/src/math/fminimum_magbf16.h new file mode 100644 index 0000000..fee5c4c8 --- /dev/null +++ b/libc/src/math/fminimum_magbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for fminimum_magbf16 --------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FMINIMUM_MAGBF16_H +#define LLVM_LIBC_SRC_MATH_FMINIMUM_MAGBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 fminimum_magbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_MAGBF16_H diff --git a/libc/src/math/fminimum_numbf16.h b/libc/src/math/fminimum_numbf16.h new file mode 100644 index 0000000..a3fd474 --- /dev/null +++ b/libc/src/math/fminimum_numbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for fminimum_numbf16 --------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FMINIMUM_NUMBF16_H +#define LLVM_LIBC_SRC_MATH_FMINIMUM_NUMBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 fminimum_numbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_NUMBF16_H diff --git a/libc/src/math/fminimumbf16.h b/libc/src/math/fminimumbf16.h new file mode 100644 index 0000000..07f1ada --- /dev/null +++ b/libc/src/math/fminimumbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for fminimumbf16 ------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FMINIMUMBF16_H +#define LLVM_LIBC_SRC_MATH_FMINIMUMBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 fminimumbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FMINIMUMBF16_H diff --git a/libc/src/math/fmodbf16.h b/libc/src/math/fmodbf16.h new file mode 100644 index 0000000..176dbcc --- /dev/null +++ b/libc/src/math/fmodbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for fmodbf16 ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FMODBF16_H +#define LLVM_LIBC_SRC_MATH_FMODBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 fmodbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FMODBF16_H diff --git a/libc/src/math/frexpbf16.h b/libc/src/math/frexpbf16.h new file mode 100644 index 0000000..1e9bba1 --- /dev/null +++ b/libc/src/math/frexpbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for frexpbf16 ---------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FREXPFB16_H +#define LLVM_LIBC_SRC_MATH_FREXPFB16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 frexpbf16(bfloat16 x, int *exp); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FREXPFB16_H diff --git a/libc/src/math/fromfpbf16.h b/libc/src/math/fromfpbf16.h new file mode 100644 index 0000000..bff991c --- /dev/null +++ b/libc/src/math/fromfpbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for fromfpbf16 --------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FROMFPBF16_H +#define LLVM_LIBC_SRC_MATH_FROMFPBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 fromfpbf16(bfloat16 x, int rnd, unsigned int width); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FROMFPBF16_H diff --git a/libc/src/math/fromfpxbf16.h b/libc/src/math/fromfpxbf16.h new file mode 100644 index 0000000..e40d975 --- /dev/null +++ b/libc/src/math/fromfpxbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for fromfpxbf16 -------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_FROMFPXBF16_H +#define LLVM_LIBC_SRC_MATH_FROMFPXBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 fromfpxbf16(bfloat16 x, int rnd, unsigned int width); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_FROMFPXBF16_H diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index a866195..a1f5de7 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -53,6 +53,20 @@ add_entrypoint_object( ) add_entrypoint_object( + canonicalizebf16 + SRCS + canonicalizebf16.cpp + HDRS + ../canonicalizebf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 +) + +add_entrypoint_object( iscanonical SRCS iscanonical.cpp @@ -97,6 +111,20 @@ add_entrypoint_object( ) add_entrypoint_object( + iscanonicalbf16 + SRCS + iscanonicalbf16.cpp + HDRS + ../iscanonicalbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 +) + +add_entrypoint_object( ceil SRCS ceil.cpp @@ -157,6 +185,22 @@ add_entrypoint_object( ) add_entrypoint_object( + ceilbf16 + SRCS + ceilbf16.cpp + HDRS + ../ceilbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + ROUND_OPT +) + +add_entrypoint_object( daddl SRCS daddl.cpp @@ -262,69 +306,6 @@ add_entrypoint_object( libc.src.__support.FPUtil.generic.add_sub ) -add_header_library( - range_reduction - HDRS - range_reduction.h - range_reduction_fma.h - DEPENDS - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.fma - libc.src.__support.FPUtil.multiply_add - libc.src.__support.FPUtil.nearest_integer - libc.src.__support.common -) - -add_header_library( - range_reduction_double - HDRS - range_reduction_double_common.h - range_reduction_double_fma.h - range_reduction_double_nofma.h - DEPENDS - libc.src.__support.FPUtil.double_double - libc.src.__support.FPUtil.dyadic_float - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.fma - libc.src.__support.FPUtil.multiply_add - libc.src.__support.FPUtil.nearest_integer - libc.src.__support.common - libc.src.__support.integer_literals -) - -add_header_library( - sincosf_utils - HDRS - sincosf_utils.h - DEPENDS - .range_reduction - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.polyeval - libc.src.__support.common -) - -add_header_library( - sincosf16_utils - HDRS - sincosf16_utils.h - DEPENDS - libc.src.__support.FPUtil.polyeval - libc.src.__support.FPUtil.nearest_integer - libc.src.__support.common -) - -add_header_library( - sincos_eval - HDRS - sincos_eval.h - DEPENDS - libc.src.__support.FPUtil.double_double - libc.src.__support.FPUtil.dyadic_float - libc.src.__support.FPUtil.multiply_add - libc.src.__support.FPUtil.polyeval - libc.src.__support.integer_literals -) - add_entrypoint_object( cos SRCS @@ -332,16 +313,7 @@ add_entrypoint_object( HDRS ../cos.h DEPENDS - .range_reduction_double - .sincos_eval - libc.hdr.errno_macros - libc.src.errno.errno - libc.src.__support.FPUtil.double_double - libc.src.__support.FPUtil.dyadic_float - libc.src.__support.FPUtil.except_value_utils - libc.src.__support.FPUtil.fenv_impl - libc.src.__support.FPUtil.fp_bits - libc.src.__support.macros.optimization + libc.src.__support.math.cos ) add_entrypoint_object( @@ -351,15 +323,7 @@ add_entrypoint_object( HDRS ../cosf.h DEPENDS - .sincosf_utils - libc.src.errno.errno - libc.src.__support.FPUtil.basic_operations - libc.src.__support.FPUtil.fenv_impl - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.except_value_utils - libc.src.__support.FPUtil.fma - libc.src.__support.FPUtil.polyeval - libc.src.__support.macros.optimization + libc.src.__support.math.cosf ) add_entrypoint_object( @@ -369,16 +333,7 @@ add_entrypoint_object( HDRS ../cosf16.h DEPENDS - .sincosf16_utils - libc.hdr.errno_macros - libc.hdr.fenv_macros - libc.src.__support.FPUtil.cast - libc.src.__support.FPUtil.fenv_impl - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.except_value_utils - libc.src.__support.FPUtil.multiply_add - libc.src.__support.macros.optimization - libc.src.__support.macros.properties.types + libc.src.__support.math.cosf16 ) add_entrypoint_object( @@ -388,12 +343,7 @@ add_entrypoint_object( HDRS ../cospif.h DEPENDS - .sincosf_utils - libc.src.__support.FPUtil.fenv_impl - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.fma - libc.src.__support.FPUtil.multiply_add - libc.src.__support.macros.optimization + libc.src.__support.math.cospif ) add_entrypoint_object( @@ -403,14 +353,7 @@ add_entrypoint_object( HDRS ../cospif16.h DEPENDS - .sincosf16_utils - libc.hdr.errno_macros - libc.hdr.fenv_macros - libc.src.__support.FPUtil.cast - libc.src.__support.FPUtil.fenv_impl - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.multiply_add - libc.src.__support.macros.optimization + libc.src.__support.math.cospif16 ) add_entrypoint_object( @@ -420,8 +363,8 @@ add_entrypoint_object( HDRS ../sin.h DEPENDS - .range_reduction_double - .sincos_eval + libc.src.__support.math.range_reduction_double + libc.src.__support.math.sincos_eval libc.hdr.errno_macros libc.src.errno.errno libc.src.__support.FPUtil.double_double @@ -440,8 +383,8 @@ add_entrypoint_object( HDRS ../sinf.h DEPENDS - .range_reduction - .sincosf_utils + libc.src.__support.math.range_reduction + libc.src.__support.math.sincosf_utils libc.src.errno.errno libc.src.__support.FPUtil.basic_operations libc.src.__support.FPUtil.fenv_impl @@ -459,7 +402,6 @@ add_entrypoint_object( HDRS ../sinf16.h DEPENDS - .sincosf16_utils libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.cast @@ -469,6 +411,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.multiply_add libc.src.__support.macros.optimization libc.src.__support.macros.properties.types + libc.src.__support.math.sincosf16_utils COMPILE_OPTIONS ${libc_opt_high_flag} ) @@ -480,8 +423,8 @@ add_entrypoint_object( HDRS ../sincos.h DEPENDS - .range_reduction_double - .sincos_eval + libc.src.__support.math.range_reduction_double + libc.src.__support.math.sincos_eval libc.hdr.errno_macros libc.src.errno.errno libc.src.__support.FPUtil.double_double @@ -500,7 +443,7 @@ add_entrypoint_object( HDRS ../sinpif.h DEPENDS - .sincosf_utils + libc.src.__support.math.sincosf_utils libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.fma @@ -517,8 +460,8 @@ add_entrypoint_object( HDRS ../sincosf.h DEPENDS - .range_reduction - .sincosf_utils + libc.src.__support.math.range_reduction + libc.src.__support.math.sincosf_utils libc.src.errno.errno libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits @@ -536,7 +479,6 @@ add_entrypoint_object( HDRS ../sinpif16.h DEPENDS - .sincosf16_utils libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.cast @@ -544,6 +486,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.multiply_add libc.src.__support.macros.optimization + libc.src.__support.math.sincosf16_utils ) add_entrypoint_object( @@ -553,7 +496,7 @@ add_entrypoint_object( HDRS ../tan.h DEPENDS - .range_reduction_double + libc.src.__support.math.range_reduction_double libc.hdr.errno_macros libc.src.errno.errno libc.src.__support.FPUtil.double_double @@ -572,8 +515,8 @@ add_entrypoint_object( HDRS ../tanf.h DEPENDS - .range_reduction - .sincosf_utils + libc.src.__support.math.range_reduction + libc.src.__support.math.sincosf_utils libc.src.errno.errno libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fenv_impl @@ -592,7 +535,6 @@ add_entrypoint_object( HDRS ../tanf16.h DEPENDS - .sincosf16_utils libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.cast @@ -602,6 +544,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.multiply_add libc.src.__support.macros.optimization libc.src.__support.macros.properties.types + libc.src.__support.math.sincosf16_utils ) add_entrypoint_object( @@ -611,7 +554,7 @@ add_entrypoint_object( HDRS ../tanpif.h DEPENDS - .sincosf_utils + libc.src.__support.math.sincosf_utils libc.src.__support.FPUtil.except_value_utils libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits @@ -626,7 +569,6 @@ add_entrypoint_object( HDRS ../tanpif16.h DEPENDS - .sincosf16_utils libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.cast @@ -635,6 +577,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.except_value_utils libc.src.__support.FPUtil.multiply_add libc.src.__support.macros.optimization + libc.src.__support.math.sincosf16_utils ) add_entrypoint_object( @@ -802,6 +745,22 @@ add_entrypoint_object( ) add_entrypoint_object( + truncbf16 + SRCS + truncbf16.cpp + HDRS + ../truncbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + ROUND_OPT +) + +add_entrypoint_object( floor SRCS floor.cpp @@ -862,6 +821,22 @@ add_entrypoint_object( ) add_entrypoint_object( + floorbf16 + SRCS + floorbf16.cpp + HDRS + ../floorbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + ROUND_OPT +) + +add_entrypoint_object( round SRCS round.cpp @@ -922,6 +897,22 @@ add_entrypoint_object( ) add_entrypoint_object( + roundbf16 + SRCS + roundbf16.cpp + HDRS + ../roundbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + ROUND_OPT +) + +add_entrypoint_object( roundeven SRCS roundeven.cpp @@ -982,6 +973,22 @@ add_entrypoint_object( ) add_entrypoint_object( + roundevenbf16 + SRCS + roundevenbf16.cpp + HDRS + ../roundevenbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + ROUND_OPT +) + +add_entrypoint_object( lround SRCS lround.cpp @@ -1034,6 +1041,19 @@ add_entrypoint_object( ) add_entrypoint_object( + lroundbf16 + SRCS + lroundbf16.cpp + HDRS + ../lroundf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.macros.config +) + +add_entrypoint_object( llround SRCS llround.cpp @@ -1086,6 +1106,19 @@ add_entrypoint_object( ) add_entrypoint_object( + llroundbf16 + SRCS + llroundbf16.cpp + HDRS + ../llroundf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.macros.config +) + +add_entrypoint_object( rint SRCS rint.cpp @@ -1146,6 +1179,21 @@ add_entrypoint_object( ) add_entrypoint_object( + rintbf16 + SRCS + rintbf16.cpp + HDRS + ../rintbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.macros.config + FLAGS + ROUND_OPT +) + +add_entrypoint_object( lrint SRCS lrint.cpp @@ -1198,6 +1246,19 @@ add_entrypoint_object( ) add_entrypoint_object( + lrintbf16 + SRCS + lrintbf16.cpp + HDRS + ../lrintbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.macros.config +) + +add_entrypoint_object( llrint SRCS llrint.cpp @@ -1250,6 +1311,17 @@ add_entrypoint_object( ) add_entrypoint_object( + llrintbf16 + SRCS + llrintbf16.cpp + HDRS + ../llrintbf16.h + DEPENDS + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.nearest_integer_operations +) + +add_entrypoint_object( nearbyint SRCS nearbyint.cpp @@ -1302,6 +1374,19 @@ add_entrypoint_object( ) add_entrypoint_object( + nearbyintbf16 + SRCS + nearbyintbf16.cpp + HDRS + ../nearbyintbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.macros.config +) + +add_entrypoint_object( erff SRCS erff.cpp @@ -1353,7 +1438,6 @@ add_entrypoint_object( ../exp2.h DEPENDS .common_constants - .explogxf libc.src.__support.CPP.bit libc.src.__support.CPP.optional libc.src.__support.FPUtil.dyadic_float @@ -1366,6 +1450,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.triple_double libc.src.__support.integer_literals libc.src.__support.macros.optimization + libc.src.__support.math.exp_utils libc.src.errno.errno ) @@ -1374,7 +1459,6 @@ add_header_library( HDRS exp2f_impl.h DEPENDS - .explogxf libc.src.__support.FPUtil.except_value_utils libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits @@ -1383,6 +1467,7 @@ add_header_library( libc.src.__support.FPUtil.polyeval libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization + libc.src.__support.math.exp10f_utils libc.src.__support.common libc.src.errno.errno ) @@ -1404,7 +1489,6 @@ add_entrypoint_object( HDRS ../exp2f16.h DEPENDS - .expxf16 libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.cast @@ -1413,6 +1497,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization + libc.src.__support.math.expxf16_utils ) add_entrypoint_object( @@ -1422,7 +1507,6 @@ add_entrypoint_object( HDRS ../exp2m1f.h DEPENDS - .explogxf libc.src.errno.errno libc.src.__support.common libc.src.__support.FPUtil.except_value_utils @@ -1433,6 +1517,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization libc.src.__support.macros.properties.cpu_features + libc.src.__support.math.exp10f_utils ) add_entrypoint_object( @@ -1442,7 +1527,6 @@ add_entrypoint_object( HDRS ../exp2m1f16.h DEPENDS - .expxf16 libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.common @@ -1455,6 +1539,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization libc.src.__support.macros.properties.cpu_features + libc.src.__support.math.expxf16_utils ) add_entrypoint_object( @@ -1497,7 +1582,6 @@ add_entrypoint_object( HDRS ../exp10m1f.h DEPENDS - .explogxf libc.src.errno.errno libc.src.__support.common libc.src.__support.FPUtil.except_value_utils @@ -1507,6 +1591,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.polyeval libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization + libc.src.__support.math.exp10f_utils ) add_entrypoint_object( @@ -1538,14 +1623,11 @@ add_entrypoint_object( ../expm1.h DEPENDS .common_constants - .explogxf libc.src.__support.CPP.bit - libc.src.__support.CPP.optional libc.src.__support.FPUtil.dyadic_float libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.multiply_add - libc.src.__support.FPUtil.nearest_integer libc.src.__support.FPUtil.polyeval libc.src.__support.FPUtil.rounding_mode libc.src.__support.FPUtil.triple_double @@ -1580,7 +1662,6 @@ add_entrypoint_object( HDRS ../expm1f16.h DEPENDS - .expxf16 libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.cast @@ -1591,6 +1672,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.polyeval libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization + libc.src.__support.math.expxf16_utils ) add_entrypoint_object( @@ -1602,7 +1684,6 @@ add_entrypoint_object( DEPENDS .common_constants .exp2f_impl - .explogxf libc.src.__support.math.exp10f libc.src.__support.CPP.bit libc.src.__support.FPUtil.fenv_impl @@ -1696,6 +1777,22 @@ add_entrypoint_object( ) add_entrypoint_object( + copysignbf16 + SRCS + copysignbf16.cpp + HDRS + ../copysignbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.manipulation_functions + FLAGS + MISC_MATH_BASIC_OPS_OPT +) + +add_entrypoint_object( frexp SRCS frexp.cpp @@ -1746,6 +1843,20 @@ add_entrypoint_object( ) add_entrypoint_object( + frexpbf16 + SRCS + frexpbf16.cpp + HDRS + ../frexpbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.manipulation_functions + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( ilogb SRCS ilogb.cpp @@ -1798,6 +1909,20 @@ add_entrypoint_object( ) add_entrypoint_object( + ilogbbf16 + SRCS + ilogbbf16.cpp + HDRS + ../ilogbbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.manipulation_functions + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( llogb SRCS llogb.cpp @@ -1850,6 +1975,20 @@ add_entrypoint_object( ) add_entrypoint_object( + llogbbf16 + SRCS + llogbbf16.cpp + HDRS + ../llogbbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.manipulation_functions + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( ldexp SRCS ldexp.cpp @@ -1899,6 +2038,20 @@ add_entrypoint_object( libc.src.__support.math.ldexpf128 ) +add_entrypoint_object( + ldexpbf16 + SRCS + ldexpbf16.cpp + HDRS + ../ldexpbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.manipulation_functions + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + add_object_library( common_constants HDRS @@ -1962,7 +2115,6 @@ add_entrypoint_object( HDRS ../log10f16.h DEPENDS - .expxf16 libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.cast @@ -1973,6 +2125,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.polyeval libc.src.__support.macros.optimization libc.src.__support.macros.properties.cpu_features + libc.src.__support.math.expxf16_utils ) add_entrypoint_object( @@ -2051,7 +2204,6 @@ add_entrypoint_object( HDRS ../log2f16.h DEPENDS - .expxf16 libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.cast @@ -2062,6 +2214,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.polyeval libc.src.__support.macros.optimization libc.src.__support.macros.properties.cpu_features + libc.src.__support.math.expxf16_utils ) add_entrypoint_object( @@ -2106,7 +2259,6 @@ add_entrypoint_object( HDRS ../logf16.h DEPENDS - .expxf16 libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.cast @@ -2117,6 +2269,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.polyeval libc.src.__support.macros.optimization libc.src.__support.macros.properties.cpu_features + libc.src.__support.math.expxf16_utils ) add_entrypoint_object( @@ -2172,6 +2325,20 @@ add_entrypoint_object( ) add_entrypoint_object( + logbbf16 + SRCS + logbbf16.cpp + HDRS + ../logbbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.manipulation_functions + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( modf SRCS modf.cpp @@ -2224,6 +2391,20 @@ add_entrypoint_object( ) add_entrypoint_object( + modfbf16 + SRCS + modfbf16.cpp + HDRS + ../modfbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.manipulation_functions + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( fmin SRCS fmin.cpp @@ -2281,6 +2462,21 @@ add_entrypoint_object( MISC_MATH_BASIC_OPS_OPT ) +add_entrypoint_object( + fminbf16 + SRCS + fminbf16.cpp + HDRS + ../fminbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + MISC_MATH_BASIC_OPS_OPT +) add_entrypoint_object( fmax @@ -2341,6 +2537,22 @@ add_entrypoint_object( ) add_entrypoint_object( + fmaxbf16 + SRCS + fmaxbf16.cpp + HDRS + ../fmaxbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + MISC_MATH_BASIC_OPS_OPT +) + +add_entrypoint_object( fmaximum SRCS fmaximum.cpp @@ -2399,6 +2611,21 @@ add_entrypoint_object( ) add_entrypoint_object( + fmaximumbf16 + SRCS + fmaximumbf16.cpp + HDRS + ../fmaximumbf16.h + DEPENDS + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + MISC_MATH_BASIC_OPS_OPT +) + +add_entrypoint_object( fmaximum_num SRCS fmaximum_num.cpp @@ -2457,6 +2684,21 @@ add_entrypoint_object( ) add_entrypoint_object( + fmaximum_numbf16 + SRCS + fmaximum_numbf16.cpp + HDRS + ../fmaximum_numbf16.h + DEPENDS + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + MISC_MATH_BASIC_OPS_OPT +) + +add_entrypoint_object( fmaximum_mag SRCS fmaximum_mag.cpp @@ -2515,6 +2757,21 @@ add_entrypoint_object( ) add_entrypoint_object( + fmaximum_magbf16 + SRCS + fmaximum_magbf16.cpp + HDRS + ../fmaximum_magbf16.h + DEPENDS + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + MISC_MATH_BASIC_OPS_OPT +) + +add_entrypoint_object( fmaximum_mag_num SRCS fmaximum_mag_num.cpp @@ -2573,6 +2830,21 @@ add_entrypoint_object( ) add_entrypoint_object( + fmaximum_mag_numbf16 + SRCS + fmaximum_mag_numbf16.cpp + HDRS + ../fmaximum_mag_numbf16.h + DEPENDS + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + MISC_MATH_BASIC_OPS_OPT +) + +add_entrypoint_object( fminimum SRCS fminimum.cpp @@ -2631,6 +2903,21 @@ add_entrypoint_object( ) add_entrypoint_object( + fminimumbf16 + SRCS + fminimumbf16.cpp + HDRS + ../fminimumbf16.h + DEPENDS + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + MISC_MATH_BASIC_OPS_OPT +) + +add_entrypoint_object( fminimum_num SRCS fminimum_num.cpp @@ -2689,6 +2976,21 @@ add_entrypoint_object( ) add_entrypoint_object( + fminimum_numbf16 + SRCS + fminimum_numbf16.cpp + HDRS + ../fminimum_numbf16.h + DEPENDS + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + MISC_MATH_BASIC_OPS_OPT +) + +add_entrypoint_object( fminimum_mag SRCS fminimum_mag.cpp @@ -2747,6 +3049,21 @@ add_entrypoint_object( ) add_entrypoint_object( + fminimum_magbf16 + SRCS + fminimum_magbf16.cpp + HDRS + ../fminimum_magbf16.h + DEPENDS + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + MISC_MATH_BASIC_OPS_OPT +) + +add_entrypoint_object( fminimum_mag_num SRCS fminimum_mag_num.cpp @@ -2805,6 +3122,21 @@ add_entrypoint_object( ) add_entrypoint_object( + fminimum_mag_numbf16 + SRCS + fminimum_mag_numbf16.cpp + HDRS + ../fminimum_mag_numbf16.h + DEPENDS + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + FLAGS + MISC_MATH_BASIC_OPS_OPT +) + +add_entrypoint_object( fmul SRCS fmul.cpp @@ -2977,6 +3309,20 @@ add_entrypoint_object( ) add_entrypoint_object( + remquobf16 + SRCS + remquobf16.cpp + HDRS + ../remquobf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.division_and_remainder_operations + libc.src.__support.macros.properties.types + libc.src.__support.macros.config +) + +add_entrypoint_object( remainderf SRCS remainderf.cpp @@ -3029,6 +3375,20 @@ add_entrypoint_object( ) add_entrypoint_object( + remainderbf16 + SRCS + remainderbf16.cpp + HDRS + ../remainderbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.division_and_remainder_operations + libc.src.__support.macros.properties.types + libc.src.__support.macros.config +) + +add_entrypoint_object( hypotf SRCS hypotf.cpp @@ -3112,6 +3472,20 @@ add_entrypoint_object( ) add_entrypoint_object( + fdimbf16 + SRCS + fdimbf16.cpp + HDRS + ../fdimbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 +) + +add_entrypoint_object( fdiv SRCS fdiv.cpp @@ -3228,6 +3602,20 @@ add_entrypoint_object( ) add_entrypoint_object( + issignalingbf16 + SRCS + issignalingbf16.cpp + HDRS + ../issignalingbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 +) + +add_entrypoint_object( isnan SRCS isnan.cpp @@ -3307,6 +3695,22 @@ add_entrypoint_object( ) add_entrypoint_object( + nanbf16 + SRCS + nanbf16.cpp + HDRS + ../nanbf16.h + DEPENDS + libc.src.errno.errno + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.libc_errno + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.__support.str_to_float +) + +add_entrypoint_object( nextafter SRCS nextafter.cpp @@ -3359,6 +3763,20 @@ add_entrypoint_object( ) add_entrypoint_object( + nextafterbf16 + SRCS + nextafterbf16.cpp + HDRS + ../nextafterbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.manipulation_functions + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( nexttoward SRCS nexttoward.cpp @@ -3400,6 +3818,20 @@ add_entrypoint_object( ) add_entrypoint_object( + nexttowardbf16 + SRCS + nexttowardbf16.cpp + HDRS + ../nexttowardbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.manipulation_functions + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( nextdown SRCS nextdown.cpp @@ -3452,6 +3884,20 @@ add_entrypoint_object( ) add_entrypoint_object( + nextdownbf16 + SRCS + nextdownbf16.cpp + HDRS + ../nextdownbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.manipulation_functions + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( nextup SRCS nextup.cpp @@ -3504,6 +3950,20 @@ add_entrypoint_object( ) add_entrypoint_object( + nextupbf16 + SRCS + nextupbf16.cpp + HDRS + ../nextupbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.manipulation_functions + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( fmod SRCS fmod.cpp @@ -3556,6 +4016,20 @@ add_entrypoint_object( ) add_entrypoint_object( + fmodbf16 + SRCS + fmodbf16.cpp + HDRS + ../fmodbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.fmod +) + +add_entrypoint_object( fromfp SRCS fromfp.cpp @@ -3608,6 +4082,20 @@ add_entrypoint_object( ) add_entrypoint_object( + fromfpbf16 + SRCS + fromfpbf16.cpp + HDRS + ../fromfpbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( fromfpx SRCS fromfpx.cpp @@ -3660,6 +4148,20 @@ add_entrypoint_object( ) add_entrypoint_object( + fromfpxbf16 + SRCS + fromfpxbf16.cpp + HDRS + ../fromfpxbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( ufromfp SRCS ufromfp.cpp @@ -3712,6 +4214,20 @@ add_entrypoint_object( ) add_entrypoint_object( + ufromfpbf16 + SRCS + ufromfpbf16.cpp + HDRS + ../ufromfpbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( ufromfpx SRCS ufromfpx.cpp @@ -3763,17 +4279,18 @@ add_entrypoint_object( libc.src.__support.FPUtil.nearest_integer_operations ) -#TODO: Add errno include to the hyperbolic functions. -add_header_library( - explogxf +add_entrypoint_object( + ufromfpxbf16 + SRCS + ufromfpxbf16.cpp HDRS - explogxf.h + ../ufromfpxbf16.h DEPENDS - .common_constants - libc.src.__support.math.exp_utils - libc.src.__support.math.acoshf_utils - libc.src.__support.macros.properties.cpu_features - libc.src.errno.errno + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.macros.config + libc.src.__support.macros.properties.types ) add_entrypoint_object( @@ -3783,11 +4300,7 @@ add_entrypoint_object( HDRS ../coshf.h DEPENDS - .explogxf - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.multiply_add - libc.src.__support.FPUtil.rounding_mode - libc.src.__support.macros.optimization + libc.src.__support.math.coshf ) add_entrypoint_object( @@ -3797,14 +4310,7 @@ add_entrypoint_object( HDRS ../coshf16.h DEPENDS - .expxf16 - libc.hdr.errno_macros - libc.hdr.fenv_macros - libc.src.__support.FPUtil.except_value_utils - libc.src.__support.FPUtil.fenv_impl - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.rounding_mode - libc.src.__support.macros.optimization + libc.src.__support.math.coshf16 ) add_entrypoint_object( @@ -3814,10 +4320,10 @@ add_entrypoint_object( HDRS ../sinhf.h DEPENDS - .explogxf libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization + libc.src.__support.math.sinhfcoshf_utils ) add_entrypoint_object( @@ -3827,14 +4333,14 @@ add_entrypoint_object( HDRS ../sinhf16.h DEPENDS - .expxf16 libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.except_value_utils - libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization + libc.src.__support.math.expxf16_utils ) add_entrypoint_object( @@ -3844,12 +4350,12 @@ add_entrypoint_object( HDRS ../tanhf.h DEPENDS - .explogxf libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.rounding_mode libc.src.__support.FPUtil.multiply_add libc.src.__support.FPUtil.polyeval libc.src.__support.macros.optimization + libc.src.__support.math.exp10f_utils ) add_entrypoint_object( @@ -3859,7 +4365,6 @@ add_entrypoint_object( HDRS ../tanhf16.h DEPENDS - .expxf16 libc.hdr.fenv_macros libc.src.__support.CPP.array libc.src.__support.FPUtil.cast @@ -3871,6 +4376,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.polyeval libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization + libc.src.__support.math.expxf16_utils ) add_entrypoint_object( @@ -3880,7 +4386,6 @@ add_entrypoint_object( HDRS ../acoshf.h DEPENDS - .explogxf libc.src.__support.math.acoshf ) @@ -3916,6 +4421,25 @@ add_entrypoint_object( ) add_entrypoint_object( + asinpif16 + SRCS + asinpif16.cpp + HDRS + ../asinpif16.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.__support.FPUtil.cast + libc.src.__support.FPUtil.except_value_utils + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.multiply_add + libc.src.__support.FPUtil.polyeval + libc.src.__support.FPUtil.sqrt + libc.src.__support.macros.optimization +) + +add_entrypoint_object( atanhf SRCS atanhf.cpp @@ -3936,6 +4460,25 @@ add_entrypoint_object( ) add_entrypoint_object( + atanpif16 + SRCS + atanpif16.cpp + HDRS + ../atanpif16.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.__support.FPUtil.cast + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.multiply_add + libc.src.__support.FPUtil.polyeval + libc.src.__support.FPUtil.sqrt + libc.src.__support.macros.optimization + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( asinf SRCS asinf.cpp @@ -4137,6 +4680,21 @@ add_entrypoint_object( ) add_entrypoint_object( + scalblnbf16 + SRCS + scalblnbf16.cpp + HDRS + ../scalblnbf16.h + DEPENDS + libc.hdr.float_macros + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.manipulation_functions +) + +add_entrypoint_object( scalbn SRCS scalbn.cpp @@ -4194,6 +4752,21 @@ add_entrypoint_object( ) add_entrypoint_object( + scalbnbf16 + SRCS + scalbnbf16.cpp + HDRS + ../scalblnbf16.h + DEPENDS + libc.hdr.float_macros + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.manipulation_functions +) + +add_entrypoint_object( fmaf SRCS fmaf.cpp @@ -4274,6 +4847,21 @@ add_entrypoint_object( libc.src.__support.FPUtil.basic_operations libc.src.__support.macros.properties.types ) + +add_entrypoint_object( + totalorderbf16 + SRCS + totalorderbf16.cpp + HDRS + ../totalorderbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 +) + add_entrypoint_object( totalordermag SRCS @@ -4326,6 +4914,20 @@ add_entrypoint_object( ) add_entrypoint_object( + totalordermagbf16 + SRCS + totalordermagbf16.cpp + HDRS + ../totalordermagbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.macros.config + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 +) + +add_entrypoint_object( getpayload SRCS getpayload.cpp @@ -4378,6 +4980,20 @@ add_entrypoint_object( ) add_entrypoint_object( + getpayloadbf16 + SRCS + getpayloadbf16.cpp + HDRS + ../getpayloadbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( setpayload SRCS setpayload.cpp @@ -4430,6 +5046,20 @@ add_entrypoint_object( ) add_entrypoint_object( + setpayloadbf16 + SRCS + setpayloadbf16.cpp + HDRS + ../setpayloadbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( setpayloadsig SRCS setpayloadsig.cpp @@ -4482,6 +5112,20 @@ add_entrypoint_object( ) add_entrypoint_object( + setpayloadsigbf16 + SRCS + setpayloadsigbf16.cpp + HDRS + ../setpayloadsigbf16.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( f16add SRCS f16add.cpp @@ -4739,11 +5383,7 @@ add_entrypoint_object( HDRS ../cbrtf.h DEPENDS - libc.hdr.fenv_macros - libc.src.__support.FPUtil.fenv_impl - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.multiply_add - libc.src.__support.macros.optimization + libc.src.__support.math.cbrtf ) add_entrypoint_object( @@ -4821,17 +5461,282 @@ add_entrypoint_object( libc.src.__support.FPUtil.generic.mul ) -add_header_library( - expxf16 +add_entrypoint_object( + bf16add + SRCS + bf16add.cpp HDRS - expxf16.h + ../bf16add.h DEPENDS - libc.hdr.stdint_proxy - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.cast - libc.src.__support.FPUtil.multiply_add - libc.src.__support.FPUtil.nearest_integer - libc.src.__support.macros.attributes - libc.src.__support.math.expf16_utils - libc.src.__support.math.exp10_float16_constants + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16addf + SRCS + bf16addf.cpp + HDRS + ../bf16addf.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16addl + SRCS + bf16addl.cpp + HDRS + ../bf16addl.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16addf128 + SRCS + bf16addf128.cpp + HDRS + ../bf16addf128.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16div + SRCS + bf16div.cpp + HDRS + ../bf16div.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.div + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16divf + SRCS + bf16divf.cpp + HDRS + ../bf16divf.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.div + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16divl + SRCS + bf16divl.cpp + HDRS + ../bf16divl.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.div + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16divf128 + SRCS + bf16divf128.cpp + HDRS + ../bf16divf128.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.div + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16fma + SRCS + bf16fma.cpp + HDRS + ../bf16fma.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fma + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16fmaf + SRCS + bf16fmaf.cpp + HDRS + ../bf16fmaf.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fma + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16fmal + SRCS + bf16fmal.cpp + HDRS + ../bf16fmal.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fma + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16fmaf128 + SRCS + bf16fmaf128.cpp + HDRS + ../bf16fmaf128.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fma + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16mul + SRCS + bf16mul.cpp + HDRS + ../bf16mul.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.mul + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16mulf + SRCS + bf16mulf.cpp + HDRS + ../bf16mulf.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.mul + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16mull + SRCS + bf16mull.cpp + HDRS + ../bf16mull.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.mul + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16mulf128 + SRCS + bf16mulf128.cpp + HDRS + ../bf16mulf128.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.mul + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16sub + SRCS + bf16sub.cpp + HDRS + ../bf16sub.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16subf + SRCS + bf16subf.cpp + HDRS + ../bf16subf.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16subl + SRCS + bf16subl.cpp + HDRS + ../bf16subl.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.macros.config + libc.src.__support.macros.properties.types +) + +add_entrypoint_object( + bf16subf128 + SRCS + bf16subf128.cpp + HDRS + ../bf16subf128.h + DEPENDS + libc.src.__support.common + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.macros.config + libc.src.__support.macros.properties.types ) diff --git a/libc/src/math/generic/acoshf.cpp b/libc/src/math/generic/acoshf.cpp index 5c04583..c964632 100644 --- a/libc/src/math/generic/acoshf.cpp +++ b/libc/src/math/generic/acoshf.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/math/acoshf.h" - #include "src/__support/math/acoshf.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/math/generic/asinpif16.cpp b/libc/src/math/generic/asinpif16.cpp new file mode 100644 index 0000000..aabc086 --- /dev/null +++ b/libc/src/math/generic/asinpif16.cpp @@ -0,0 +1,127 @@ +//===-- Half-precision asinpif16(x) function ------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#include "src/math/asinpif16.h" +#include "hdr/errno_macros.h" +#include "hdr/fenv_macros.h" +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/PolyEval.h" +#include "src/__support/FPUtil/cast.h" +#include "src/__support/FPUtil/except_value_utils.h" +#include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/FPUtil/sqrt.h" +#include "src/__support/macros/optimization.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(float16, asinpif16, (float16 x)) { + using FPBits = fputil::FPBits<float16>; + + FPBits xbits(x); + bool is_neg = xbits.is_neg(); + double x_abs = fputil::cast<double>(xbits.abs().get_val()); + + auto signed_result = [is_neg](auto r) -> auto { return is_neg ? -r : r; }; + + if (LIBC_UNLIKELY(x_abs > 1.0)) { + // aspinf16(NaN) = NaN + if (xbits.is_nan()) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + return x; + } + + // 1 < |x| <= +/-inf + fputil::raise_except_if_required(FE_INVALID); + fputil::set_errno_if_required(EDOM); + + return FPBits::quiet_nan().get_val(); + } + + // the coefficients for the polynomial approximation of asin(x)/pi in the + // range [0, 0.5] extracted using python-sympy + // + // Python code to generate the coefficients: + // > from sympy import * + // > import math + // > x = symbols('x') + // > print(series(asin(x)/math.pi, x, 0, 21)) + // + // OUTPUT: + // + // 0.318309886183791*x + 0.0530516476972984*x**3 + 0.0238732414637843*x**5 + + // 0.0142102627760621*x**7 + 0.00967087327815336*x**9 + + // 0.00712127941391293*x**11 + 0.00552355646848375*x**13 + + // 0.00444514782463692*x**15 + 0.00367705242846804*x**17 + + // 0.00310721681820837*x**19 + O(x**21) + // + // it's very accurate in the range [0, 0.5] and has a maximum error of + // 0.0000000000000001 in the range [0, 0.5]. + constexpr double POLY_COEFFS[] = { + 0x1.45f306dc9c889p-2, // x^1 + 0x1.b2995e7b7b5fdp-5, // x^3 + 0x1.8723a1d588a36p-6, // x^5 + 0x1.d1a452f20430dp-7, // x^7 + 0x1.3ce52a3a09f61p-7, // x^9 + 0x1.d2b33e303d375p-8, // x^11 + 0x1.69fde663c674fp-8, // x^13 + 0x1.235134885f19bp-8, // x^15 + }; + // polynomial evaluation using horner's method + // work only for |x| in [0, 0.5] + auto asinpi_polyeval = [](double x) -> double { + return x * fputil::polyeval(x * x, POLY_COEFFS[0], POLY_COEFFS[1], + POLY_COEFFS[2], POLY_COEFFS[3], POLY_COEFFS[4], + POLY_COEFFS[5], POLY_COEFFS[6], POLY_COEFFS[7]); + }; + + // if |x| <= 0.5: + if (LIBC_UNLIKELY(x_abs <= 0.5)) { + // Use polynomial approximation of asin(x)/pi in the range [0, 0.5] + double result = asinpi_polyeval(fputil::cast<double>(x)); + return fputil::cast<float16>(result); + } + + // If |x| > 0.5, we need to use the range reduction method: + // y = asin(x) => x = sin(y) + // because: sin(a) = cos(pi/2 - a) + // therefore: + // x = cos(pi/2 - y) + // let z = pi/2 - y, + // x = cos(z) + // because: cos(2a) = 1 - 2 * sin^2(a), z = 2a, a = z/2 + // therefore: + // cos(z) = 1 - 2 * sin^2(z/2) + // sin(z/2) = sqrt((1 - cos(z))/2) + // sin(z/2) = sqrt((1 - x)/2) + // let u = (1 - x)/2 + // then: + // sin(z/2) = sqrt(u) + // z/2 = asin(sqrt(u)) + // z = 2 * asin(sqrt(u)) + // pi/2 - y = 2 * asin(sqrt(u)) + // y = pi/2 - 2 * asin(sqrt(u)) + // y/pi = 1/2 - 2 * asin(sqrt(u))/pi + // + // Finally, we can write: + // asinpi(x) = 1/2 - 2 * asinpi(sqrt(u)) + // where u = (1 - x) /2 + // = 0.5 - 0.5 * x + // = multiply_add(-0.5, x, 0.5) + + double u = fputil::multiply_add(-0.5, x_abs, 0.5); + double asinpi_sqrt_u = asinpi_polyeval(fputil::sqrt<double>(u)); + double result = fputil::multiply_add(-2.0, asinpi_sqrt_u, 0.5); + + return fputil::cast<float16>(signed_result(result)); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/atanpif16.cpp b/libc/src/math/generic/atanpif16.cpp new file mode 100644 index 0000000..c54087c --- /dev/null +++ b/libc/src/math/generic/atanpif16.cpp @@ -0,0 +1,157 @@ +//===-- Half-precision atanpi function ------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/atanpif16.h" +#include "hdr/errno_macros.h" +#include "hdr/fenv_macros.h" +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/PolyEval.h" +#include "src/__support/FPUtil/cast.h" +#include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/FPUtil/sqrt.h" +#include "src/__support/macros/optimization.h" + +namespace LIBC_NAMESPACE_DECL { + +// Using Python's SymPy library, we can obtain the polynomial approximation of +// arctan(x)/pi. The steps are as follows: +// >>> from sympy import * +// >>> import math +// >>> x = symbols('x') +// >>> print(series(atan(x)/math.pi, x, 0, 17)) +// +// Output: +// 0.318309886183791*x - 0.106103295394597*x**3 + 0.0636619772367581*x**5 - +// 0.0454728408833987*x**7 + 0.0353677651315323*x**9 - 0.0289372623803446*x**11 +// + 0.0244853758602916*x**13 - 0.0212206590789194*x**15 + O(x**17) +// +// We will assign this degree-15 Taylor polynomial as g(x). This polynomial +// approximation is accurate for arctan(x)/pi when |x| is in the range [0, 0.5]. +// +// +// To compute arctan(x) for all real x, we divide the domain into the following +// cases: +// +// * Case 1: |x| <= 0.5 +// In this range, the direct polynomial approximation is used: +// arctan(x)/pi = sign(x) * g(|x|) +// or equivalently, arctan(x) = sign(x) * pi * g(|x|). +// +// * Case 2: 0.5 < |x| <= 1 +// We use the double-angle identity for the tangent function, specifically: +// arctan(x) = 2 * arctan(x / (1 + sqrt(1 + x^2))). +// Applying this, we have: +// arctan(x)/pi = sign(x) * 2 * arctan(x')/pi, +// where x' = |x| / (1 + sqrt(1 + x^2)). +// Thus, arctan(x)/pi = sign(x) * 2 * g(x') +// +// When |x| is in (0.5, 1], the value of x' will always fall within the +// interval [0.207, 0.414], which is within the accurate range of g(x). +// +// * Case 3: |x| > 1 +// For values of |x| greater than 1, we use the reciprocal transformation +// identity: +// arctan(x) = pi/2 - arctan(1/x) for x > 0. +// For any x (real number), this generalizes to: +// arctan(x)/pi = sign(x) * (1/2 - arctan(1/|x|)/pi). +// Then, using g(x) for arctan(1/|x|)/pi: +// arctan(x)/pi = sign(x) * (1/2 - g(1/|x|)). +// +// Note that if 1/|x| still falls outside the +// g(x)'s primary range of accuracy (i.e., if 0.5 < 1/|x| <= 1), the rule +// from Case 2 must be applied recursively to 1/|x|. + +LLVM_LIBC_FUNCTION(float16, atanpif16, (float16 x)) { + using FPBits = fputil::FPBits<float16>; + + FPBits xbits(x); + bool is_neg = xbits.is_neg(); + + auto signed_result = [is_neg](double r) -> float16 { + return fputil::cast<float16>(is_neg ? -r : r); + }; + + if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) { + if (xbits.is_nan()) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + return x; + } + // atanpi(±∞) = ±0.5 + return signed_result(0.5); + } + + if (LIBC_UNLIKELY(xbits.is_zero())) + return x; + + double x_abs = fputil::cast<double>(xbits.abs().get_val()); + + if (LIBC_UNLIKELY(x_abs == 1.0)) + return signed_result(0.25); + + // evaluate atan(x)/pi using polynomial approximation, valid for |x| <= 0.5 + constexpr auto atanpi_eval = [](double x) -> double { + // polynomial coefficients for atan(x)/pi taylor series + // generated using sympy: series(atan(x)/pi, x, 0, 17) + constexpr static double POLY_COEFFS[] = { + 0x1.45f306dc9c889p-2, // x^1: 1/pi + -0x1.b2995e7b7b60bp-4, // x^3: -1/(3*pi) + 0x1.04c26be3b06ccp-4, // x^5: 1/(5*pi) + -0x1.7483758e69c08p-5, // x^7: -1/(7*pi) + 0x1.21bb945252403p-5, // x^9: 1/(9*pi) + -0x1.da1bace3cc68ep-6, // x^11: -1/(11*pi) + 0x1.912b1c2336cf2p-6, // x^13: 1/(13*pi) + -0x1.5bade52f95e7p-6, // x^15: -1/(15*pi) + }; + double x_sq = x * x; + return x * fputil::polyeval(x_sq, POLY_COEFFS[0], POLY_COEFFS[1], + POLY_COEFFS[2], POLY_COEFFS[3], POLY_COEFFS[4], + POLY_COEFFS[5], POLY_COEFFS[6], POLY_COEFFS[7]); + }; + + // Case 1: |x| <= 0.5 - Direct polynomial evaluation + if (LIBC_LIKELY(x_abs <= 0.5)) { + double result = atanpi_eval(x_abs); + return signed_result(result); + } + + // case 2: 0.5 < |x| <= 1 - use double-angle reduction + // atan(x) = 2 * atan(x / (1 + sqrt(1 + x^2))) + // so atanpi(x) = 2 * atanpi(x') where x' = x / (1 + sqrt(1 + x^2)) + if (x_abs <= 1.0) { + double x_abs_sq = x_abs * x_abs; + double sqrt_term = fputil::sqrt<double>(1.0 + x_abs_sq); + double x_prime = x_abs / (1.0 + sqrt_term); + double result = 2.0 * atanpi_eval(x_prime); + return signed_result(result); + } + + // case 3: |x| > 1 - use reciprocal transformation + // atan(x) = pi/2 - atan(1/x) for x > 0 + // so atanpi(x) = 1/2 - atanpi(1/x) + double x_recip = 1.0 / x_abs; + double result; + + // if 1/|x| > 0.5, we need to apply Case 2 transformation to 1/|x| + if (x_recip > 0.5) { + double x_recip_sq = x_recip * x_recip; + double sqrt_term = fputil::sqrt<double>(1.0 + x_recip_sq); + double x_prime = x_recip / (1.0 + sqrt_term); + result = fputil::multiply_add(-2.0, atanpi_eval(x_prime), 0.5); + } else { + // direct evaluation since 1/|x| <= 0.5 + result = 0.5 - atanpi_eval(x_recip); + } + + return signed_result(result); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16add.cpp b/libc/src/math/generic/bf16add.cpp new file mode 100644 index 0000000..257596a --- /dev/null +++ b/libc/src/math/generic/bf16add.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16add function --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16add.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/add_sub.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16add, (double x, double y)) { + return fputil::generic::add<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16addf.cpp b/libc/src/math/generic/bf16addf.cpp new file mode 100644 index 0000000..65e6cbf --- /dev/null +++ b/libc/src/math/generic/bf16addf.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16addf function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16addf.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/add_sub.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16addf, (float x, float y)) { + return fputil::generic::add<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16addf128.cpp b/libc/src/math/generic/bf16addf128.cpp new file mode 100644 index 0000000..03f70af --- /dev/null +++ b/libc/src/math/generic/bf16addf128.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16addf128 function ----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16addf128.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/add_sub.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16addf128, (float128 x, float128 y)) { + return fputil::generic::add<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16addl.cpp b/libc/src/math/generic/bf16addl.cpp new file mode 100644 index 0000000..c212195 --- /dev/null +++ b/libc/src/math/generic/bf16addl.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16addl function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16addl.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/add_sub.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16addl, (long double x, long double y)) { + return fputil::generic::add<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16div.cpp b/libc/src/math/generic/bf16div.cpp new file mode 100644 index 0000000..5e9b1b4 --- /dev/null +++ b/libc/src/math/generic/bf16div.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16div function --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16div.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/div.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16div, (double x, double y)) { + return fputil::generic::div<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16divf.cpp b/libc/src/math/generic/bf16divf.cpp new file mode 100644 index 0000000..2054a64 --- /dev/null +++ b/libc/src/math/generic/bf16divf.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16divf function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16divf.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/div.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16divf, (float x, float y)) { + return fputil::generic::div<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16divf128.cpp b/libc/src/math/generic/bf16divf128.cpp new file mode 100644 index 0000000..fbe9775 --- /dev/null +++ b/libc/src/math/generic/bf16divf128.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16divf128 function ----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16divf128.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/div.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16divf128, (float128 x, float128 y)) { + return fputil::generic::div<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16divl.cpp b/libc/src/math/generic/bf16divl.cpp new file mode 100644 index 0000000..21dd6b1 --- /dev/null +++ b/libc/src/math/generic/bf16divl.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16divl function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16divl.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/div.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16divl, (long double x, long double y)) { + return fputil::generic::div<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16fma.cpp b/libc/src/math/generic/bf16fma.cpp new file mode 100644 index 0000000..0f0fe86 --- /dev/null +++ b/libc/src/math/generic/bf16fma.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16fma function --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16fma.h" +#include "src/__support/FPUtil/FMA.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16fma, (double x, double y, double z)) { + return fputil::fma<bfloat16>(x, y, z); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16fmaf.cpp b/libc/src/math/generic/bf16fmaf.cpp new file mode 100644 index 0000000..739691c --- /dev/null +++ b/libc/src/math/generic/bf16fmaf.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16fmaf function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16fmaf.h" +#include "src/__support/FPUtil/FMA.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16fmaf, (float x, float y, float z)) { + return fputil::fma<bfloat16>(x, y, z); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16fmaf128.cpp b/libc/src/math/generic/bf16fmaf128.cpp new file mode 100644 index 0000000..a29a0b0 --- /dev/null +++ b/libc/src/math/generic/bf16fmaf128.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of bf16fmaf128 function ----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16fmaf128.h" +#include "src/__support/FPUtil/FMA.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16fmaf128, + (float128 x, float128 y, float128 z)) { + return fputil::fma<bfloat16>(x, y, z); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16fmal.cpp b/libc/src/math/generic/bf16fmal.cpp new file mode 100644 index 0000000..f31ec69 --- /dev/null +++ b/libc/src/math/generic/bf16fmal.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of bf16fmal function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16fmal.h" + +#include "src/__support/FPUtil/FMA.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16fmal, + (long double x, long double y, long double z)) { + return fputil::fma<bfloat16>(x, y, z); +} +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16mul.cpp b/libc/src/math/generic/bf16mul.cpp new file mode 100644 index 0000000..c50eec2 --- /dev/null +++ b/libc/src/math/generic/bf16mul.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16mul function --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16mul.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/mul.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16mul, (double x, double y)) { + return fputil::generic::mul<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16mulf.cpp b/libc/src/math/generic/bf16mulf.cpp new file mode 100644 index 0000000..117fcd1 --- /dev/null +++ b/libc/src/math/generic/bf16mulf.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16mulf function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16mulf.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/mul.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16mulf, (float x, float y)) { + return fputil::generic::mul<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16mulf128.cpp b/libc/src/math/generic/bf16mulf128.cpp new file mode 100644 index 0000000..ff2a081 --- /dev/null +++ b/libc/src/math/generic/bf16mulf128.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16mulf128 function ----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16mulf128.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/mul.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16mulf128, (float128 x, float128 y)) { + return fputil::generic::mul<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16mull.cpp b/libc/src/math/generic/bf16mull.cpp new file mode 100644 index 0000000..e7c4fc0 --- /dev/null +++ b/libc/src/math/generic/bf16mull.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16mull function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16mull.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/mul.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16mull, (long double x, long double y)) { + return fputil::generic::mul<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16sub.cpp b/libc/src/math/generic/bf16sub.cpp new file mode 100644 index 0000000..65eb209 --- /dev/null +++ b/libc/src/math/generic/bf16sub.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16sub function --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16sub.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/add_sub.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16sub, (double x, double y)) { + return fputil::generic::sub<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16subf.cpp b/libc/src/math/generic/bf16subf.cpp new file mode 100644 index 0000000..6bba4be --- /dev/null +++ b/libc/src/math/generic/bf16subf.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16subf function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16subf.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/add_sub.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16subf, (float x, float y)) { + return fputil::generic::sub<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16subf128.cpp b/libc/src/math/generic/bf16subf128.cpp new file mode 100644 index 0000000..e5fe107 --- /dev/null +++ b/libc/src/math/generic/bf16subf128.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16subf128 function ----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16subf128.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/add_sub.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16subf128, (float128 x, float128 y)) { + return fputil::generic::sub<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/bf16subl.cpp b/libc/src/math/generic/bf16subl.cpp new file mode 100644 index 0000000..d3a970c --- /dev/null +++ b/libc/src/math/generic/bf16subl.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of bf16subl function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/bf16subl.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/add_sub.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, bf16subl, (long double x, long double y)) { + return fputil::generic::sub<bfloat16>(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/canonicalizebf16.cpp b/libc/src/math/generic/canonicalizebf16.cpp new file mode 100644 index 0000000..9cc3790 --- /dev/null +++ b/libc/src/math/generic/canonicalizebf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of canonicalizebf16 function -----------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/canonicalizebf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, canonicalizebf16, (bfloat16 * cx, const bfloat16 *x)) { + return fputil::canonicalize(*cx, *x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/cbrtf.cpp b/libc/src/math/generic/cbrtf.cpp index 71b23c4..0bd8f71 100644 --- a/libc/src/math/generic/cbrtf.cpp +++ b/libc/src/math/generic/cbrtf.cpp @@ -7,153 +7,10 @@ //===----------------------------------------------------------------------===// #include "src/math/cbrtf.h" -#include "hdr/fenv_macros.h" -#include "src/__support/FPUtil/FEnvImpl.h" -#include "src/__support/FPUtil/FPBits.h" -#include "src/__support/FPUtil/multiply_add.h" -#include "src/__support/common.h" -#include "src/__support/macros/config.h" -#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY +#include "src/__support/math/cbrtf.h" namespace LIBC_NAMESPACE_DECL { -namespace { - -// Look up table for 2^(i/3) for i = 0, 1, 2. -constexpr double CBRT2[3] = {1.0, 0x1.428a2f98d728bp0, 0x1.965fea53d6e3dp0}; - -// Degree-7 polynomials approximation of ((1 + x)^(1/3) - 1)/x for 0 <= x <= 1 -// generated by Sollya with: -// > for i from 0 to 15 do { -// P = fpminimax(((1 + x)^(1/3) - 1)/x, 6, [|D...|], [i/16, (i + 1)/16]); -// print("{", coeff(P, 0), ",", coeff(P, 1), ",", coeff(P, 2), ",", -// coeff(P, 3), ",", coeff(P, 4), ",", coeff(P, 5), ",", -// coeff(P, 6), "},"); -// }; -// Then (1 + x)^(1/3) ~ 1 + x * P(x). -constexpr double COEFFS[16][7] = { - {0x1.55555555554ebp-2, -0x1.c71c71c678c0cp-4, 0x1.f9add2776de81p-5, - -0x1.511e10aa964a7p-5, 0x1.ee44165937fa2p-6, -0x1.7c5c9e059345dp-6, - 0x1.047f75e0aff14p-6}, - {0x1.5555554d1149ap-2, -0x1.c71c676fcb5bp-4, 0x1.f9ab127dc57ebp-5, - -0x1.50ea8fd1d4c15p-5, 0x1.e9d68f28ced43p-6, -0x1.60e0e1e661311p-6, - 0x1.716eca1d6e3bcp-7}, - {0x1.5555546377d45p-2, -0x1.c71bc1c6d49d2p-4, 0x1.f9924cc0ed24dp-5, - -0x1.4fea3beb53b3bp-5, 0x1.de028a9a07b1bp-6, -0x1.3b090d2233524p-6, - 0x1.0aeca34893785p-7}, - {0x1.55554dce9f649p-2, -0x1.c7188b34b98f8p-4, 0x1.f93e1af34af49p-5, - -0x1.4d9a06be75c63p-5, 0x1.cb943f4f68992p-6, -0x1.139a685a5e3c4p-6, - 0x1.88410674c6a5dp-8}, - {0x1.5555347d211c3p-2, -0x1.c70f2a4b1a5fap-4, 0x1.f88420e8602c3p-5, - -0x1.49becfa4ed3ep-5, 0x1.b475cd9013162p-6, -0x1.dcfee1dd2f8efp-7, - 0x1.249bb51a1c498p-8}, - {0x1.5554f01b33dbap-2, -0x1.c6facb929dbf1p-4, 0x1.f73fb7861252ep-5, - -0x1.4459a4a0071fap-5, 0x1.9a8df2b504fc2p-6, -0x1.9a7ce3006d06ep-7, - 0x1.ba9230918fa2ep-9}, - {0x1.55545c695db5fp-2, -0x1.c6d6089f20275p-4, 0x1.f556e0ea80efp-5, - -0x1.3d91372d083f4p-5, 0x1.7f66cff331f4p-6, -0x1.606a562491737p-7, - 0x1.52e3e17c71069p-9}, - {0x1.55534a879232ap-2, -0x1.c69b836998b84p-4, 0x1.f2bb26dac0e4cp-5, - -0x1.359eed43716d7p-5, 0x1.64218cd824fbcp-6, -0x1.2e703e2e091e8p-7, - 0x1.0677d9af6aad4p-9}, - {0x1.5551836bb5494p-2, -0x1.c64658c15353bp-4, 0x1.ef68517451a6ep-5, - -0x1.2cc20a980dceep-5, 0x1.49843e0fad93ap-6, -0x1.03c59ccb68e54p-7, - 0x1.9ad325dc7adcbp-10}, - {0x1.554ecacb0d035p-2, -0x1.c5d2664026ffcp-4, 0x1.eb624796ba809p-5, - -0x1.233803d19a535p-5, 0x1.300decb1c3c28p-6, -0x1.befe18031ec3dp-8, - 0x1.449f5ee175c69p-10}, - {0x1.554ae1f5ae815p-2, -0x1.c53c6b14ff6b2p-4, 0x1.e6b2d5127bb5bp-5, - -0x1.19387336788a3p-5, 0x1.180955a6ab255p-6, -0x1.81696703ba369p-8, - 0x1.02cb36389bd79p-10}, - {0x1.55458a59f356ep-2, -0x1.c4820dd631ae9p-4, 0x1.e167af818bd15p-5, - -0x1.0ef35f6f72e52p-5, 0x1.019c33b65e4ebp-6, -0x1.4d25bdd52d3a5p-8, - 0x1.a008ae91f5936p-11}, - {0x1.553e878eafee1p-2, -0x1.c3a1d0b2a3db2p-4, 0x1.db90d8ed9f89bp-5, - -0x1.0490e20f1ae91p-5, 0x1.d9a5d1fc42fe3p-7, -0x1.20bf8227c2abfp-8, - 0x1.50f8174cdb6e9p-11}, - {0x1.5535a0dedf1b1p-2, -0x1.c29afb8bd01a1p-4, 0x1.d53f6371c1e27p-5, - -0x1.f463209b433e2p-6, 0x1.b35222a17e44p-7, -0x1.f5efbf505e133p-9, - 0x1.12e0e94e8586dp-11}, - {0x1.552aa25e57bfdp-2, -0x1.c16d811e4acadp-4, 0x1.ce8489b47aa51p-5, - -0x1.dfde7ff758ea8p-6, 0x1.901f43aac38c8p-7, -0x1.b581d07df5ad5p-9, - 0x1.c3726535f1fc6p-12}, - {0x1.551d5d9b204d3p-2, -0x1.c019e328f8db1p-4, 0x1.c7710f44fc3cep-5, - -0x1.cbbbe25ea8ba4p-6, 0x1.6fe270088623dp-7, -0x1.7e6fc79733761p-9, - 0x1.75077abf18d84p-12}, -}; - -} // anonymous namespace - -LLVM_LIBC_FUNCTION(float, cbrtf, (float x)) { - using FloatBits = typename fputil::FPBits<float>; - using DoubleBits = typename fputil::FPBits<double>; - - FloatBits x_bits(x); - - uint32_t x_abs = x_bits.uintval() & 0x7fff'ffff; - uint32_t sign_bit = (x_bits.uintval() >> 31) << DoubleBits::EXP_LEN; - - if (LIBC_UNLIKELY(x == 0.0f || x_abs >= 0x7f80'0000)) { - // x is 0, Inf, or NaN. - // Make sure it works for FTZ/DAZ modes. - return x + x; - } - - double xd = static_cast<double>(x); - DoubleBits xd_bits(xd); - - // When using biased exponent of x in double precision, - // x_e = real_exponent_of_x + 1023 - // Then: - // x_e / 3 = real_exponent_of_x / 3 + 1023/3 - // = real_exponent_of_x / 3 + 341 - // So to make it the correct biased exponent of x^(1/3), we add - // 1023 - 341 = 682 - // to the quotient x_e / 3. - unsigned x_e = static_cast<unsigned>(xd_bits.get_biased_exponent()); - unsigned out_e = (x_e / 3 + 682) | sign_bit; - unsigned shift_e = x_e % 3; - - // Set x_m = 2^(x_e % 3) * (1.mantissa) - uint64_t x_m = xd_bits.get_mantissa(); - // Use the leading 4 bits for look up table - unsigned idx = static_cast<unsigned>(x_m >> (DoubleBits::FRACTION_LEN - 4)); - - x_m |= static_cast<uint64_t>(DoubleBits::EXP_BIAS) - << DoubleBits::FRACTION_LEN; - - double x_reduced = DoubleBits(x_m).get_val(); - double dx = x_reduced - 1.0; - - double dx_sq = dx * dx; - double c0 = fputil::multiply_add(dx, COEFFS[idx][0], 1.0); - double c1 = fputil::multiply_add(dx, COEFFS[idx][2], COEFFS[idx][1]); - double c2 = fputil::multiply_add(dx, COEFFS[idx][4], COEFFS[idx][3]); - double c3 = fputil::multiply_add(dx, COEFFS[idx][6], COEFFS[idx][5]); - - double dx_4 = dx_sq * dx_sq; - double p0 = fputil::multiply_add(dx_sq, c1, c0); - double p1 = fputil::multiply_add(dx_sq, c3, c2); - - double r = fputil::multiply_add(dx_4, p1, p0) * CBRT2[shift_e]; - - uint64_t r_m = DoubleBits(r).get_mantissa(); - // Check if the output is exact. To be exact, the smallest 1-bit of the - // output has to be at least 2^-7 or higher. So we check the lowest 44 bits - // to see if they are within 2^(-52 + 3) errors from all zeros, then the - // result cube root is exact. - if (LIBC_UNLIKELY(((r_m + 8) & 0xfffffffffff) <= 16)) { - if ((r_m & 0xfffffffffff) <= 8) - r_m &= 0xffff'ffff'ffff'ffe0; - else - r_m = (r_m & 0xffff'ffff'ffff'ffe0) + 0x20; - fputil::clear_except_if_required(FE_INEXACT); - } - // Adjust exponent and sign. - uint64_t r_bits = - r_m | (static_cast<uint64_t>(out_e) << DoubleBits::FRACTION_LEN); - - return static_cast<float>(DoubleBits(r_bits).get_val()); -} +LLVM_LIBC_FUNCTION(float, cbrtf, (float x)) { return math::cbrtf(x); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/ceilbf16.cpp b/libc/src/math/generic/ceilbf16.cpp new file mode 100644 index 0000000..441dcf0 --- /dev/null +++ b/libc/src/math/generic/ceilbf16.cpp @@ -0,0 +1,19 @@ +//===-- Implementation of ceilbf16 function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/ceilbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, ceilbf16, (bfloat16 x)) { return fputil::ceil(x); } + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/copysignbf16.cpp b/libc/src/math/generic/copysignbf16.cpp new file mode 100644 index 0000000..48ade2b --- /dev/null +++ b/libc/src/math/generic/copysignbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of copysignbf16 function ---------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/copysignbf16.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, copysignbf16, (bfloat16 x, bfloat16 y)) { + return fputil::copysign(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/cos.cpp b/libc/src/math/generic/cos.cpp index 5da0f868..aabf3bc 100644 --- a/libc/src/math/generic/cos.cpp +++ b/libc/src/math/generic/cos.cpp @@ -7,161 +7,10 @@ //===----------------------------------------------------------------------===// #include "src/math/cos.h" -#include "hdr/errno_macros.h" -#include "src/__support/FPUtil/FEnvImpl.h" -#include "src/__support/FPUtil/FPBits.h" -#include "src/__support/FPUtil/double_double.h" -#include "src/__support/FPUtil/dyadic_float.h" -#include "src/__support/FPUtil/except_value_utils.h" -#include "src/__support/common.h" -#include "src/__support/macros/config.h" -#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY -#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA -#include "src/math/generic/range_reduction_double_common.h" -#include "src/math/generic/sincos_eval.h" - -#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE -#include "range_reduction_double_fma.h" -#else -#include "range_reduction_double_nofma.h" -#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE +#include "src/__support/math/cos.h" namespace LIBC_NAMESPACE_DECL { -using DoubleDouble = fputil::DoubleDouble; -using Float128 = typename fputil::DyadicFloat<128>; - -LLVM_LIBC_FUNCTION(double, cos, (double x)) { - using FPBits = typename fputil::FPBits<double>; - FPBits xbits(x); - - uint16_t x_e = xbits.get_biased_exponent(); - - DoubleDouble y; - unsigned k; - LargeRangeReduction range_reduction_large{}; - - // |x| < 2^16. - if (LIBC_LIKELY(x_e < FPBits::EXP_BIAS + FAST_PASS_EXPONENT)) { - // |x| < 2^-7 - if (LIBC_UNLIKELY(x_e < FPBits::EXP_BIAS - 7)) { - // |x| < 2^-27 - if (LIBC_UNLIKELY(x_e < FPBits::EXP_BIAS - 27)) { - // Signed zeros. - if (LIBC_UNLIKELY(x == 0.0)) - return 1.0; - - // For |x| < 2^-27, |cos(x) - 1| < |x|^2/2 < 2^-54 = ulp(1 - 2^-53)/2. - return fputil::round_result_slightly_down(1.0); - } - // No range reduction needed. - k = 0; - y.lo = 0.0; - y.hi = x; - } else { - // Small range reduction. - k = range_reduction_small(x, y); - } - } else { - // Inf or NaN - if (LIBC_UNLIKELY(x_e > 2 * FPBits::EXP_BIAS)) { - if (xbits.is_signaling_nan()) { - fputil::raise_except_if_required(FE_INVALID); - return FPBits::quiet_nan().get_val(); - } - // cos(+-Inf) = NaN - if (xbits.get_mantissa() == 0) { - fputil::set_errno_if_required(EDOM); - fputil::raise_except_if_required(FE_INVALID); - } - return x + FPBits::quiet_nan().get_val(); - } - - // Large range reduction. - k = range_reduction_large.fast(x, y); - } - - DoubleDouble sin_y, cos_y; - - [[maybe_unused]] double err = generic::sincos_eval(y, sin_y, cos_y); - - // Look up sin(k * pi/128) and cos(k * pi/128) -#ifdef LIBC_MATH_HAS_SMALL_TABLES - // Memory saving versions. Use 65-entry table. - auto get_idx_dd = [](unsigned kk) -> DoubleDouble { - unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63); - DoubleDouble ans = SIN_K_PI_OVER_128[idx]; - if (kk & 128) { - ans.hi = -ans.hi; - ans.lo = -ans.lo; - } - return ans; - }; - DoubleDouble msin_k = get_idx_dd(k + 128); - DoubleDouble cos_k = get_idx_dd(k + 64); -#else - // Fast look up version, but needs 256-entry table. - // -sin(k * pi/128) = sin((k + 128) * pi/128) - // cos(k * pi/128) = sin(k * pi/128 + pi/2) = sin((k + 64) * pi/128). - DoubleDouble msin_k = SIN_K_PI_OVER_128[(k + 128) & 255]; - DoubleDouble cos_k = SIN_K_PI_OVER_128[(k + 64) & 255]; -#endif // LIBC_MATH_HAS_SMALL_TABLES - - // After range reduction, k = round(x * 128 / pi) and y = x - k * (pi / 128). - // So k is an integer and -pi / 256 <= y <= pi / 256. - // Then cos(x) = cos((k * pi/128 + y) - // = cos(y) * cos(k*pi/128) - sin(y) * sin(k*pi/128) - DoubleDouble cos_k_cos_y = fputil::quick_mult(cos_y, cos_k); - DoubleDouble msin_k_sin_y = fputil::quick_mult(sin_y, msin_k); - - DoubleDouble rr = fputil::exact_add<false>(cos_k_cos_y.hi, msin_k_sin_y.hi); - rr.lo += msin_k_sin_y.lo + cos_k_cos_y.lo; - -#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS - return rr.hi + rr.lo; -#else - - double rlp = rr.lo + err; - double rlm = rr.lo - err; - - double r_upper = rr.hi + rlp; // (rr.lo + ERR); - double r_lower = rr.hi + rlm; // (rr.lo - ERR); - - // Ziv's rounding test. - if (LIBC_LIKELY(r_upper == r_lower)) - return r_upper; - - Float128 u_f128, sin_u, cos_u; - if (LIBC_LIKELY(x_e < FPBits::EXP_BIAS + FAST_PASS_EXPONENT)) - u_f128 = range_reduction_small_f128(x); - else - u_f128 = range_reduction_large.accurate(); - - generic::sincos_eval(u_f128, sin_u, cos_u); - - auto get_sin_k = [](unsigned kk) -> Float128 { - unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63); - Float128 ans = SIN_K_PI_OVER_128_F128[idx]; - if (kk & 128) - ans.sign = Sign::NEG; - return ans; - }; - - // -sin(k * pi/128) = sin((k + 128) * pi/128) - // cos(k * pi/128) = sin(k * pi/128 + pi/2) = sin((k + 64) * pi/128). - Float128 msin_k_f128 = get_sin_k(k + 128); - Float128 cos_k_f128 = get_sin_k(k + 64); - - // cos(x) = cos((k * pi/128 + u) - // = cos(u) * cos(k*pi/128) - sin(u) * sin(k*pi/128) - Float128 r = fputil::quick_add(fputil::quick_mul(cos_k_f128, cos_u), - fputil::quick_mul(msin_k_f128, sin_u)); - - // TODO: Add assertion if Ziv's accuracy tests fail in debug mode. - // https://github.com/llvm/llvm-project/issues/96452. - - return static_cast<double>(r); -#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS -} +LLVM_LIBC_FUNCTION(double, cos, (double x)) { return math::cos(x); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/cosf.cpp b/libc/src/math/generic/cosf.cpp index 7cdae09..5c23d99 100644 --- a/libc/src/math/generic/cosf.cpp +++ b/libc/src/math/generic/cosf.cpp @@ -7,139 +7,10 @@ //===----------------------------------------------------------------------===// #include "src/math/cosf.h" -#include "sincosf_utils.h" -#include "src/__support/FPUtil/BasicOperations.h" -#include "src/__support/FPUtil/FEnvImpl.h" -#include "src/__support/FPUtil/FPBits.h" -#include "src/__support/FPUtil/except_value_utils.h" -#include "src/__support/FPUtil/multiply_add.h" -#include "src/__support/common.h" -#include "src/__support/macros/config.h" -#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY -#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA +#include "src/__support/math/cosf.h" namespace LIBC_NAMESPACE_DECL { -#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS -// Exceptional cases for cosf. -static constexpr size_t N_EXCEPTS = 6; - -static constexpr fputil::ExceptValues<float, N_EXCEPTS> COSF_EXCEPTS{{ - // (inputs, RZ output, RU offset, RD offset, RN offset) - // x = 0x1.64a032p43, cos(x) = 0x1.9d4ba4p-1 (RZ) - {0x55325019, 0x3f4ea5d2, 1, 0, 0}, - // x = 0x1.4555p51, cos(x) = 0x1.115d7cp-1 (RZ) - {0x5922aa80, 0x3f08aebe, 1, 0, 1}, - // x = 0x1.48a858p54, cos(x) = 0x1.f48148p-2 (RZ) - {0x5aa4542c, 0x3efa40a4, 1, 0, 0}, - // x = 0x1.3170fp63, cos(x) = 0x1.fe2976p-1 (RZ) - {0x5f18b878, 0x3f7f14bb, 1, 0, 0}, - // x = 0x1.2b9622p67, cos(x) = 0x1.f0285cp-1 (RZ) - {0x6115cb11, 0x3f78142e, 1, 0, 1}, - // x = 0x1.ddebdep120, cos(x) = 0x1.114438p-1 (RZ) - {0x7beef5ef, 0x3f08a21c, 1, 0, 0}, -}}; -#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS - -LLVM_LIBC_FUNCTION(float, cosf, (float x)) { - using FPBits = typename fputil::FPBits<float>; - - FPBits xbits(x); - xbits.set_sign(Sign::POS); - - uint32_t x_abs = xbits.uintval(); - double xd = static_cast<double>(xbits.get_val()); - - // Range reduction: - // For |x| > pi/16, we perform range reduction as follows: - // Find k and y such that: - // x = (k + y) * pi/32 - // k is an integer - // |y| < 0.5 - // For small range (|x| < 2^45 when FMA instructions are available, 2^22 - // otherwise), this is done by performing: - // k = round(x * 32/pi) - // y = x * 32/pi - k - // For large range, we will omit all the higher parts of 16/pi such that the - // least significant bits of their full products with x are larger than 63, - // since cos((k + y + 64*i) * pi/32) = cos(x + i * 2pi) = cos(x). - // - // When FMA instructions are not available, we store the digits of 32/pi in - // chunks of 28-bit precision. This will make sure that the products: - // x * THIRTYTWO_OVER_PI_28[i] are all exact. - // When FMA instructions are available, we simply store the digits of 32/pi in - // chunks of doubles (53-bit of precision). - // So when multiplying by the largest values of single precision, the - // resulting output should be correct up to 2^(-208 + 128) ~ 2^-80. By the - // worst-case analysis of range reduction, |y| >= 2^-38, so this should give - // us more than 40 bits of accuracy. For the worst-case estimation of range - // reduction, see for instances: - // Elementary Functions by J-M. Muller, Chapter 11, - // Handbook of Floating-Point Arithmetic by J-M. Muller et. al., - // Chapter 10.2. - // - // Once k and y are computed, we then deduce the answer by the cosine of sum - // formula: - // cos(x) = cos((k + y)*pi/32) - // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32) - // The values of sin(k*pi/32) and cos(k*pi/32) for k = 0..63 are precomputed - // and stored using a vector of 32 doubles. Sin(y*pi/32) and cos(y*pi/32) are - // computed using degree-7 and degree-6 minimax polynomials generated by - // Sollya respectively. - - // |x| < 0x1.0p-12f - if (LIBC_UNLIKELY(x_abs < 0x3980'0000U)) { - // When |x| < 2^-12, the relative error of the approximation cos(x) ~ 1 - // is: - // |cos(x) - 1| < |x^2 / 2| = 2^-25 < epsilon(1)/2. - // So the correctly rounded values of cos(x) are: - // = 1 - eps(x) if rounding mode = FE_TOWARDZERO or FE_DOWWARD, - // = 1 otherwise. - // To simplify the rounding decision and make it more efficient and to - // prevent compiler to perform constant folding, we use - // fma(x, -2^-25, 1) instead. - // Note: to use the formula 1 - 2^-25*x to decide the correct rounding, we - // do need fma(x, -2^-25, 1) to prevent underflow caused by -2^-25*x when - // |x| < 2^-125. For targets without FMA instructions, we simply use - // double for intermediate results as it is more efficient than using an - // emulated version of FMA. -#if defined(LIBC_TARGET_CPU_HAS_FMA_FLOAT) - return fputil::multiply_add(xbits.get_val(), -0x1.0p-25f, 1.0f); -#else - return static_cast<float>(fputil::multiply_add(xd, -0x1.0p-25, 1.0)); -#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT - } - -#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS - if (auto r = COSF_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value())) - return r.value(); -#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS - - // x is inf or nan. - if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) { - if (xbits.is_signaling_nan()) { - fputil::raise_except_if_required(FE_INVALID); - return FPBits::quiet_nan().get_val(); - } - - if (x_abs == 0x7f80'0000U) { - fputil::set_errno_if_required(EDOM); - fputil::raise_except_if_required(FE_INVALID); - } - return x + FPBits::quiet_nan().get_val(); - } - - // Combine the results with the sine of sum formula: - // cos(x) = cos((k + y)*pi/32) - // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32) - // = cosm1_y * cos_k + sin_y * sin_k - // = (cosm1_y * cos_k + cos_k) + sin_y * sin_k - double sin_k, cos_k, sin_y, cosm1_y; - - sincosf_eval(xd, x_abs, sin_k, cos_k, sin_y, cosm1_y); - - return static_cast<float>(fputil::multiply_add( - sin_y, -sin_k, fputil::multiply_add(cosm1_y, cos_k, cos_k))); -} +LLVM_LIBC_FUNCTION(float, cosf, (float x)) { return math::cosf(x); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/cosf16.cpp b/libc/src/math/generic/cosf16.cpp index 99bb03e..031c3e1 100644 --- a/libc/src/math/generic/cosf16.cpp +++ b/libc/src/math/generic/cosf16.cpp @@ -7,87 +7,10 @@ //===----------------------------------------------------------------------===// #include "src/math/cosf16.h" -#include "hdr/errno_macros.h" -#include "hdr/fenv_macros.h" -#include "sincosf16_utils.h" -#include "src/__support/FPUtil/FEnvImpl.h" -#include "src/__support/FPUtil/FPBits.h" -#include "src/__support/FPUtil/cast.h" -#include "src/__support/FPUtil/except_value_utils.h" -#include "src/__support/FPUtil/multiply_add.h" -#include "src/__support/macros/optimization.h" +#include "src/__support/math/cosf16.h" namespace LIBC_NAMESPACE_DECL { -#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS -constexpr size_t N_EXCEPTS = 4; - -constexpr fputil::ExceptValues<float16, N_EXCEPTS> COSF16_EXCEPTS{{ - // (input, RZ output, RU offset, RD offset, RN offset) - {0x2b7c, 0x3bfc, 1, 0, 1}, - {0x4ac1, 0x38b5, 1, 0, 0}, - {0x5c49, 0xb8c6, 0, 1, 0}, - {0x7acc, 0xa474, 0, 1, 0}, -}}; -#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS - -LLVM_LIBC_FUNCTION(float16, cosf16, (float16 x)) { - using FPBits = fputil::FPBits<float16>; - FPBits xbits(x); - - uint16_t x_u = xbits.uintval(); - uint16_t x_abs = x_u & 0x7fff; - float xf = x; - - // Range reduction: - // For |x| > pi/32, we perform range reduction as follows: - // Find k and y such that: - // x = (k + y) * pi/32 - // k is an integer, |y| < 0.5 - // - // This is done by performing: - // k = round(x * 32/pi) - // y = x * 32/pi - k - // - // Once k and y are computed, we then deduce the answer by the cosine of sum - // formula: - // cos(x) = cos((k + y) * pi/32) - // = cos(k * pi/32) * cos(y * pi/32) - - // sin(k * pi/32) * sin(y * pi/32) - -#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS - // Handle exceptional values - if (auto r = COSF16_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value())) - return r.value(); -#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS - - // cos(+/-0) = 1 - if (LIBC_UNLIKELY(x_abs == 0U)) - return fputil::cast<float16>(1.0f); - - // cos(+/-inf) = NaN, and cos(NaN) = NaN - if (xbits.is_inf_or_nan()) { - if (xbits.is_signaling_nan()) { - fputil::raise_except_if_required(FE_INVALID); - return FPBits::quiet_nan().get_val(); - } - - if (xbits.is_inf()) { - fputil::set_errno_if_required(EDOM); - fputil::raise_except_if_required(FE_INVALID); - } - - return x + FPBits::quiet_nan().get_val(); - } - - float sin_k, cos_k, sin_y, cosm1_y; - sincosf16_eval(xf, sin_k, cos_k, sin_y, cosm1_y); - // Since, cosm1_y = cos_y - 1, therefore: - // cos(x) = cos_k * cos_y - sin_k * sin_y - // = cos_k * (cos_y - 1 + 1) - sin_k * sin_y - // = cos_k * cosm1_y - sin_k * sin_y + cos_k - return fputil::cast<float16>(fputil::multiply_add( - cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k))); -} +LLVM_LIBC_FUNCTION(float16, cosf16, (float16 x)) { return math::cosf16(x); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/coshf.cpp b/libc/src/math/generic/coshf.cpp index 9f87564..368c0fd 100644 --- a/libc/src/math/generic/coshf.cpp +++ b/libc/src/math/generic/coshf.cpp @@ -7,50 +7,10 @@ //===----------------------------------------------------------------------===// #include "src/math/coshf.h" -#include "src/__support/FPUtil/FEnvImpl.h" -#include "src/__support/FPUtil/FPBits.h" -#include "src/__support/FPUtil/rounding_mode.h" -#include "src/__support/macros/config.h" -#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY -#include "src/math/generic/explogxf.h" +#include "src/__support/math/coshf.h" namespace LIBC_NAMESPACE_DECL { -LLVM_LIBC_FUNCTION(float, coshf, (float x)) { - using FPBits = typename fputil::FPBits<float>; - - FPBits xbits(x); - xbits.set_sign(Sign::POS); - x = xbits.get_val(); - - uint32_t x_u = xbits.uintval(); - - // When |x| >= 90, or x is inf or nan - if (LIBC_UNLIKELY(x_u >= 0x42b4'0000U || x_u <= 0x3280'0000U)) { - // |x| <= 2^-26 - if (x_u <= 0x3280'0000U) { - return 1.0f + x; - } - - if (xbits.is_inf_or_nan()) - return x + FPBits::inf().get_val(); - - int rounding = fputil::quick_get_round(); - if (LIBC_UNLIKELY(rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)) - return FPBits::max_normal().get_val(); - - fputil::set_errno_if_required(ERANGE); - fputil::raise_except_if_required(FE_OVERFLOW); - - return x + FPBits::inf().get_val(); - } - - // TODO: We should be able to reduce the latency and reciprocal throughput - // further by using a low degree (maybe 3-7 ?) minimax polynomial for small - // but not too small inputs, such as |x| < 2^-2, or |x| < 2^-3. - - // cosh(x) = (e^x + e^(-x)) / 2. - return static_cast<float>(exp_pm_eval</*is_sinh*/ false>(x)); -} +LLVM_LIBC_FUNCTION(float, coshf, (float x)) { return math::coshf(x); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/coshf16.cpp b/libc/src/math/generic/coshf16.cpp index 689d16a..d86edd9 100644 --- a/libc/src/math/generic/coshf16.cpp +++ b/libc/src/math/generic/coshf16.cpp @@ -7,105 +7,10 @@ //===----------------------------------------------------------------------===// #include "src/math/coshf16.h" -#include "expxf16.h" -#include "hdr/errno_macros.h" -#include "hdr/fenv_macros.h" -#include "src/__support/FPUtil/FEnvImpl.h" -#include "src/__support/FPUtil/FPBits.h" -#include "src/__support/FPUtil/except_value_utils.h" -#include "src/__support/FPUtil/rounding_mode.h" -#include "src/__support/common.h" -#include "src/__support/macros/config.h" -#include "src/__support/macros/optimization.h" +#include "src/__support/math/coshf16.h" namespace LIBC_NAMESPACE_DECL { -#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS -static constexpr fputil::ExceptValues<float16, 9> COSHF16_EXCEPTS_POS = {{ - // x = 0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ) - {0x29a8U, 0x3c00U, 1U, 0U, 1U}, - // x = 0x1.8c4p+0, coshf16(x) = 0x1.3a8p+1 (RZ) - {0x3e31U, 0x40eaU, 1U, 0U, 0U}, - // x = 0x1.994p+0, coshf16(x) = 0x1.498p+1 (RZ) - {0x3e65U, 0x4126U, 1U, 0U, 0U}, - // x = 0x1.b6p+0, coshf16(x) = 0x1.6d8p+1 (RZ) - {0x3ed8U, 0x41b6U, 1U, 0U, 1U}, - // x = 0x1.aap+1, coshf16(x) = 0x1.be8p+3 (RZ) - {0x42a8U, 0x4afaU, 1U, 0U, 1U}, - // x = 0x1.cc4p+1, coshf16(x) = 0x1.23cp+4 (RZ) - {0x4331U, 0x4c8fU, 1U, 0U, 0U}, - // x = 0x1.288p+2, coshf16(x) = 0x1.9b4p+5 (RZ) - {0x44a2U, 0x526dU, 1U, 0U, 0U}, - // x = 0x1.958p+2, coshf16(x) = 0x1.1a4p+8 (RZ) - {0x4656U, 0x5c69U, 1U, 0U, 0U}, - // x = 0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ) - {0x497cU, 0x7715U, 1U, 0U, 1U}, -}}; - -static constexpr fputil::ExceptValues<float16, 6> COSHF16_EXCEPTS_NEG = {{ - // x = -0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ) - {0xa9a8U, 0x3c00U, 1U, 0U, 1U}, - // x = -0x1.b6p+0, coshf16(x) = 0x1.6d8p+1 (RZ) - {0xbed8U, 0x41b6U, 1U, 0U, 1U}, - // x = -0x1.288p+2, coshf16(x) = 0x1.9b4p+5 (RZ) - {0xc4a2U, 0x526dU, 1U, 0U, 0U}, - // x = -0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ) - {0xc97cU, 0x7715U, 1U, 0U, 1U}, - // x = -0x1.8c4p+0, coshf16(x) = 0x1.3a8p+1 (RZ) - {0xbe31U, 0x40eaU, 1U, 0U, 0U}, - // x = -0x1.994p+0, coshf16(x) = 0x1.498p+1 (RZ) - {0xbe65U, 0x4126U, 1U, 0U, 0U}, -}}; -#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS - -LLVM_LIBC_FUNCTION(float16, coshf16, (float16 x)) { - using FPBits = fputil::FPBits<float16>; - FPBits x_bits(x); - - uint16_t x_u = x_bits.uintval(); - uint16_t x_abs = x_u & 0x7fffU; - - // When |x| >= acosh(2^16), or x is NaN. - if (LIBC_UNLIKELY(x_abs >= 0x49e5U)) { - // cosh(NaN) = NaN - if (x_bits.is_nan()) { - if (x_bits.is_signaling_nan()) { - fputil::raise_except_if_required(FE_INVALID); - return FPBits::quiet_nan().get_val(); - } - - return x; - } - - // When |x| >= acosh(2^16). - if (x_abs >= 0x49e5U) { - // cosh(+/-inf) = +inf - if (x_bits.is_inf()) - return FPBits::inf().get_val(); - - switch (fputil::quick_get_round()) { - case FE_TONEAREST: - case FE_UPWARD: - fputil::set_errno_if_required(ERANGE); - fputil::raise_except_if_required(FE_OVERFLOW | FE_INEXACT); - return FPBits::inf().get_val(); - default: - return FPBits::max_normal().get_val(); - } - } - } - -#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS - if (x_bits.is_pos()) { - if (auto r = COSHF16_EXCEPTS_POS.lookup(x_u); LIBC_UNLIKELY(r.has_value())) - return r.value(); - } else { - if (auto r = COSHF16_EXCEPTS_NEG.lookup(x_u); LIBC_UNLIKELY(r.has_value())) - return r.value(); - } -#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS - - return eval_sinh_or_cosh</*IsSinh=*/false>(x); -} +LLVM_LIBC_FUNCTION(float16, coshf16, (float16 x)) { return math::coshf16(x); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/cospif.cpp b/libc/src/math/generic/cospif.cpp index 5b6880f..b9a4637 100644 --- a/libc/src/math/generic/cospif.cpp +++ b/libc/src/math/generic/cospif.cpp @@ -7,95 +7,10 @@ //===----------------------------------------------------------------------===// #include "src/math/cospif.h" -#include "sincosf_utils.h" -#include "src/__support/FPUtil/FEnvImpl.h" -#include "src/__support/FPUtil/FPBits.h" -#include "src/__support/FPUtil/multiply_add.h" -#include "src/__support/common.h" -#include "src/__support/macros/config.h" -#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY -#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA +#include "src/__support/math/cospif.h" namespace LIBC_NAMESPACE_DECL { -LLVM_LIBC_FUNCTION(float, cospif, (float x)) { - using FPBits = typename fputil::FPBits<float>; - - FPBits xbits(x); - xbits.set_sign(Sign::POS); - - uint32_t x_abs = xbits.uintval(); - double xd = static_cast<double>(xbits.get_val()); - - // Range reduction: - // For |x| > 1/32, we perform range reduction as follows: - // Find k and y such that: - // x = (k + y) * 1/32 - // k is an integer - // |y| < 0.5 - // - // This is done by performing: - // k = round(x * 32) - // y = x * 32 - k - // - // Once k and y are computed, we then deduce the answer by the cosine of sum - // formula: - // cospi(x) = cos((k + y)*pi/32) - // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32) - // The values of sin(k*pi/32) and cos(k*pi/32) for k = 0..63 are precomputed - // and stored using a vector of 32 doubles. Sin(y*pi/32) and cos(y*pi/32) are - // computed using degree-7 and degree-6 minimax polynomials generated by - // Sollya respectively. - - // The exhautive test passes for smaller values - if (LIBC_UNLIKELY(x_abs < 0x38A2'F984U)) { - -#if defined(LIBC_TARGET_CPU_HAS_FMA_FLOAT) - return fputil::multiply_add(xbits.get_val(), -0x1.0p-25f, 1.0f); -#else - return static_cast<float>(fputil::multiply_add(xd, -0x1.0p-25, 1.0)); -#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT - } - - // Numbers greater or equal to 2^23 are always integers or NaN - if (LIBC_UNLIKELY(x_abs >= 0x4B00'0000)) { - - if (LIBC_UNLIKELY(x_abs < 0x4B80'0000)) { - return (x_abs & 0x1) ? -1.0f : 1.0f; - } - - // x is inf or nan. - if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) { - if (xbits.is_signaling_nan()) { - fputil::raise_except_if_required(FE_INVALID); - return FPBits::quiet_nan().get_val(); - } - - if (x_abs == 0x7f80'0000U) { - fputil::set_errno_if_required(EDOM); - fputil::raise_except_if_required(FE_INVALID); - } - return x + FPBits::quiet_nan().get_val(); - } - - return 1.0f; - } - - // Combine the results with the sine of sum formula: - // cos(pi * x) = cos((k + y)*pi/32) - // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32) - // = (cosm1_y + 1) * cos_k - sin_y * sin_k - // = (cosm1_y * cos_k + cos_k) - sin_y * sin_k - double sin_k, cos_k, sin_y, cosm1_y; - - sincospif_eval(xd, sin_k, cos_k, sin_y, cosm1_y); - - if (LIBC_UNLIKELY(sin_y == 0 && cos_k == 0)) { - return 0.0f; - } - - return static_cast<float>(fputil::multiply_add( - sin_y, -sin_k, fputil::multiply_add(cosm1_y, cos_k, cos_k))); -} +LLVM_LIBC_FUNCTION(float, cospif, (float x)) { return math::cospif(x); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/cospif16.cpp b/libc/src/math/generic/cospif16.cpp index 9dc2592..a4bae8e 100644 --- a/libc/src/math/generic/cospif16.cpp +++ b/libc/src/math/generic/cospif16.cpp @@ -7,79 +7,10 @@ //===----------------------------------------------------------------------===// #include "src/math/cospif16.h" -#include "hdr/errno_macros.h" -#include "hdr/fenv_macros.h" -#include "sincosf16_utils.h" -#include "src/__support/FPUtil/FEnvImpl.h" -#include "src/__support/FPUtil/FPBits.h" -#include "src/__support/FPUtil/cast.h" -#include "src/__support/FPUtil/multiply_add.h" -#include "src/__support/macros/optimization.h" +#include "src/__support/math/cospif16.h" namespace LIBC_NAMESPACE_DECL { -LLVM_LIBC_FUNCTION(float16, cospif16, (float16 x)) { - using FPBits = typename fputil::FPBits<float16>; - FPBits xbits(x); - - uint16_t x_u = xbits.uintval(); - uint16_t x_abs = x_u & 0x7fff; - float xf = x; - - // Range reduction: - // For |x| > 1/32, we perform range reduction as follows: - // Find k and y such that: - // x = (k + y) * 1/32 - // k is an integer - // |y| < 0.5 - // - // This is done by performing: - // k = round(x * 32) - // y = x * 32 - k - // - // Once k and y are computed, we then deduce the answer by the cosine of sum - // formula: - // cos(x * pi) = cos((k + y) * pi/32) - // = cos(k * pi/32) * cos(y * pi/32) + - // sin(y * pi/32) * sin(k * pi/32) - - // For signed zeros - if (LIBC_UNLIKELY(x_abs == 0U)) - return fputil::cast<float16>(1.0f); - - // Numbers greater or equal to 2^10 are integers, or infinity, or NaN - if (LIBC_UNLIKELY(x_abs >= 0x6400)) { - if (LIBC_UNLIKELY(x_abs <= 0x67FF)) - return fputil::cast<float16>((x_abs & 0x1) ? -1.0f : 1.0f); - - // Check for NaN or infintiy values - if (LIBC_UNLIKELY(x_abs >= 0x7c00)) { - if (xbits.is_signaling_nan()) { - fputil::raise_except_if_required(FE_INVALID); - return FPBits::quiet_nan().get_val(); - } - // If value is equal to infinity - if (x_abs == 0x7c00) { - fputil::set_errno_if_required(EDOM); - fputil::raise_except_if_required(FE_INVALID); - } - - return x + FPBits::quiet_nan().get_val(); - } - - return fputil::cast<float16>(1.0f); - } - - float sin_k, cos_k, sin_y, cosm1_y; - sincospif16_eval(xf, sin_k, cos_k, sin_y, cosm1_y); - - if (LIBC_UNLIKELY(sin_y == 0 && cos_k == 0)) - return fputil::cast<float16>(0.0f); - - // Since, cosm1_y = cos_y - 1, therefore: - // cos(x * pi) = cos_k(cosm1_y) + cos_k - sin_k * sin_y - return fputil::cast<float16>(fputil::multiply_add( - cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k))); -} +LLVM_LIBC_FUNCTION(float16, cospif16, (float16 x)) { return math::cospif16(x); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/exp10m1f.cpp b/libc/src/math/generic/exp10m1f.cpp index 2772910..8589e3f 100644 --- a/libc/src/math/generic/exp10m1f.cpp +++ b/libc/src/math/generic/exp10m1f.cpp @@ -17,8 +17,7 @@ #include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" - -#include "explogxf.h" +#include "src/__support/math/exp10f_utils.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/math/generic/exp2.cpp b/libc/src/math/generic/exp2.cpp index 726f88b..154154f 100644 --- a/libc/src/math/generic/exp2.cpp +++ b/libc/src/math/generic/exp2.cpp @@ -8,7 +8,6 @@ #include "src/math/exp2.h" #include "common_constants.h" // Lookup tables EXP2_MID1 and EXP_M2. -#include "explogxf.h" // ziv_test_denorm. #include "src/__support/CPP/bit.h" #include "src/__support/CPP/optional.h" #include "src/__support/FPUtil/FEnvImpl.h" @@ -24,6 +23,7 @@ #include "src/__support/integer_literals.h" #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY +#include "src/__support/math/exp_utils.h" // ziv_test_denorm. namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/math/generic/exp2f16.cpp b/libc/src/math/generic/exp2f16.cpp index 5c039c5..5db0c3a 100644 --- a/libc/src/math/generic/exp2f16.cpp +++ b/libc/src/math/generic/exp2f16.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/math/exp2f16.h" -#include "expxf16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" #include "src/__support/FPUtil/FEnvImpl.h" @@ -18,6 +17,7 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" +#include "src/__support/math/expxf16_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -34,6 +34,7 @@ static constexpr fputil::ExceptValues<float16, 3> EXP2F16_EXCEPTS = {{ #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS LLVM_LIBC_FUNCTION(float16, exp2f16, (float16 x)) { + using namespace math::expxf16_internal; using FPBits = fputil::FPBits<float16>; FPBits x_bits(x); diff --git a/libc/src/math/generic/exp2f_impl.h b/libc/src/math/generic/exp2f_impl.h index 5c6c2bd..b85bb15 100644 --- a/libc/src/math/generic/exp2f_impl.h +++ b/libc/src/math/generic/exp2f_impl.h @@ -20,8 +20,7 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/__support/macros/properties/cpu_features.h" - -#include "explogxf.h" +#include "src/__support/math/exp10f_utils.h" namespace LIBC_NAMESPACE_DECL { namespace generic { diff --git a/libc/src/math/generic/exp2m1f.cpp b/libc/src/math/generic/exp2m1f.cpp index 127c6ea..16244ed 100644 --- a/libc/src/math/generic/exp2m1f.cpp +++ b/libc/src/math/generic/exp2m1f.cpp @@ -18,8 +18,7 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" #include "src/__support/macros/properties/cpu_features.h" - -#include "explogxf.h" +#include "src/__support/math/exp10f_utils.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/math/generic/exp2m1f16.cpp b/libc/src/math/generic/exp2m1f16.cpp index 61633cd..ce0cc60 100644 --- a/libc/src/math/generic/exp2m1f16.cpp +++ b/libc/src/math/generic/exp2m1f16.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/math/exp2m1f16.h" -#include "expxf16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" #include "src/__support/FPUtil/FEnvImpl.h" @@ -21,6 +20,7 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" #include "src/__support/macros/properties/cpu_features.h" +#include "src/__support/math/expxf16_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -76,6 +76,7 @@ static constexpr fputil::ExceptValues<float16, N_EXP2M1F16_EXCEPTS_HI> #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS LLVM_LIBC_FUNCTION(float16, exp2m1f16, (float16 x)) { + using namespace math::expxf16_internal; using FPBits = fputil::FPBits<float16>; FPBits x_bits(x); diff --git a/libc/src/math/generic/expm1.cpp b/libc/src/math/generic/expm1.cpp index a4dbf38..c360554 100644 --- a/libc/src/math/generic/expm1.cpp +++ b/libc/src/math/generic/expm1.cpp @@ -8,9 +8,7 @@ #include "src/math/expm1.h" #include "common_constants.h" // Lookup tables EXP_M1 and EXP_M2. -#include "explogxf.h" // ziv_test_denorm. #include "src/__support/CPP/bit.h" -#include "src/__support/CPP/optional.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/PolyEval.h" @@ -18,7 +16,6 @@ #include "src/__support/FPUtil/dyadic_float.h" #include "src/__support/FPUtil/except_value_utils.h" #include "src/__support/FPUtil/multiply_add.h" -#include "src/__support/FPUtil/nearest_integer.h" #include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/FPUtil/triple_double.h" #include "src/__support/common.h" diff --git a/libc/src/math/generic/expm1f16.cpp b/libc/src/math/generic/expm1f16.cpp index 2188dfb..c2231f0 100644 --- a/libc/src/math/generic/expm1f16.cpp +++ b/libc/src/math/generic/expm1f16.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/math/expm1f16.h" -#include "expxf16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" #include "src/__support/FPUtil/FEnvImpl.h" @@ -20,6 +19,7 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" +#include "src/__support/math/expxf16_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -51,6 +51,7 @@ static constexpr fputil::ExceptValues<float16, N_EXPM1F16_EXCEPTS_HI> #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS LLVM_LIBC_FUNCTION(float16, expm1f16, (float16 x)) { + using namespace math::expxf16_internal; using FPBits = fputil::FPBits<float16>; FPBits x_bits(x); diff --git a/libc/src/math/generic/fdimbf16.cpp b/libc/src/math/generic/fdimbf16.cpp new file mode 100644 index 0000000..0f54055 --- /dev/null +++ b/libc/src/math/generic/fdimbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of fdimbf16 function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/fdimbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, fdimbf16, (bfloat16 x, bfloat16 y)) { + return fputil::fdim(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/floorbf16.cpp b/libc/src/math/generic/floorbf16.cpp new file mode 100644 index 0000000..d157096 --- /dev/null +++ b/libc/src/math/generic/floorbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of floorbf16 function ------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/floorbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, floorbf16, (bfloat16 x)) { + return fputil::floor(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/fmaxbf16.cpp b/libc/src/math/generic/fmaxbf16.cpp new file mode 100644 index 0000000..01d395b --- /dev/null +++ b/libc/src/math/generic/fmaxbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of fmaxbf16 function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/fmaxbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, fmaxbf16, (bfloat16 x, bfloat16 y)) { + return fputil::fmax(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/fmaximum_mag_numbf16.cpp b/libc/src/math/generic/fmaximum_mag_numbf16.cpp new file mode 100644 index 0000000..485e3295 --- /dev/null +++ b/libc/src/math/generic/fmaximum_mag_numbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of fmaximum_mag_numbf16 function -------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/fmaximum_mag_numbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, fmaximum_mag_numbf16, (bfloat16 x, bfloat16 y)) { + return fputil::fmaximum_mag_num(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/fmaximum_magbf16.cpp b/libc/src/math/generic/fmaximum_magbf16.cpp new file mode 100644 index 0000000..0654ed9 --- /dev/null +++ b/libc/src/math/generic/fmaximum_magbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of fmaximum_magbf16 function -----------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/fmaximum_magbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, fmaximum_magbf16, (bfloat16 x, bfloat16 y)) { + return fputil::fmaximum_mag(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/fmaximum_numbf16.cpp b/libc/src/math/generic/fmaximum_numbf16.cpp new file mode 100644 index 0000000..b058d50 --- /dev/null +++ b/libc/src/math/generic/fmaximum_numbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of fmaximum_numbf16 function -----------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/fmaximum_numbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, fmaximum_numbf16, (bfloat16 x, bfloat16 y)) { + return fputil::fmaximum_num(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/fmaximumbf16.cpp b/libc/src/math/generic/fmaximumbf16.cpp new file mode 100644 index 0000000..e10830b --- /dev/null +++ b/libc/src/math/generic/fmaximumbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of fmaximumbf16 function ---------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/fmaximumbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, fmaximumbf16, (bfloat16 x, bfloat16 y)) { + return fputil::fmaximum(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/fminbf16.cpp b/libc/src/math/generic/fminbf16.cpp new file mode 100644 index 0000000..c3e29ee --- /dev/null +++ b/libc/src/math/generic/fminbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of fminbf16 function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/fminbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, fminbf16, (bfloat16 x, bfloat16 y)) { + return fputil::fmin(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/fminimum_mag_numbf16.cpp b/libc/src/math/generic/fminimum_mag_numbf16.cpp new file mode 100644 index 0000000..5056fc7 --- /dev/null +++ b/libc/src/math/generic/fminimum_mag_numbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of fminimum_mag_numbf16 function -------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/fminimum_mag_numbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, fminimum_mag_numbf16, (bfloat16 x, bfloat16 y)) { + return fputil::fminimum_mag_num(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/fminimum_magbf16.cpp b/libc/src/math/generic/fminimum_magbf16.cpp new file mode 100644 index 0000000..f61d2d2 --- /dev/null +++ b/libc/src/math/generic/fminimum_magbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of fminimum_magbf16 function -----------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/fminimum_magbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, fminimum_magbf16, (bfloat16 x, bfloat16 y)) { + return fputil::fminimum_mag(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/fminimum_numbf16.cpp b/libc/src/math/generic/fminimum_numbf16.cpp new file mode 100644 index 0000000..079a830 --- /dev/null +++ b/libc/src/math/generic/fminimum_numbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of fminimum_numbf16 function -----------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/fminimum_numbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, fminimum_numbf16, (bfloat16 x, bfloat16 y)) { + return fputil::fminimum_num(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/fminimumbf16.cpp b/libc/src/math/generic/fminimumbf16.cpp new file mode 100644 index 0000000..da976b9 --- /dev/null +++ b/libc/src/math/generic/fminimumbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of fminimumbf16 function ---------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/fminimumbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, fminimumbf16, (bfloat16 x, bfloat16 y)) { + return fputil::fminimum(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/fmodbf16.cpp b/libc/src/math/generic/fmodbf16.cpp new file mode 100644 index 0000000..902a680 --- /dev/null +++ b/libc/src/math/generic/fmodbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of fmodbf16 function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/fmodbf16.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/FPUtil/generic/FMod.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, fmodbf16, (bfloat16 x, bfloat16 y)) { + return fputil::generic::FMod<bfloat16>::eval(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/frexpbf16.cpp b/libc/src/math/generic/frexpbf16.cpp new file mode 100644 index 0000000..004f64f --- /dev/null +++ b/libc/src/math/generic/frexpbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of frexpbf16 function ------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/frexpbf16.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, frexpbf16, (bfloat16 x, int *exp)) { + return fputil::frexp(x, *exp); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/fromfpbf16.cpp b/libc/src/math/generic/fromfpbf16.cpp new file mode 100644 index 0000000..db1b8f1 --- /dev/null +++ b/libc/src/math/generic/fromfpbf16.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of fromfpbf16 function -----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/fromfpbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, fromfpbf16, + (bfloat16 x, int rnd, unsigned int width)) { + return fputil::fromfp</*IsSigned=*/true>(x, rnd, width); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/fromfpxbf16.cpp b/libc/src/math/generic/fromfpxbf16.cpp new file mode 100644 index 0000000..8c16c41 --- /dev/null +++ b/libc/src/math/generic/fromfpxbf16.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of fromfpxbf16 function ----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/fromfpxbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, fromfpxbf16, + (bfloat16 x, int rnd, unsigned int width)) { + return fputil::fromfpx</*IsSigned=*/true>(x, rnd, width); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/getpayloadbf16.cpp b/libc/src/math/generic/getpayloadbf16.cpp new file mode 100644 index 0000000..544ed0a --- /dev/null +++ b/libc/src/math/generic/getpayloadbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of getpayloadbf16 function -------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/getpayloadbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, getpayloadbf16, (const bfloat16 *x)) { + return fputil::getpayload(*x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/hypotf16.cpp b/libc/src/math/generic/hypotf16.cpp index d782c26..fa90069 100644 --- a/libc/src/math/generic/hypotf16.cpp +++ b/libc/src/math/generic/hypotf16.cpp @@ -48,16 +48,15 @@ LLVM_LIBC_FUNCTION(float16, hypotf16, (float16 x, float16 y)) { return a_bits.get_val(); } - // TODO: Investigate why replacing the return line below with: - // return x_bits.get_val() + y_bits.get_val(); - // fails the hypotf16 smoke tests. + float af = fputil::cast<float>(a_bits.get_val()); + float bf = fputil::cast<float>(b_bits.get_val()); + + // Compiler runtime basic operations for float16 might not be correctly + // rounded for all rounding modes. if (LIBC_UNLIKELY(a_u - b_u >= static_cast<uint16_t>((FPBits::FRACTION_LEN + 2) << FPBits::FRACTION_LEN))) - return a_bits.get_val() + b_bits.get_val(); - - float af = fputil::cast<float>(a_bits.get_val()); - float bf = fputil::cast<float>(b_bits.get_val()); + return fputil::cast<float16>(af + bf); // These squares are exact. float a_sq = af * af; diff --git a/libc/src/math/generic/ilogbbf16.cpp b/libc/src/math/generic/ilogbbf16.cpp new file mode 100644 index 0000000..6811139 --- /dev/null +++ b/libc/src/math/generic/ilogbbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of ilogbbf16 function ------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/ilogbbf16.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, ilogbbf16, (bfloat16 x)) { + return fputil::intlogb<int>(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/iscanonicalbf16.cpp b/libc/src/math/generic/iscanonicalbf16.cpp new file mode 100644 index 0000000..34c11bf --- /dev/null +++ b/libc/src/math/generic/iscanonicalbf16.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of iscanonicalbf16 function ------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/iscanonicalbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, iscanonicalbf16, (bfloat16 x)) { + bfloat16 tmp; + return fputil::canonicalize(tmp, x) == 0; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/issignalingbf16.cpp b/libc/src/math/generic/issignalingbf16.cpp new file mode 100644 index 0000000..3bb17ef --- /dev/null +++ b/libc/src/math/generic/issignalingbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of issignalingbf16 function ------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/issignalingbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, issignalingbf16, (bfloat16 x)) { + return fputil::issignaling_impl(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/ldexpbf16.cpp b/libc/src/math/generic/ldexpbf16.cpp new file mode 100644 index 0000000..42a5039 --- /dev/null +++ b/libc/src/math/generic/ldexpbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of ldexpbf16 function ------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/ldexpbf16.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, ldexpbf16, (bfloat16 x, int exp)) { + return fputil::ldexp(x, exp); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/llogbbf16.cpp b/libc/src/math/generic/llogbbf16.cpp new file mode 100644 index 0000000..74c2762 --- /dev/null +++ b/libc/src/math/generic/llogbbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of llogbbf16 function ------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/llogbbf16.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(long, llogbbf16, (bfloat16 x)) { + return fputil::intlogb<long>(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/llrintbf16.cpp b/libc/src/math/generic/llrintbf16.cpp new file mode 100644 index 0000000..ec85454 --- /dev/null +++ b/libc/src/math/generic/llrintbf16.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of llrintbf16 function -----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/llrintbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(long long, llrintbf16, (bfloat16 x)) { + return fputil::round_to_signed_integer_using_current_rounding_mode<bfloat16, + long long>( + x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/llroundbf16.cpp b/libc/src/math/generic/llroundbf16.cpp new file mode 100644 index 0000000..2497b6b --- /dev/null +++ b/libc/src/math/generic/llroundbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of llroundbf16 function ----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/llroundbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(long long, llroundbf16, (bfloat16 x)) { + return fputil::round_to_signed_integer<bfloat16, long long>(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/log10f16.cpp b/libc/src/math/generic/log10f16.cpp index 2626af4..4bb684a 100644 --- a/libc/src/math/generic/log10f16.cpp +++ b/libc/src/math/generic/log10f16.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/math/log10f16.h" -#include "expxf16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" #include "src/__support/FPUtil/FEnvImpl.h" @@ -20,6 +19,7 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" #include "src/__support/macros/properties/cpu_features.h" +#include "src/__support/math/expxf16_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -75,6 +75,7 @@ static constexpr fputil::ExceptValues<float16, N_LOG10F16_EXCEPTS> #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS LLVM_LIBC_FUNCTION(float16, log10f16, (float16 x)) { + using namespace math::expxf16_internal; using FPBits = fputil::FPBits<float16>; FPBits x_bits(x); diff --git a/libc/src/math/generic/log2f16.cpp b/libc/src/math/generic/log2f16.cpp index 34be780..5b60323 100644 --- a/libc/src/math/generic/log2f16.cpp +++ b/libc/src/math/generic/log2f16.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/math/log2f16.h" -#include "expxf16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" #include "src/__support/FPUtil/FEnvImpl.h" @@ -20,6 +19,7 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" #include "src/__support/macros/properties/cpu_features.h" +#include "src/__support/math/expxf16_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -61,6 +61,7 @@ static constexpr fputil::ExceptValues<float16, N_LOG2F16_EXCEPTS> #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS LLVM_LIBC_FUNCTION(float16, log2f16, (float16 x)) { + using namespace math::expxf16_internal; using FPBits = fputil::FPBits<float16>; FPBits x_bits(x); diff --git a/libc/src/math/generic/logbbf16.cpp b/libc/src/math/generic/logbbf16.cpp new file mode 100644 index 0000000..5a43ddf --- /dev/null +++ b/libc/src/math/generic/logbbf16.cpp @@ -0,0 +1,19 @@ +//===-- Implementation of logbbf16 function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/logbbf16.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, logbbf16, (bfloat16 x)) { return fputil::logb(x); } + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/logf16.cpp b/libc/src/math/generic/logf16.cpp index 8e0d7d8..22e0dc8 100644 --- a/libc/src/math/generic/logf16.cpp +++ b/libc/src/math/generic/logf16.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/math/logf16.h" -#include "expxf16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" #include "src/__support/FPUtil/FEnvImpl.h" @@ -20,6 +19,7 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" #include "src/__support/macros/properties/cpu_features.h" +#include "src/__support/math/expxf16_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -68,6 +68,7 @@ static constexpr fputil::ExceptValues<float16, N_LOGF16_EXCEPTS> #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS LLVM_LIBC_FUNCTION(float16, logf16, (float16 x)) { + using namespace math::expxf16_internal; using FPBits = fputil::FPBits<float16>; FPBits x_bits(x); diff --git a/libc/src/math/generic/lrintbf16.cpp b/libc/src/math/generic/lrintbf16.cpp new file mode 100644 index 0000000..4b37890 --- /dev/null +++ b/libc/src/math/generic/lrintbf16.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of lrintbf16 function ------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/lrintbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(long, lrintbf16, (bfloat16 x)) { + return fputil::round_to_signed_integer_using_current_rounding_mode<bfloat16, + long>(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/lroundbf16.cpp b/libc/src/math/generic/lroundbf16.cpp new file mode 100644 index 0000000..89095d17 --- /dev/null +++ b/libc/src/math/generic/lroundbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of lroundbf16 function -----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/lroundbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(long, lroundbf16, (bfloat16 x)) { + return fputil::round_to_signed_integer<bfloat16, long>(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/modfbf16.cpp b/libc/src/math/generic/modfbf16.cpp new file mode 100644 index 0000000..09458f6 --- /dev/null +++ b/libc/src/math/generic/modfbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of modfbf16 function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/modfbf16.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, modfbf16, (bfloat16 x, bfloat16 *iptr)) { + return fputil::modf(x, *iptr); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/nanbf16.cpp b/libc/src/math/generic/nanbf16.cpp new file mode 100644 index 0000000..678dd6a --- /dev/null +++ b/libc/src/math/generic/nanbf16.cpp @@ -0,0 +1,25 @@ +//===-- Implementation of nanbf16 function --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/nanbf16.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/config.h" +#include "src/__support/str_to_float.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, nanbf16, (const char *arg)) { + auto result = internal::strtonan<bfloat16>(arg); + if (result.has_error()) + libc_errno = result.error; + return result.value; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/nearbyintbf16.cpp b/libc/src/math/generic/nearbyintbf16.cpp new file mode 100644 index 0000000..a639199 --- /dev/null +++ b/libc/src/math/generic/nearbyintbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of nearbyintbf16 function --------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/nearbyintbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, nearbyintbf16, (bfloat16 x)) { + return fputil::round_using_current_rounding_mode(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/nextafterbf16.cpp b/libc/src/math/generic/nextafterbf16.cpp new file mode 100644 index 0000000..e21a2dc --- /dev/null +++ b/libc/src/math/generic/nextafterbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of nextafterbf16 function --------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/nextafterbf16.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, nextafterbf16, (bfloat16 x, bfloat16 y)) { + return fputil::nextafter(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/nextdownbf16.cpp b/libc/src/math/generic/nextdownbf16.cpp new file mode 100644 index 0000000..2115df9 --- /dev/null +++ b/libc/src/math/generic/nextdownbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of nextdownbf16 function ---------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/nextdownbf16.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, nextdownbf16, (bfloat16 x)) { + return fputil::nextupdown</*IsDown=*/true>(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/nexttowardbf16.cpp b/libc/src/math/generic/nexttowardbf16.cpp new file mode 100644 index 0000000..3deab87 --- /dev/null +++ b/libc/src/math/generic/nexttowardbf16.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of nexttowardbf16 function -------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/nexttowardbf16.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, nexttowardbf16, (bfloat16 x, long double y)) { + // nextafter<T, U> where T != U is nexttoward + return fputil::nextafter(x, y); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/nextupbf16.cpp b/libc/src/math/generic/nextupbf16.cpp new file mode 100644 index 0000000..147ce37 --- /dev/null +++ b/libc/src/math/generic/nextupbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of nextupbf16 function -----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/nextupbf16.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, nextupbf16, (bfloat16 x)) { + return fputil::nextupdown</*IsDown=*/false>(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/remainderbf16.cpp b/libc/src/math/generic/remainderbf16.cpp new file mode 100644 index 0000000..e70726a --- /dev/null +++ b/libc/src/math/generic/remainderbf16.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of remainderbf16 function --------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/remainderbf16.h" +#include "src/__support/FPUtil/DivisionAndRemainderOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, remainderbf16, (bfloat16 x, bfloat16 y)) { + int quotient; + return fputil::remquo(x, y, quotient); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/remquobf16.cpp b/libc/src/math/generic/remquobf16.cpp new file mode 100644 index 0000000..e1b13f8 --- /dev/null +++ b/libc/src/math/generic/remquobf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of remquobf16 function -----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/remquobf16.h" +#include "src/__support/FPUtil/DivisionAndRemainderOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, remquobf16, (bfloat16 x, bfloat16 y, int *exp)) { + return fputil::remquo(x, y, *exp); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/rintbf16.cpp b/libc/src/math/generic/rintbf16.cpp new file mode 100644 index 0000000..2ffe16a --- /dev/null +++ b/libc/src/math/generic/rintbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of rintbf16 function -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/rintbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, rintbf16, (bfloat16 x)) { + return fputil::round_using_current_rounding_mode(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/roundbf16.cpp b/libc/src/math/generic/roundbf16.cpp new file mode 100644 index 0000000..cc7e5e2 --- /dev/null +++ b/libc/src/math/generic/roundbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of roundbf16 function ------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/roundbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, roundbf16, (bfloat16 x)) { + return fputil::round(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/roundevenbf16.cpp b/libc/src/math/generic/roundevenbf16.cpp new file mode 100644 index 0000000..39419e4 --- /dev/null +++ b/libc/src/math/generic/roundevenbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of roundevenbf16 function --------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/roundevenbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, roundevenbf16, (bfloat16 x)) { + return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/scalblnbf16.cpp b/libc/src/math/generic/scalblnbf16.cpp new file mode 100644 index 0000000..f85f702 --- /dev/null +++ b/libc/src/math/generic/scalblnbf16.cpp @@ -0,0 +1,26 @@ +//===-- Implementation of scalblnbf16 function ----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/scalblnbf16.h" +#include "hdr/float_macros.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +#if FLT_RADIX != 2 +#error "FLT_RADIX != 2 is not supported." +#endif + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, scalblnbf16, (bfloat16 x, long n)) { + return fputil::ldexp(x, n); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/scalbnbf16.cpp b/libc/src/math/generic/scalbnbf16.cpp new file mode 100644 index 0000000..108f9e7 --- /dev/null +++ b/libc/src/math/generic/scalbnbf16.cpp @@ -0,0 +1,26 @@ +//===-- Implementation of scalbnbf16 function -----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/scalbnbf16.h" +#include "hdr/float_macros.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +#if FLT_RADIX != 2 +#error "FLT_RADIX != 2 is not supported." +#endif + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, scalbnbf16, (bfloat16 x, int n)) { + return fputil::ldexp(x, n); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/setpayloadbf16.cpp b/libc/src/math/generic/setpayloadbf16.cpp new file mode 100644 index 0000000..49f9b9c --- /dev/null +++ b/libc/src/math/generic/setpayloadbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of setpayloadbf16 function -------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/setpayloadbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, setpayloadbf16, (bfloat16 * res, bfloat16 pl)) { + return static_cast<int>(fputil::setpayload</*IsSignaling=*/false>(*res, pl)); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/setpayloadsigbf16.cpp b/libc/src/math/generic/setpayloadsigbf16.cpp new file mode 100644 index 0000000..7a2b7c7 --- /dev/null +++ b/libc/src/math/generic/setpayloadsigbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of setpayloadsigbf16 function ----------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/setpayloadsigbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, setpayloadsigbf16, (bfloat16 * res, bfloat16 pl)) { + return static_cast<int>(fputil::setpayload</*IsSignaling=*/true>(*res, pl)); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/sin.cpp b/libc/src/math/generic/sin.cpp index a614427b..1b6310f 100644 --- a/libc/src/math/generic/sin.cpp +++ b/libc/src/math/generic/sin.cpp @@ -18,13 +18,13 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA -#include "src/math/generic/range_reduction_double_common.h" -#include "src/math/generic/sincos_eval.h" +#include "src/__support/math/range_reduction_double_common.h" +#include "src/__support/math/sincos_eval.h" #ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE -#include "range_reduction_double_fma.h" +#include "src/__support/math/range_reduction_double_fma.h" #else -#include "range_reduction_double_nofma.h" +#include "src/__support/math/range_reduction_double_nofma.h" #endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE namespace LIBC_NAMESPACE_DECL { @@ -33,6 +33,7 @@ using DoubleDouble = fputil::DoubleDouble; using Float128 = typename fputil::DyadicFloat<128>; LLVM_LIBC_FUNCTION(double, sin, (double x)) { + using namespace math::range_reduction_double_internal; using FPBits = typename fputil::FPBits<double>; FPBits xbits(x); @@ -95,7 +96,8 @@ LLVM_LIBC_FUNCTION(double, sin, (double x)) { DoubleDouble sin_y, cos_y; - [[maybe_unused]] double err = generic::sincos_eval(y, sin_y, cos_y); + [[maybe_unused]] double err = + math::sincos_eval_internal::sincos_eval(y, sin_y, cos_y); // Look up sin(k * pi/128) and cos(k * pi/128) #ifdef LIBC_MATH_HAS_SMALL_TABLES @@ -149,7 +151,7 @@ LLVM_LIBC_FUNCTION(double, sin, (double x)) { else u_f128 = range_reduction_large.accurate(); - generic::sincos_eval(u_f128, sin_u, cos_u); + math::sincos_eval_internal::sincos_eval(u_f128, sin_u, cos_u); auto get_sin_k = [](unsigned kk) -> Float128 { unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63); diff --git a/libc/src/math/generic/sincos.cpp b/libc/src/math/generic/sincos.cpp index 08c8a82..38661de 100644 --- a/libc/src/math/generic/sincos.cpp +++ b/libc/src/math/generic/sincos.cpp @@ -19,13 +19,13 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA -#include "src/math/generic/range_reduction_double_common.h" -#include "src/math/generic/sincos_eval.h" +#include "src/__support/math/range_reduction_double_common.h" +#include "src/__support/math/sincos_eval.h" #ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE -#include "range_reduction_double_fma.h" +#include "src/__support/math/range_reduction_double_fma.h" #else -#include "range_reduction_double_nofma.h" +#include "src/__support/math/range_reduction_double_nofma.h" #endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE namespace LIBC_NAMESPACE_DECL { @@ -34,6 +34,7 @@ using DoubleDouble = fputil::DoubleDouble; using Float128 = typename fputil::DyadicFloat<128>; LLVM_LIBC_FUNCTION(void, sincos, (double x, double *sin_x, double *cos_x)) { + using namespace math::range_reduction_double_internal; using FPBits = typename fputil::FPBits<double>; FPBits xbits(x); @@ -106,7 +107,8 @@ LLVM_LIBC_FUNCTION(void, sincos, (double x, double *sin_x, double *cos_x)) { DoubleDouble sin_y, cos_y; - [[maybe_unused]] double err = generic::sincos_eval(y, sin_y, cos_y); + [[maybe_unused]] double err = + math::sincos_eval_internal::sincos_eval(y, sin_y, cos_y); // Look up sin(k * pi/128) and cos(k * pi/128) #ifdef LIBC_MATH_HAS_SMALL_TABLES @@ -179,7 +181,7 @@ LLVM_LIBC_FUNCTION(void, sincos, (double x, double *sin_x, double *cos_x)) { else u_f128 = range_reduction_large.accurate(); - generic::sincos_eval(u_f128, sin_u, cos_u); + math::sincos_eval_internal::sincos_eval(u_f128, sin_u, cos_u); auto get_sin_k = [](unsigned kk) -> Float128 { unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63); diff --git a/libc/src/math/generic/sincosf.cpp b/libc/src/math/generic/sincosf.cpp index 9c7bf18..5179c98 100644 --- a/libc/src/math/generic/sincosf.cpp +++ b/libc/src/math/generic/sincosf.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/math/sincosf.h" -#include "sincosf_utils.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/multiply_add.h" @@ -16,6 +15,7 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA +#include "src/__support/math/sincosf_utils.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/math/generic/sinf.cpp b/libc/src/math/generic/sinf.cpp index 38ea56f..a8e634c 100644 --- a/libc/src/math/generic/sinf.cpp +++ b/libc/src/math/generic/sinf.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/math/sinf.h" -#include "sincosf_utils.h" #include "src/__support/FPUtil/BasicOperations.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" @@ -18,11 +17,12 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA +#include "src/__support/math/sincosf_utils.h" #if defined(LIBC_TARGET_CPU_HAS_FMA_DOUBLE) -#include "range_reduction_fma.h" +#include "src/__support/math/range_reduction_fma.h" #else -#include "range_reduction.h" +#include "src/__support/math/range_reduction.h" #endif namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/math/generic/sinf16.cpp b/libc/src/math/generic/sinf16.cpp index 28debbd..2b57920 100644 --- a/libc/src/math/generic/sinf16.cpp +++ b/libc/src/math/generic/sinf16.cpp @@ -9,13 +9,13 @@ #include "src/math/sinf16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" -#include "sincosf16_utils.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/cast.h" #include "src/__support/FPUtil/except_value_utils.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/macros/optimization.h" +#include "src/__support/math/sincosf16_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -32,6 +32,7 @@ constexpr fputil::ExceptValues<float16, N_EXCEPTS> SINF16_EXCEPTS{{ #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS LLVM_LIBC_FUNCTION(float16, sinf16, (float16 x)) { + using namespace sincosf16_internal; using FPBits = fputil::FPBits<float16>; FPBits xbits(x); diff --git a/libc/src/math/generic/sinhf.cpp b/libc/src/math/generic/sinhf.cpp index 63111f8..5f2d0b5 100644 --- a/libc/src/math/generic/sinhf.cpp +++ b/libc/src/math/generic/sinhf.cpp @@ -12,7 +12,7 @@ #include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY -#include "src/math/generic/explogxf.h" +#include "src/__support/math/sinhfcoshf_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -73,7 +73,8 @@ LLVM_LIBC_FUNCTION(float, sinhf, (float x)) { } // sinh(x) = (e^x - e^(-x)) / 2. - return static_cast<float>(exp_pm_eval</*is_sinh*/ true>(x)); + return static_cast<float>( + math::sinhfcoshf_internal::exp_pm_eval</*is_sinh*/ true>(x)); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/sinhf16.cpp b/libc/src/math/generic/sinhf16.cpp index b426ea7..f6b5c9b 100644 --- a/libc/src/math/generic/sinhf16.cpp +++ b/libc/src/math/generic/sinhf16.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/math/sinhf16.h" -#include "expxf16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" #include "src/__support/FPUtil/FEnvImpl.h" @@ -17,6 +16,7 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" +#include "src/__support/math/expxf16_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -89,6 +89,7 @@ static constexpr fputil::ExceptValues<float16, 13> SINHF16_EXCEPTS_NEG = {{ #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS LLVM_LIBC_FUNCTION(float16, sinhf16, (float16 x)) { + using namespace math::expxf16_internal; using FPBits = fputil::FPBits<float16>; FPBits x_bits(x); diff --git a/libc/src/math/generic/sinpif.cpp b/libc/src/math/generic/sinpif.cpp index 492689d..f3383f1 100644 --- a/libc/src/math/generic/sinpif.cpp +++ b/libc/src/math/generic/sinpif.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/math/sinpif.h" -#include "sincosf_utils.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/PolyEval.h" @@ -15,6 +14,7 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY +#include "src/__support/math/sincosf_utils.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/math/generic/sinpif16.cpp b/libc/src/math/generic/sinpif16.cpp index 68af484..311e6f9 100644 --- a/libc/src/math/generic/sinpif16.cpp +++ b/libc/src/math/generic/sinpif16.cpp @@ -9,15 +9,16 @@ #include "src/math/sinpif16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" -#include "sincosf16_utils.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/cast.h" #include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/math/sincosf16_utils.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(float16, sinpif16, (float16 x)) { + using namespace sincosf16_internal; using FPBits = typename fputil::FPBits<float16>; FPBits xbits(x); diff --git a/libc/src/math/generic/tan.cpp b/libc/src/math/generic/tan.cpp index 89b812c..7ea40c9 100644 --- a/libc/src/math/generic/tan.cpp +++ b/libc/src/math/generic/tan.cpp @@ -20,12 +20,12 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA -#include "src/math/generic/range_reduction_double_common.h" +#include "src/__support/math/range_reduction_double_common.h" #ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE -#include "range_reduction_double_fma.h" +#include "src/__support/math/range_reduction_double_fma.h" #else -#include "range_reduction_double_nofma.h" +#include "src/__support/math/range_reduction_double_nofma.h" #endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE namespace LIBC_NAMESPACE_DECL { @@ -121,6 +121,7 @@ LIBC_INLINE double tan_eval(const DoubleDouble &u, DoubleDouble &result) { } // anonymous namespace LLVM_LIBC_FUNCTION(double, tan, (double x)) { + using namespace math::range_reduction_double_internal; using FPBits = typename fputil::FPBits<double>; FPBits xbits(x); diff --git a/libc/src/math/generic/tanf.cpp b/libc/src/math/generic/tanf.cpp index ca5e35d..a8c557b 100644 --- a/libc/src/math/generic/tanf.cpp +++ b/libc/src/math/generic/tanf.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/math/tanf.h" -#include "sincosf_utils.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/PolyEval.h" @@ -18,6 +17,7 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA +#include "src/__support/math/sincosf_utils.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/math/generic/tanf16.cpp b/libc/src/math/generic/tanf16.cpp index 229f4a3..20323a8 100644 --- a/libc/src/math/generic/tanf16.cpp +++ b/libc/src/math/generic/tanf16.cpp @@ -9,13 +9,13 @@ #include "src/math/tanf16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" -#include "sincosf16_utils.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/cast.h" #include "src/__support/FPUtil/except_value_utils.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/macros/optimization.h" +#include "src/__support/math/sincosf16_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -37,6 +37,7 @@ constexpr fputil::ExceptValues<float16, N_EXCEPTS> TANF16_EXCEPTS{{ #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS LLVM_LIBC_FUNCTION(float16, tanf16, (float16 x)) { + using namespace sincosf16_internal; using FPBits = fputil::FPBits<float16>; FPBits xbits(x); diff --git a/libc/src/math/generic/tanhf.cpp b/libc/src/math/generic/tanhf.cpp index 32153c3..0c55047 100644 --- a/libc/src/math/generic/tanhf.cpp +++ b/libc/src/math/generic/tanhf.cpp @@ -14,7 +14,7 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/__support/macros/properties/cpu_features.h" -#include "src/math/generic/explogxf.h" +#include "src/__support/math/exp10f_utils.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/math/generic/tanhf16.cpp b/libc/src/math/generic/tanhf16.cpp index 4c43cfd..fc0e28b 100644 --- a/libc/src/math/generic/tanhf16.cpp +++ b/libc/src/math/generic/tanhf16.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/math/tanhf16.h" -#include "expxf16.h" #include "hdr/fenv_macros.h" #include "src/__support/CPP/array.h" #include "src/__support/FPUtil/FEnvImpl.h" @@ -21,6 +20,7 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" +#include "src/__support/math/expxf16_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -34,6 +34,7 @@ static constexpr fputil::ExceptValues<float16, 2> TANHF16_EXCEPTS = {{ #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS LLVM_LIBC_FUNCTION(float16, tanhf16, (float16 x)) { + using namespace math::expxf16_internal; using FPBits = fputil::FPBits<float16>; FPBits x_bits(x); diff --git a/libc/src/math/generic/tanpif.cpp b/libc/src/math/generic/tanpif.cpp index 58d46c9..b49f3ce 100644 --- a/libc/src/math/generic/tanpif.cpp +++ b/libc/src/math/generic/tanpif.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "src/math/tanpif.h" -#include "sincosf_utils.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/cast.h" @@ -16,6 +15,7 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY +#include "src/__support/math/sincosf_utils.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/math/generic/tanpif16.cpp b/libc/src/math/generic/tanpif16.cpp index 792d405..b137b09 100644 --- a/libc/src/math/generic/tanpif16.cpp +++ b/libc/src/math/generic/tanpif16.cpp @@ -9,13 +9,13 @@ #include "src/math/tanpif16.h" #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" -#include "sincosf16_utils.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/cast.h" #include "src/__support/FPUtil/except_value_utils.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/macros/optimization.h" +#include "src/__support/math/sincosf16_utils.h" namespace LIBC_NAMESPACE_DECL { @@ -39,6 +39,7 @@ constexpr fputil::ExceptValues<float16, N_EXCEPTS> TANPIF16_EXCEPTS{{ #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS LLVM_LIBC_FUNCTION(float16, tanpif16, (float16 x)) { + using namespace sincosf16_internal; using FPBits = typename fputil::FPBits<float16>; FPBits xbits(x); diff --git a/libc/src/math/generic/totalorderbf16.cpp b/libc/src/math/generic/totalorderbf16.cpp new file mode 100644 index 0000000..bb9c86e --- /dev/null +++ b/libc/src/math/generic/totalorderbf16.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of totalorderbf16 function -------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/totalorderbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, totalorderbf16, + (const bfloat16 *x, const bfloat16 *y)) { + return static_cast<int>(fputil::totalorder(*x, *y)); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/totalordermagbf16.cpp b/libc/src/math/generic/totalordermagbf16.cpp new file mode 100644 index 0000000..3fc61d9 --- /dev/null +++ b/libc/src/math/generic/totalordermagbf16.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of totalordermagbf16 function ----------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/totalordermagbf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, totalordermagbf16, + (const bfloat16 *x, const bfloat16 *y)) { + return static_cast<int>(fputil::totalordermag(*x, *y)); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/truncbf16.cpp b/libc/src/math/generic/truncbf16.cpp new file mode 100644 index 0000000..dfbe83d --- /dev/null +++ b/libc/src/math/generic/truncbf16.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of truncbf16 function ------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/truncbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, truncbf16, (bfloat16 x)) { + return fputil::trunc(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/ufromfpbf16.cpp b/libc/src/math/generic/ufromfpbf16.cpp new file mode 100644 index 0000000..336771b --- /dev/null +++ b/libc/src/math/generic/ufromfpbf16.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of ufromfpbf16 function ----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/ufromfpbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, ufromfpbf16, + (bfloat16 x, int rnd, unsigned int width)) { + return fputil::fromfp</*IsSigned=*/false>(x, rnd, width); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/ufromfpxbf16.cpp b/libc/src/math/generic/ufromfpxbf16.cpp new file mode 100644 index 0000000..ac9cf44 --- /dev/null +++ b/libc/src/math/generic/ufromfpxbf16.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of ufromfpxbf16 function ---------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/ufromfpxbf16.h" +#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(bfloat16, ufromfpxbf16, + (bfloat16 x, int rnd, unsigned int width)) { + return fputil::fromfpx</*IsSigned=*/false>(x, rnd, width); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/getpayloadbf16.h b/libc/src/math/getpayloadbf16.h new file mode 100644 index 0000000..e4767f0 --- /dev/null +++ b/libc/src/math/getpayloadbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for getpayloadbf16 ----------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_GETPAYLOADBF16_H +#define LLVM_LIBC_SRC_MATH_GETPAYLOADBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 getpayloadbf16(const bfloat16 *x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_GETPAYLOADBF16_H diff --git a/libc/src/math/ilogbbf16.h b/libc/src/math/ilogbbf16.h new file mode 100644 index 0000000..da2384b --- /dev/null +++ b/libc/src/math/ilogbbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for ilogbbf16 ---------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_ILOGBBF16_H +#define LLVM_LIBC_SRC_MATH_ILOGBBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +int ilogbbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_ILOGBBF16_H diff --git a/libc/src/math/iscanonicalbf16.h b/libc/src/math/iscanonicalbf16.h new file mode 100644 index 0000000..f4f975e --- /dev/null +++ b/libc/src/math/iscanonicalbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for iscanonicalbf16 ---------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_ISCANONICALBF16_H +#define LLVM_LIBC_SRC_MATH_ISCANONICALBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +int iscanonicalbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_ISCANONICALBF16_H diff --git a/libc/src/math/issignalingbf16.h b/libc/src/math/issignalingbf16.h new file mode 100644 index 0000000..afbe70f --- /dev/null +++ b/libc/src/math/issignalingbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for issignalingbf16 ---------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_ISSIGNALINGBF16_H +#define LLVM_LIBC_SRC_MATH_ISSIGNALINGBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +int issignalingbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_ISSIGNALINGBF16_H diff --git a/libc/src/math/ldexpbf16.h b/libc/src/math/ldexpbf16.h new file mode 100644 index 0000000..7436d8d --- /dev/null +++ b/libc/src/math/ldexpbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for ldexpbf16 ---------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_LDEXPBF16_H +#define LLVM_LIBC_SRC_MATH_LDEXPBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 ldexpbf16(bfloat16 x, int exp); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_LDEXPBF16_H diff --git a/libc/src/math/llogbbf16.h b/libc/src/math/llogbbf16.h new file mode 100644 index 0000000..13f0570 --- /dev/null +++ b/libc/src/math/llogbbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for llogbbf16 ---------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_LLOGBBF16_H +#define LLVM_LIBC_SRC_MATH_LLOGBBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +long llogbbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_LLOGBBF16_H diff --git a/libc/src/math/llrintbf16.h b/libc/src/math/llrintbf16.h new file mode 100644 index 0000000..23402a5 --- /dev/null +++ b/libc/src/math/llrintbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for llrintbf16 --------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_LLRINTBF16_H +#define LLVM_LIBC_SRC_MATH_LLRINTBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +long long llrintbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_LLRINTBF16_H diff --git a/libc/src/math/llroundbf16.h b/libc/src/math/llroundbf16.h new file mode 100644 index 0000000..69878e4 --- /dev/null +++ b/libc/src/math/llroundbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for llroundbf16 -------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_LLROUNDBF16_H +#define LLVM_LIBC_SRC_MATH_LLROUNDBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +long long llroundbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_LLROUNDBF16_H diff --git a/libc/src/math/logbbf16.h b/libc/src/math/logbbf16.h new file mode 100644 index 0000000..2c0d77e --- /dev/null +++ b/libc/src/math/logbbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for logbbf16 ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_LOGBBF16_H +#define LLVM_LIBC_SRC_MATH_LOGBBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 logbbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_LOGBBF16_H diff --git a/libc/src/math/lrintbf16.h b/libc/src/math/lrintbf16.h new file mode 100644 index 0000000..ec24472 --- /dev/null +++ b/libc/src/math/lrintbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for lrintbf16 ---------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_LRINTBF16_H +#define LLVM_LIBC_SRC_MATH_LRINTBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +long lrintbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_LRINTBF16_H diff --git a/libc/src/math/lroundbf16.h b/libc/src/math/lroundbf16.h new file mode 100644 index 0000000..c08db7a --- /dev/null +++ b/libc/src/math/lroundbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for lroundbf16 --------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_LROUNDBF16_H +#define LLVM_LIBC_SRC_MATH_LROUNDBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +long lroundbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_LROUNDBF16_H diff --git a/libc/src/math/modfbf16.h b/libc/src/math/modfbf16.h new file mode 100644 index 0000000..df05b6c --- /dev/null +++ b/libc/src/math/modfbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for modfbf16 ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_MODFBF16_H +#define LLVM_LIBC_SRC_MATH_MODFBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 modfbf16(bfloat16 x, bfloat16 *iptr); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_MODFBF16_H diff --git a/libc/src/math/nanbf16.h b/libc/src/math/nanbf16.h new file mode 100644 index 0000000..1551044 --- /dev/null +++ b/libc/src/math/nanbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for nanbf16 -----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_NANBF16_H +#define LLVM_LIBC_SRC_MATH_NANBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 nanbf16(const char *arg); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_NANBF16_H diff --git a/libc/src/math/nearbyintbf16.h b/libc/src/math/nearbyintbf16.h new file mode 100644 index 0000000..bc7eb3b --- /dev/null +++ b/libc/src/math/nearbyintbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for nearbyintbf16 -----------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_NEARBYINTBF16_H +#define LLVM_LIBC_SRC_MATH_NEARBYINTBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 nearbyintbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_NEARBYINTBF16_H diff --git a/libc/src/math/nextafterbf16.h b/libc/src/math/nextafterbf16.h new file mode 100644 index 0000000..f962c7c --- /dev/null +++ b/libc/src/math/nextafterbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for nextafterbf16 -----------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_NEXTAFTERBF16_H +#define LLVM_LIBC_SRC_MATH_NEXTAFTERBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 nextafterbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_NEXTAFTERBF16_H diff --git a/libc/src/math/nextdownbf16.h b/libc/src/math/nextdownbf16.h new file mode 100644 index 0000000..36b0cd7 --- /dev/null +++ b/libc/src/math/nextdownbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for nextdownbf16 ------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_NEXTDOWNBF16_H +#define LLVM_LIBC_SRC_MATH_NEXTDOWNBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 nextdownbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_NEXTDOWNBF16_H diff --git a/libc/src/math/nexttowardbf16.h b/libc/src/math/nexttowardbf16.h new file mode 100644 index 0000000..930abf8 --- /dev/null +++ b/libc/src/math/nexttowardbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for nexttowardbf16 ----------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_NEXTTOWARDBF16_H +#define LLVM_LIBC_SRC_MATH_NEXTTOWARDBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 nexttowardbf16(bfloat16 x, long double y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_NEXTTOWARDBF16_H diff --git a/libc/src/math/nextupbf16.h b/libc/src/math/nextupbf16.h new file mode 100644 index 0000000..872de84 --- /dev/null +++ b/libc/src/math/nextupbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for nextupbf16 --------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_NEXTUPBF16_H +#define LLVM_LIBC_SRC_MATH_NEXTUPBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 nextupbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_NEXTUPBF16_H diff --git a/libc/src/math/remainderbf16.h b/libc/src/math/remainderbf16.h new file mode 100644 index 0000000..a1a2eaa --- /dev/null +++ b/libc/src/math/remainderbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for remainderbf16 -----------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_REMAINDERBF16_H +#define LLVM_LIBC_SRC_MATH_REMAINDERBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 remainderbf16(bfloat16 x, bfloat16 y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_REMAINDERBF16_H diff --git a/libc/src/math/remquobf16.h b/libc/src/math/remquobf16.h new file mode 100644 index 0000000..909db17 --- /dev/null +++ b/libc/src/math/remquobf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for remquobf16 --------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_REMQUOBF16_H +#define LLVM_LIBC_SRC_MATH_REMQUOBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 remquobf16(bfloat16 x, bfloat16 y, int *exp); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_REMQUOBF16_H diff --git a/libc/src/math/rintbf16.h b/libc/src/math/rintbf16.h new file mode 100644 index 0000000..aae1541 --- /dev/null +++ b/libc/src/math/rintbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for rintbf16 ----------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_RINTBF16_H +#define LLVM_LIBC_SRC_MATH_RINTBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 rintbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_RINTBF16_H diff --git a/libc/src/math/roundbf16.h b/libc/src/math/roundbf16.h new file mode 100644 index 0000000..0f74e43 --- /dev/null +++ b/libc/src/math/roundbf16.h @@ -0,0 +1,22 @@ +//===-- Implementation header for roundbf16 ---------------------*- C++ +//-*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_ROUNDBF16_H +#define LLVM_LIBC_SRC_MATH_ROUNDBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 roundbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_ROUNDBF16_H diff --git a/libc/src/math/roundevenbf16.h b/libc/src/math/roundevenbf16.h new file mode 100644 index 0000000..f4374d2 --- /dev/null +++ b/libc/src/math/roundevenbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for roundevenbf16 -----------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_ROUNDEVENBF16_H +#define LLVM_LIBC_SRC_MATH_ROUNDEVENBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 roundevenbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_ROUNDEVENBF16_H diff --git a/libc/src/math/scalblnbf16.h b/libc/src/math/scalblnbf16.h new file mode 100644 index 0000000..10aad05 --- /dev/null +++ b/libc/src/math/scalblnbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for scalblnbf16 -------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_SCALBLNBF16_H +#define LLVM_LIBC_SRC_MATH_SCALBLNBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 scalblnbf16(bfloat16 x, long n); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_SCALBLNBF16_H diff --git a/libc/src/math/scalbnbf16.h b/libc/src/math/scalbnbf16.h new file mode 100644 index 0000000..67efa33 --- /dev/null +++ b/libc/src/math/scalbnbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for scalbnbf16 --------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_SCALBNBF16_H +#define LLVM_LIBC_SRC_MATH_SCALBNBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 scalbnbf16(bfloat16 x, int n); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_SCALBNBF16_H diff --git a/libc/src/math/setpayloadbf16.h b/libc/src/math/setpayloadbf16.h new file mode 100644 index 0000000..e3a60b2 --- /dev/null +++ b/libc/src/math/setpayloadbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for setpayloadbf16 ----------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_SETPAYLOADBF16_H +#define LLVM_LIBC_SRC_MATH_SETPAYLOADBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +int setpayloadbf16(bfloat16 *res, bfloat16 pl); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_SETPAYLOADBF16_H diff --git a/libc/src/math/setpayloadsigbf16.h b/libc/src/math/setpayloadsigbf16.h new file mode 100644 index 0000000..5baba95 --- /dev/null +++ b/libc/src/math/setpayloadsigbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for setpayloadsigbf16 -------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_SETPAYLOADSIGBF16_H +#define LLVM_LIBC_SRC_MATH_SETPAYLOADSIGBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +int setpayloadsigbf16(bfloat16 *res, bfloat16 pl); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_SETPAYLOADSIGBF16_H diff --git a/libc/src/math/totalorderbf16.h b/libc/src/math/totalorderbf16.h new file mode 100644 index 0000000..2414852 --- /dev/null +++ b/libc/src/math/totalorderbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for totalorderbf16 ----------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_TOTALORDERF16_H +#define LLVM_LIBC_SRC_MATH_TOTALORDERF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +int totalorderbf16(const bfloat16 *x, const bfloat16 *y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_TOTALORDERF16_H diff --git a/libc/src/math/totalordermagbf16.h b/libc/src/math/totalordermagbf16.h new file mode 100644 index 0000000..c48de1c --- /dev/null +++ b/libc/src/math/totalordermagbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for totalordermagbf16 -------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_TOTALORDERMAGF16_H +#define LLVM_LIBC_SRC_MATH_TOTALORDERMAGF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +int totalordermagbf16(const bfloat16 *x, const bfloat16 *y); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_TOTALORDERMAGF16_H diff --git a/libc/src/math/truncbf16.h b/libc/src/math/truncbf16.h new file mode 100644 index 0000000..c87d4cc --- /dev/null +++ b/libc/src/math/truncbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for truncbf16 ---------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_TRUNCBF16_H +#define LLVM_LIBC_SRC_MATH_TRUNCBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 truncbf16(bfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_TRUNCBF16_H diff --git a/libc/src/math/ufromfpbf16.h b/libc/src/math/ufromfpbf16.h new file mode 100644 index 0000000..1fd876a --- /dev/null +++ b/libc/src/math/ufromfpbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for ufromfpbf16 -------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_UFROMFPBF16_H +#define LLVM_LIBC_SRC_MATH_UFROMFPBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 ufromfpbf16(bfloat16 x, int rnd, unsigned int width); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_UFROMFPBF16_H diff --git a/libc/src/math/ufromfpxbf16.h b/libc/src/math/ufromfpxbf16.h new file mode 100644 index 0000000..ec63744 --- /dev/null +++ b/libc/src/math/ufromfpxbf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for ufromfpxbf16 ------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_UFROMFPXBF16_H +#define LLVM_LIBC_SRC_MATH_UFROMFPXBF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +bfloat16 ufromfpxbf16(bfloat16 x, int rnd, unsigned int width); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_UFROMFPXBF16_H diff --git a/libc/src/stdlib/exit.cpp b/libc/src/stdlib/exit.cpp index 28a6f8a..ef3b8dd 100644 --- a/libc/src/stdlib/exit.cpp +++ b/libc/src/stdlib/exit.cpp @@ -15,7 +15,17 @@ namespace LIBC_NAMESPACE_DECL { extern "C" void __cxa_finalize(void *); +// exit needs to clean up TLS and call associated destructors. +// TODO: Strictly speaking, it is not valid to call exit in overlay mode +// as we have no way to ensure system libc will call the TLS destructors. +// We should run exit related tests in hermetic mode but this is currently +// blocked by https://github.com/llvm/llvm-project/issues/133925. +extern "C" [[gnu::weak]] void __cxa_thread_finalize(); + +// TODO: use recursive mutex to protect this routine. [[noreturn]] LLVM_LIBC_FUNCTION(void, exit, (int status)) { + if (__cxa_thread_finalize) + __cxa_thread_finalize(); __cxa_finalize(nullptr); internal::exit(status); } diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt index 809decf..5c9f622 100644 --- a/libc/src/string/CMakeLists.txt +++ b/libc/src/string/CMakeLists.txt @@ -20,6 +20,7 @@ add_header_library( libc.hdr.stdint_proxy libc.src.__support.CPP.bitset libc.src.__support.CPP.type_traits + libc.src.__support.CPP.simd libc.src.__support.common ${string_config_options} ) diff --git a/libc/src/string/memory_utils/aarch64/inline_strlen.h b/libc/src/string/memory_utils/aarch64/inline_strlen.h new file mode 100644 index 0000000..36fd1aa --- /dev/null +++ b/libc/src/string/memory_utils/aarch64/inline_strlen.h @@ -0,0 +1,53 @@ +//===-- Strlen implementation for aarch64 ---------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_STRLEN_H +#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_STRLEN_H + +#if defined(__ARM_NEON) +#include "src/__support/CPP/bit.h" // countr_zero + +#include <arm_neon.h> +#include <stddef.h> // size_t + +namespace LIBC_NAMESPACE_DECL { + +namespace neon { +[[gnu::no_sanitize_address]] [[maybe_unused]] LIBC_INLINE static size_t +string_length(const char *src) { + using Vector __attribute__((may_alias)) = uint8x8_t; + + uintptr_t misalign_bytes = reinterpret_cast<uintptr_t>(src) % sizeof(Vector); + const Vector *block_ptr = + reinterpret_cast<const Vector *>(src - misalign_bytes); + Vector v = *block_ptr; + Vector vcmp = vceqz_u8(v); + uint64x1_t cmp_mask = vreinterpret_u64_u8(vcmp); + uint64_t cmp = vget_lane_u64(cmp_mask, 0); + cmp = cmp >> (misalign_bytes << 3); + if (cmp) + return cpp::countr_zero(cmp) >> 3; + + while (true) { + ++block_ptr; + v = *block_ptr; + vcmp = vceqz_u8(v); + cmp_mask = vreinterpret_u64_u8(vcmp); + cmp = vget_lane_u64(cmp_mask, 0); + if (cmp) + return static_cast<size_t>(reinterpret_cast<uintptr_t>(block_ptr) - + reinterpret_cast<uintptr_t>(src) + + (cpp::countr_zero(cmp) >> 3)); + } +} +} // namespace neon + +namespace string_length_impl = neon; + +} // namespace LIBC_NAMESPACE_DECL +#endif // __ARM_NEON +#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_STRLEN_H diff --git a/libc/src/string/memory_utils/generic/inline_strlen.h b/libc/src/string/memory_utils/generic/inline_strlen.h new file mode 100644 index 0000000..68fba2a --- /dev/null +++ b/libc/src/string/memory_utils/generic/inline_strlen.h @@ -0,0 +1,54 @@ +//===-- Strlen for generic SIMD types -------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_INLINE_STRLEN_H +#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_INLINE_STRLEN_H + +#include "src/__support/CPP/bit.h" +#include "src/__support/CPP/simd.h" +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE_DECL { +namespace internal { + +// Exploit the underlying integer representation to do a variable shift. +LIBC_INLINE constexpr cpp::simd_mask<char> shift_mask(cpp::simd_mask<char> m, + size_t shift) { + using bitmask_ty = cpp::internal::get_as_integer_type_t<cpp::simd_mask<char>>; + bitmask_ty r = cpp::bit_cast<bitmask_ty>(m) >> shift; + return cpp::bit_cast<cpp::simd_mask<char>>(r); +} + +[[clang::no_sanitize("address")]] LIBC_INLINE size_t +string_length(const char *src) { + constexpr cpp::simd<char> null_byte = cpp::splat('\0'); + + size_t alignment = alignof(cpp::simd<char>); + const cpp::simd<char> *aligned = reinterpret_cast<const cpp::simd<char> *>( + __builtin_align_down(src, alignment)); + + cpp::simd<char> chars = cpp::load_aligned<cpp::simd<char>>(aligned); + cpp::simd_mask<char> mask = cpp::simd_cast<bool>(chars == null_byte); + size_t offset = src - reinterpret_cast<const char *>(aligned); + if (cpp::any_of(shift_mask(mask, offset))) + return cpp::find_first_set(shift_mask(mask, offset)); + + for (;;) { + cpp::simd<char> chars = cpp::load_aligned<cpp::simd<char>>(++aligned); + cpp::simd_mask<char> mask = cpp::simd_cast<bool>(chars == null_byte); + if (cpp::any_of(mask)) + return (reinterpret_cast<const char *>(aligned) - src) + + cpp::find_first_set(mask); + } +} +} // namespace internal + +namespace string_length_impl = internal; +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_INLINE_STRLEN_H diff --git a/libc/src/string/memory_utils/x86_64/inline_strlen.h b/libc/src/string/memory_utils/x86_64/inline_strlen.h new file mode 100644 index 0000000..739f8c1 --- /dev/null +++ b/libc/src/string/memory_utils/x86_64/inline_strlen.h @@ -0,0 +1,107 @@ +//===-- Strlen implementation for x86_64 ----------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_X86_64_INLINE_STRLEN_H +#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_X86_64_INLINE_STRLEN_H + +#include "src/__support/CPP/bit.h" // countr_zero + +#include <immintrin.h> +#include <stddef.h> // size_t + +namespace LIBC_NAMESPACE_DECL { + +namespace string_length_internal { +// Return a bit-mask with the nth bit set if the nth-byte in block_ptr is zero. +template <typename Vector, typename Mask> +[[gnu::no_sanitize_address]] LIBC_INLINE static Mask +compare_and_mask(const Vector *block_ptr); + +template <typename Vector, typename Mask, + decltype(compare_and_mask<Vector, Mask>)> +[[gnu::no_sanitize_address]] LIBC_INLINE static size_t +string_length_vector(const char *src) { + uintptr_t misalign_bytes = reinterpret_cast<uintptr_t>(src) % sizeof(Vector); + + const Vector *block_ptr = + reinterpret_cast<const Vector *>(src - misalign_bytes); + auto cmp = compare_and_mask<Vector, Mask>(block_ptr) >> misalign_bytes; + if (cmp) + return cpp::countr_zero(cmp); + + while (true) { + block_ptr++; + cmp = compare_and_mask<Vector, Mask>(block_ptr); + if (cmp) + return static_cast<size_t>(reinterpret_cast<uintptr_t>(block_ptr) - + reinterpret_cast<uintptr_t>(src) + + cpp::countr_zero(cmp)); + } +} + +template <> +LIBC_INLINE uint32_t +compare_and_mask<__m128i, uint32_t>(const __m128i *block_ptr) { + __m128i v = _mm_load_si128(block_ptr); + __m128i z = _mm_setzero_si128(); + __m128i c = _mm_cmpeq_epi8(z, v); + return _mm_movemask_epi8(c); +} + +namespace sse2 { +[[maybe_unused]] LIBC_INLINE size_t string_length(const char *src) { + return string_length_vector<__m128i, uint32_t, + compare_and_mask<__m128i, uint32_t>>(src); +} +} // namespace sse2 + +#if defined(__AVX2__) +template <> +LIBC_INLINE uint32_t +compare_and_mask<__m256i, uint32_t>(const __m256i *block_ptr) { + __m256i v = _mm256_load_si256(block_ptr); + __m256i z = _mm256_setzero_si256(); + __m256i c = _mm256_cmpeq_epi8(z, v); + return _mm256_movemask_epi8(c); +} + +namespace avx2 { +[[maybe_unused]] LIBC_INLINE size_t string_length(const char *src) { + return string_length_vector<__m256i, uint32_t, + compare_and_mask<__m256i, uint32_t>>(src); +} +} // namespace avx2 +#endif + +#if defined(__AVX512F__) +template <> +LIBC_INLINE __mmask64 +compare_and_mask<__m512i, __mmask64>(const __m512i *block_ptr) { + __m512i v = _mm512_load_si512(block_ptr); + __m512i z = _mm512_setzero_si512(); + return _mm512_cmp_epu8_mask(z, v, _MM_CMPINT_EQ); +} +namespace avx512 { +[[maybe_unused]] LIBC_INLINE size_t string_length(const char *src) { + return string_length_vector<__m512i, __mmask64, + compare_and_mask<__m512i, __mmask64>>(src); +} +} // namespace avx512 +#endif +} // namespace string_length_internal + +#if defined(__AVX512F__) +namespace string_length_impl = string_length_internal::avx512; +#elif defined(__AVX2__) +namespace string_length_impl = string_length_internal::avx2; +#else +namespace string_length_impl = string_length_internal::sse2; +#endif + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_X86_64_INLINE_STRLEN_H diff --git a/libc/src/string/string_utils.h b/libc/src/string/string_utils.h index 80e5783..1080348 100644 --- a/libc/src/string/string_utils.h +++ b/libc/src/string/string_utils.h @@ -22,6 +22,18 @@ #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY +#if defined(LIBC_COPT_STRING_UNSAFE_WIDE_READ) +#if LIBC_HAS_VECTOR_TYPE +#include "src/string/memory_utils/generic/inline_strlen.h" +#elif defined(LIBC_TARGET_ARCH_IS_X86) +#include "src/string/memory_utils/x86_64/inline_strlen.h" +#elif defined(LIBC_TARGET_ARCH_IS_AARCH64) && defined(__ARM_NEON) +#include "src/string/memory_utils/aarch64/inline_strlen.h" +#else +namespace string_length_impl = LIBC_NAMESPACE::wide_read; +#endif +#endif // defined(LIBC_COPT_STRING_UNSAFE_WIDE_READ) + namespace LIBC_NAMESPACE_DECL { namespace internal { @@ -53,7 +65,7 @@ template <typename Word> LIBC_INLINE constexpr Word repeat_byte(Word byte) { // high bit set will no longer have it set, narrowing the list of bytes which // result in non-zero values to just the zero byte. template <typename Word> LIBC_INLINE constexpr bool has_zeroes(Word block) { - constexpr Word LOW_BITS = repeat_byte<Word>(0x01); + constexpr unsigned int LOW_BITS = repeat_byte<Word>(0x01); constexpr Word HIGH_BITS = repeat_byte<Word>(0x80); Word subtracted = block - LOW_BITS; Word inverted = ~block; @@ -81,16 +93,23 @@ LIBC_INLINE size_t string_length_wide_read(const char *src) { return static_cast<size_t>(char_ptr - src); } -// Returns the length of a string, denoted by the first occurrence -// of a null terminator. -template <typename T> LIBC_INLINE size_t string_length(const T *src) { -#ifdef LIBC_COPT_STRING_UNSAFE_WIDE_READ +namespace wide_read { +LIBC_INLINE size_t string_length(const char *src) { // Unsigned int is the default size for most processors, and on x86-64 it // performs better than larger sizes when the src pointer can't be assumed to // be aligned to a word boundary, so it's the size we use for reading the // string a block at a time. + return string_length_wide_read<unsigned int>(src); +} + +} // namespace wide_read + +// Returns the length of a string, denoted by the first occurrence +// of a null terminator. +template <typename T> LIBC_INLINE size_t string_length(const T *src) { +#ifdef LIBC_COPT_STRING_UNSAFE_WIDE_READ if constexpr (cpp::is_same_v<T, char>) - return string_length_wide_read<unsigned int>(src); + return string_length_impl::string_length(src); #endif size_t length; for (length = 0; *src; ++src, ++length) @@ -99,8 +118,9 @@ template <typename T> LIBC_INLINE size_t string_length(const T *src) { } template <typename Word> -LIBC_INLINE void *find_first_character_wide_read(const unsigned char *src, - unsigned char ch, size_t n) { +[[gnu::no_sanitize_address]] LIBC_INLINE void * +find_first_character_wide_read(const unsigned char *src, unsigned char ch, + size_t n) { const unsigned char *char_ptr = src; size_t cur = 0; @@ -184,33 +204,36 @@ LIBC_INLINE size_t complementary_span(const char *src, const char *segment) { template <bool SkipDelim = true> LIBC_INLINE char *string_token(char *__restrict src, const char *__restrict delimiter_string, - char **__restrict saveptr) { - // Return nullptr immediately if both src AND saveptr are nullptr - if (LIBC_UNLIKELY(src == nullptr && ((src = *saveptr) == nullptr))) + char **__restrict context) { + // Return nullptr immediately if both src AND context are nullptr + if (LIBC_UNLIKELY(src == nullptr && ((src = *context) == nullptr))) return nullptr; static_assert(CHAR_BIT == 8, "bitset of 256 assumes char is 8 bits"); - cpp::bitset<256> delimiter_set; + cpp::bitset<256> delims; for (; *delimiter_string != '\0'; ++delimiter_string) - delimiter_set.set(static_cast<size_t>(*delimiter_string)); + delims.set(*reinterpret_cast<const unsigned char *>(delimiter_string)); + unsigned char *tok_start = reinterpret_cast<unsigned char *>(src); if constexpr (SkipDelim) - for (; *src != '\0' && delimiter_set.test(static_cast<size_t>(*src)); ++src) - ; - if (*src == '\0') { - *saveptr = src; + while (*tok_start != '\0' && delims.test(*tok_start)) + ++tok_start; + if (*tok_start == '\0' && SkipDelim) { + *context = nullptr; return nullptr; } - char *token = src; - for (; *src != '\0'; ++src) { - if (delimiter_set.test(static_cast<size_t>(*src))) { - *src = '\0'; - ++src; - break; - } + + unsigned char *tok_end = tok_start; + while (*tok_end != '\0' && !delims.test(*tok_end)) + ++tok_end; + + if (*tok_end == '\0') { + *context = nullptr; + } else { + *tok_end = '\0'; + *context = reinterpret_cast<char *>(tok_end + 1); } - *saveptr = src; - return token; + return reinterpret_cast<char *>(tok_start); } LIBC_INLINE size_t strlcpy(char *__restrict dst, const char *__restrict src, diff --git a/libc/src/sys/time/linux/utimes.cpp b/libc/src/sys/time/linux/utimes.cpp index 9c00ce9..e740190b 100644 --- a/libc/src/sys/time/linux/utimes.cpp +++ b/libc/src/sys/time/linux/utimes.cpp @@ -21,24 +21,21 @@ namespace LIBC_NAMESPACE_DECL { -#ifdef SYS_utimes -constexpr auto UTIMES_SYSCALL_ID = SYS_utimes; -#elif defined(SYS_utimensat) -constexpr auto UTIMES_SYSCALL_ID = SYS_utimensat; -#elif defined(SYS_utimensat_time64) -constexpr auto UTIMES_SYSCALL_ID = SYS_utimensat_time64; -#else -#error "utimes, utimensat, utimensat_time64, syscalls not available." -#endif - LLVM_LIBC_FUNCTION(int, utimes, (const char *path, const struct timeval times[2])) { int ret; #ifdef SYS_utimes // No need to define a timespec struct, use the syscall directly. - ret = LIBC_NAMESPACE::syscall_impl<int>(UTIMES_SYSCALL_ID, path, times); + ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_utimes, path, times); #elif defined(SYS_utimensat) || defined(SYS_utimensat_time64) + +#if defined(SYS_utimensat) + constexpr auto UTIMES_SYSCALL_ID = SYS_utimensat; +#elif defined(SYS_utimensat_time64) + constexpr auto UTIMES_SYSCALL_ID = SYS_utimensat_time64; +#endif + // the utimensat syscall requires a timespec struct, not timeval. struct timespec ts[2]; struct timespec *ts_ptr = nullptr; // default value if times is nullptr @@ -74,6 +71,9 @@ LLVM_LIBC_FUNCTION(int, utimes, // flags=0 means don't follow symlinks (like utimes) ret = LIBC_NAMESPACE::syscall_impl<int>(UTIMES_SYSCALL_ID, AT_FDCWD, path, ts_ptr, 0); + +#else +#error "utimes, utimensat, utimensat_time64, syscalls not available." #endif // SYS_utimensat if (ret < 0) { diff --git a/libc/src/unistd/linux/setsid.cpp b/libc/src/unistd/linux/setsid.cpp index df4629b..b1a265c 100644 --- a/libc/src/unistd/linux/setsid.cpp +++ b/libc/src/unistd/linux/setsid.cpp @@ -11,6 +11,7 @@ #include "hdr/types/pid_t.h" #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" #include <sys/syscall.h> // For syscall numbers. @@ -18,7 +19,12 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(pid_t, setsid, ()) { - return LIBC_NAMESPACE::syscall_impl<pid_t>(SYS_setsid); + pid_t ret = LIBC_NAMESPACE::syscall_impl<pid_t>(SYS_setsid); + if (ret < 0) { + libc_errno = static_cast<int>(-ret); + return -1; + } + return ret; } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wchar/wcsncmp.cpp b/libc/src/wchar/wcsncmp.cpp index f2e052b..baca12b 100644 --- a/libc/src/wchar/wcsncmp.cpp +++ b/libc/src/wchar/wcsncmp.cpp @@ -30,8 +30,7 @@ LLVM_LIBC_FUNCTION(int, wcsncmp, if (!comp(lc, '\0') || comp(lc, *right)) break; } - return comp(*reinterpret_cast<const wchar_t *>(left), - *reinterpret_cast<const wchar_t *>(right)); + return comp(*left, *right); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wctype/iswalpha.cpp b/libc/src/wctype/iswalpha.cpp index e18f293..09f55d3 100644 --- a/libc/src/wctype/iswalpha.cpp +++ b/libc/src/wctype/iswalpha.cpp @@ -14,6 +14,6 @@ namespace LIBC_NAMESPACE_DECL { -LLVM_LIBC_FUNCTION(bool, iswalpha, (wint_t c)) { return internal::iswalpha(c); } +LLVM_LIBC_FUNCTION(int, iswalpha, (wint_t c)) { return internal::iswalpha(c); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wctype/iswalpha.h b/libc/src/wctype/iswalpha.h index 681fc6b..0353388 100644 --- a/libc/src/wctype/iswalpha.h +++ b/libc/src/wctype/iswalpha.h @@ -14,7 +14,7 @@ namespace LIBC_NAMESPACE_DECL { -bool iswalpha(wint_t c); +int iswalpha(wint_t c); } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/startup/baremetal/aarch64/CMakeLists.txt b/libc/startup/baremetal/aarch64/CMakeLists.txt new file mode 100644 index 0000000..f75bd89 --- /dev/null +++ b/libc/startup/baremetal/aarch64/CMakeLists.txt @@ -0,0 +1,16 @@ +add_startup_object( + crt1 + SRC + start.cpp + DEPENDS + libc.src.stdlib.atexit + libc.src.stdlib.exit + libc.src.string.memcpy + libc.src.string.memset + libc.startup.baremetal.init + libc.startup.baremetal.fini + COMPILE_OPTIONS + -ffreestanding # To avoid compiler warnings about calling the main function. + -fno-builtin + -Wno-global-constructors # To allow vector table initialization +) diff --git a/libc/startup/baremetal/aarch64/start.cpp b/libc/startup/baremetal/aarch64/start.cpp new file mode 100644 index 0000000..ff3ea933 --- /dev/null +++ b/libc/startup/baremetal/aarch64/start.cpp @@ -0,0 +1,112 @@ +//===-- Implementation of crt for aarch64 ---------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "hdr/stdint_proxy.h" +#include "src/__support/macros/config.h" +#include "src/stdlib/atexit.h" +#include "src/stdlib/exit.h" +#include "src/string/memcpy.h" +#include "src/string/memset.h" +#include "startup/baremetal/fini.h" +#include "startup/baremetal/init.h" + +#include <arm_acle.h> + +extern "C" { +int main(int argc, char **argv); +void _start(); + +// Semihosting library initialisation if applicable. Required for printf, etc. +[[gnu::weak]] void _platform_init() {} + +// These symbols are provided by the linker. The exact names are not defined by +// a standard. +extern uintptr_t __stack; +extern uintptr_t __data_source[]; +extern uintptr_t __data_start[]; +extern uintptr_t __data_size[]; +extern uintptr_t __bss_start[]; +extern uintptr_t __bss_size[]; +} // extern "C" + +namespace { +// The Arm ARM for the A-profile architecture (D14.1.5) defines the exceptions. +// However, for simplicity, we don't bother logging, and just exit. +void GenericException_Handler() { LIBC_NAMESPACE::exit(1); } + +// The AArch64 exception vector table has 16 entries, each of which is 128 +// bytes long, and contains code. The whole table must be 2048-byte aligned. +// For our purposes, each entry just contains one branch instruction to the +// exception reporting function, since we never want to resume after an +// exception. +[[gnu::section(".vectors"), gnu::aligned(2048), gnu::used, gnu::naked]] +void vector_table() { +#define VECTOR_TABLE_ENTRY \ + asm(".balign 128"); \ + asm("B %0" : : "X"(GenericException_Handler)); + + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; + VECTOR_TABLE_ENTRY; +} +} // namespace + +namespace LIBC_NAMESPACE_DECL { + +[[noreturn]] void do_start() { + // TODO: This startup code is not extensive, but rather the MVP for QEMU + // testing. + // TODO: Setup memory (MMU, page table, caches) + // TODO: Consider v8-R variants + + // Set up exception handling + __arm_wsr64("VBAR_EL1", reinterpret_cast<uint64_t>(&vector_table)); + +#ifdef __ARM_FP + // Do not trap FP/SME/SVE instructions + static constexpr uint64_t CPACR_SHIFT_FPEN = 20; + static constexpr uint64_t CPACR_SHIFT_SMEN = 24; + uint64_t cpacr = __arm_rsr64("CPACR_EL1"); + cpacr |= (0x3 << CPACR_SHIFT_FPEN); + cpacr |= (0x3 << CPACR_SHIFT_SMEN); + __arm_wsr64("CPACR_EL1", cpacr); +#endif + + // Perform the equivalent of scatterloading + LIBC_NAMESPACE::memcpy(__data_start, __data_source, + reinterpret_cast<uintptr_t>(__data_size)); + LIBC_NAMESPACE::memset(__bss_start, '\0', + reinterpret_cast<uintptr_t>(__bss_size)); + __libc_init_array(); + + _platform_init(); + LIBC_NAMESPACE::atexit(&__libc_fini_array); + LIBC_NAMESPACE::exit(main(0, 0)); +} +} // namespace LIBC_NAMESPACE_DECL + +extern "C" { +[[gnu::section(".text.init.enter"), gnu::naked]] +void _start() { + asm volatile("mov sp, %0" : : "r"(&__stack)); + asm volatile("bl %0" : : "X"(LIBC_NAMESPACE::do_start)); +} +} // extern "C" diff --git a/libc/startup/baremetal/arm/start.cpp b/libc/startup/baremetal/arm/start.cpp index 123efc4..c089a14 100644 --- a/libc/startup/baremetal/arm/start.cpp +++ b/libc/startup/baremetal/arm/start.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/stdint_proxy.h" #include "src/__support/macros/config.h" #include "src/stdlib/atexit.h" #include "src/stdlib/exit.h" @@ -14,7 +15,7 @@ #include "startup/baremetal/fini.h" #include "startup/baremetal/init.h" -#include <stdint.h> +#include <arm_acle.h> // For __arm_wsr extern "C" { int main(int argc, char **argv); @@ -31,7 +32,10 @@ extern uintptr_t __data_start[]; extern uintptr_t __data_size[]; extern uintptr_t __bss_start[]; extern uintptr_t __bss_size[]; +} // extern "C" +namespace { +#if __ARM_ARCH_PROFILE == 'M' // Based on // https://developer.arm.com/documentation/107565/0101/Use-case-examples/Generic-Information/What-is-inside-a-program-image-/Vector-table void NMI_Handler() {} @@ -49,35 +53,89 @@ void SysTick_Handler() {} // to be zero and Cortex-M23 can require up to 10, so 1024-byte align the vector // table. using HandlerType = void (*)(void); -const HandlerType vector_table[] - __attribute__((section(".vectors"), aligned(1024), used)) = { - (HandlerType)&__stack, // SP - _start, // Reset - NMI_Handler, // NMI Handler - HardFault_Handler, // Hard Fault Handlerß - MemManage_Handler, // MPU Fault Han`dler - BusFault_Handler, // Bus Fault Handler - UsageFault_Handler, // Usage Fault Handler - 0, // Reserved - 0, // Reserved - 0, // Reserved - 0, // Reserved - SVC_Handler, // SVC Handler - DebugMon_Handler, // Debug Monitor Handler - 0, // Reserved - PendSV_Handler, // PendSV Handler - SysTick_Handler, // SysTick Handler - // Unused +[[gnu::section(".vectors"), gnu::aligned(1024), gnu::used]] +const HandlerType vector_table[] = { + reinterpret_cast<HandlerType>(&__stack), // SP + _start, // Reset + NMI_Handler, // NMI Handler + HardFault_Handler, // Hard Fault Handler + MemManage_Handler, // MPU Fault Handler + BusFault_Handler, // Bus Fault Handler + UsageFault_Handler, // Usage Fault Handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVC_Handler, // SVC Handler + DebugMon_Handler, // Debug Monitor Handler + 0, // Reserved + PendSV_Handler, // PendSV Handler + SysTick_Handler, // SysTick Handler + // Unused }; -} // extern "C" +#else +// Based on +// https://developer.arm.com/documentation/den0013/0400/Boot-Code/Booting-a-bare-metal-system +void Reset_Handler() { LIBC_NAMESPACE::exit(1); } +void Undefined_Handler() { LIBC_NAMESPACE::exit(1); } +void SWI_Handler() { LIBC_NAMESPACE::exit(1); } +void PrefetchAbort_Handler() { LIBC_NAMESPACE::exit(1); } +void DataAbort_Handler() { LIBC_NAMESPACE::exit(1); } +void IRQ_Handler() { LIBC_NAMESPACE::exit(1); } +void FIQ_Handler() { LIBC_NAMESPACE::exit(1); } + +// The AArch32 exception vector table has 8 entries, each of which is 4 +// bytes long, and contains code. The whole table must be 32-byte aligned. +// The table may also be relocated, so we make it position-independent by +// having a table of handler addresses and loading the address to pc. +[[gnu::section(".vectors"), gnu::aligned(32), gnu::used, gnu::naked, + gnu::target("arm")]] +void vector_table() { + asm("LDR pc, [pc, #24]"); + asm("LDR pc, [pc, #24]"); + asm("LDR pc, [pc, #24]"); + asm("LDR pc, [pc, #24]"); + asm("LDR pc, [pc, #24]"); + asm("LDR pc, [pc, #24]"); + asm("LDR pc, [pc, #24]"); + asm("LDR pc, [pc, #24]"); + asm(".word %c0" : : "X"(Reset_Handler)); + asm(".word %c0" : : "X"(Undefined_Handler)); + asm(".word %c0" : : "X"(SWI_Handler)); + asm(".word %c0" : : "X"(PrefetchAbort_Handler)); + asm(".word %c0" : : "X"(DataAbort_Handler)); + asm(".word %c0" : : "X"(0)); + asm(".word %c0" : : "X"(IRQ_Handler)); + asm(".word %c0" : : "X"(FIQ_Handler)); +} +#endif +} // namespace namespace LIBC_NAMESPACE_DECL { [[noreturn]] void do_start() { // FIXME: set up the QEMU test environment +#if __ARM_ARCH_PROFILE == 'A' || __ARM_ARCH_PROFILE == 'R' + // Set up registers to be used in exception handling + // Copy the current sp value to each of the banked copies of sp. + __arm_wsr("CPSR_c", 0x11); // FIQ + asm volatile("mov sp, %0" : : "r"(__builtin_frame_address(0))); + __arm_wsr("CPSR_c", 0x12); // IRQ + asm volatile("mov sp, %0" : : "r"(__builtin_frame_address(0))); + __arm_wsr("CPSR_c", 0x17); // ABT + asm volatile("mov sp, %0" : : "r"(__builtin_frame_address(0))); + __arm_wsr("CPSR_c", 0x1B); // UND + asm volatile("mov sp, %0" : : "r"(__builtin_frame_address(0))); + __arm_wsr("CPSR_c", 0x1F); // SYS + asm volatile("mov sp, %0" : : "r"(__builtin_frame_address(0))); + __arm_wsr("CPSR_c", 0x13); // SVC +#endif + // Perform the equivalent of scatterloading - LIBC_NAMESPACE::memcpy(__data_start, __data_source, (uintptr_t)__data_size); - LIBC_NAMESPACE::memset(__bss_start, '\0', (uintptr_t)__bss_size); + LIBC_NAMESPACE::memcpy(__data_start, __data_source, + reinterpret_cast<uintptr_t>(__data_size)); + LIBC_NAMESPACE::memset(__bss_start, '\0', + reinterpret_cast<uintptr_t>(__bss_size)); __libc_init_array(); _platform_init(); @@ -86,7 +144,13 @@ namespace LIBC_NAMESPACE_DECL { } } // namespace LIBC_NAMESPACE_DECL -extern "C" void _start() { +extern "C" { +#ifdef __ARM_ARCH_ISA_ARM +// If ARM state is supported, it must be used (instead of Thumb) +[[gnu::naked, gnu::target("arm")]] +#endif +void _start() { asm volatile("mov sp, %0" : : "r"(&__stack)); asm volatile("bl %0" : : "X"(LIBC_NAMESPACE::do_start)); } +} // extern "C" diff --git a/libc/test/IntegrationTest/CMakeLists.txt b/libc/test/IntegrationTest/CMakeLists.txt index 3afe354..235e9fe 100644 --- a/libc/test/IntegrationTest/CMakeLists.txt +++ b/libc/test/IntegrationTest/CMakeLists.txt @@ -13,5 +13,6 @@ add_object_library( DEPENDS libc.hdr.stdint_proxy libc.src.__support.OSUtil.osutil + libc.src.__support.CPP.atomic ${arch_specific_deps} ) diff --git a/libc/test/IntegrationTest/test.cpp b/libc/test/IntegrationTest/test.cpp index 8baf746..19eb255 100644 --- a/libc/test/IntegrationTest/test.cpp +++ b/libc/test/IntegrationTest/test.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// - #include "hdr/stdint_proxy.h" +#include "src/__support/CPP/atomic.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" #include <stddef.h> @@ -63,16 +63,21 @@ int atexit(void (*func)(void)) { return LIBC_NAMESPACE::atexit(func); } // which just hands out continuous blocks from a statically allocated chunk of // memory. -static constexpr uint64_t MEMORY_SIZE = 16384; -static uint8_t memory[MEMORY_SIZE]; -static uint8_t *ptr = memory; +static constexpr uint64_t ALIGNMENT = alignof(double); +static constexpr uint64_t MEMORY_SIZE = 256 * 1024 /* 256 KiB */; +alignas(ALIGNMENT) static uint8_t memory[MEMORY_SIZE]; +static size_t ptr = 0; extern "C" { -void *malloc(size_t s) { - void *mem = ptr; - ptr += s; - return static_cast<uint64_t>(ptr - memory) >= MEMORY_SIZE ? nullptr : mem; +void *malloc(size_t size) { + LIBC_NAMESPACE::cpp::AtomicRef<size_t> ref(ptr); + size = (size + ALIGNMENT - 1) & ~(ALIGNMENT - 1); + size_t old_ptr = + ref.fetch_add(size, LIBC_NAMESPACE::cpp::MemoryOrder::RELAXED); + if (static_cast<size_t>(old_ptr + size) >= MEMORY_SIZE) + return nullptr; + return &memory[old_ptr]; } void free(void *) {} diff --git a/libc/test/UnitTest/CMakeLists.txt b/libc/test/UnitTest/CMakeLists.txt index d92ab6f..f1a83fc 100644 --- a/libc/test/UnitTest/CMakeLists.txt +++ b/libc/test/UnitTest/CMakeLists.txt @@ -125,6 +125,7 @@ add_unittest_framework_library( RoundingModeUtils.h DEPENDS LibcTest + libc.test.UnitTest.ErrnoCheckingTest libc.test.UnitTest.string_utils libc.src.__support.CPP.array libc.src.__support.FPUtil.fp_bits diff --git a/libc/test/UnitTest/FEnvSafeTest.cpp b/libc/test/UnitTest/FEnvSafeTest.cpp index 168b1d4..f644569 100644 --- a/libc/test/UnitTest/FEnvSafeTest.cpp +++ b/libc/test/UnitTest/FEnvSafeTest.cpp @@ -9,8 +9,10 @@ #include "FEnvSafeTest.h" #include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" #include "src/__support/macros/properties/architectures.h" +#include "test/UnitTest/ErrnoCheckingTest.h" namespace LIBC_NAMESPACE_DECL { namespace testing { @@ -25,6 +27,10 @@ void FEnvSafeTest::TearDown() { if (!should_be_unchanged) { restore_fenv(); } + // TODO (PR 135320): Remove this override once all FEnvSafeTest instances are + // updated to validate or ignore errno. + libc_errno = 0; + ErrnoCheckingTest::TearDown(); } void FEnvSafeTest::get_fenv(fenv_t &fenv) { diff --git a/libc/test/UnitTest/FEnvSafeTest.h b/libc/test/UnitTest/FEnvSafeTest.h index a3c5e62..1e10629 100644 --- a/libc/test/UnitTest/FEnvSafeTest.h +++ b/libc/test/UnitTest/FEnvSafeTest.h @@ -12,6 +12,7 @@ #include "hdr/types/fenv_t.h" #include "src/__support/CPP/utility.h" #include "src/__support/macros/config.h" +#include "test/UnitTest/ErrnoCheckingTest.h" #include "test/UnitTest/Test.h" namespace LIBC_NAMESPACE_DECL { @@ -20,7 +21,7 @@ namespace testing { // This provides a test fixture (or base class for other test fixtures) that // asserts that each test does not leave the FPU state represented by `fenv_t` // (aka `FPState`) perturbed from its initial state. -class FEnvSafeTest : public Test { +class FEnvSafeTest : public ErrnoCheckingTest { public: void TearDown() override; diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h index da15cf2..592cd1b 100644 --- a/libc/test/UnitTest/FPMatcher.h +++ b/libc/test/UnitTest/FPMatcher.h @@ -14,8 +14,10 @@ #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/fpbits_str.h" +#include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" #include "src/__support/macros/properties/architectures.h" +#include "test/UnitTest/ErrnoCheckingTest.h" #include "test/UnitTest/RoundingModeUtils.h" #include "test/UnitTest/StringUtils.h" #include "test/UnitTest/Test.h" @@ -166,7 +168,7 @@ CFPMatcher<T, C> getMatcherComplex(T expectedValue) { return CFPMatcher<T, C>(expectedValue); } -template <typename T> struct FPTest : public Test { +template <typename T> struct FPTest : public ErrnoCheckingTest { using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using StorageType = typename FPBits::StorageType; static constexpr StorageType STORAGE_MAX = @@ -191,6 +193,13 @@ template <typename T> struct FPTest : public Test { fputil::testing::RoundingMode::Downward, fputil::testing::RoundingMode::TowardZero, }; + + void TearDown() override { + // TODO (PR 135320): Remove this override once all FPTest instances are + // updated to validate or ignore errno. + libc_errno = 0; + ErrnoCheckingTest::TearDown(); + } }; // Add facility to test Flush-Denormal-To-Zero (FTZ) and Denormal-As-Zero (DAZ) diff --git a/libc/test/integration/src/__support/GPU/CMakeLists.txt b/libc/test/integration/src/__support/GPU/CMakeLists.txt index e066830..1fb175b 100644 --- a/libc/test/integration/src/__support/GPU/CMakeLists.txt +++ b/libc/test/integration/src/__support/GPU/CMakeLists.txt @@ -27,3 +27,16 @@ add_integration_test( LOADER_ARGS --threads 64 ) + +add_libc_test( + fixedstack_test + SUITE + libc-support-gpu-tests + SRCS + fixedstack_test.cpp + DEPENDS + libc.src.__support.GPU.fixedstack + LOADER_ARGS + --threads 32 + --blocks 16 +) diff --git a/libc/test/integration/src/__support/GPU/fixedstack_test.cpp b/libc/test/integration/src/__support/GPU/fixedstack_test.cpp new file mode 100644 index 0000000..fde51df --- /dev/null +++ b/libc/test/integration/src/__support/GPU/fixedstack_test.cpp @@ -0,0 +1,44 @@ +//===-- Integration test for the lock-free stack --------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/__support/GPU/fixedstack.h" +#include "src/__support/GPU/utils.h" +#include "test/IntegrationTest/test.h" + +using namespace LIBC_NAMESPACE; + +static FixedStack<uint32_t, 2048> global_stack; + +void run() { + // We need enough space in the stack as threads in flight can temporarily + // consume memory before they finish comitting it back to the stack. + ASSERT_EQ(gpu::get_num_blocks() * gpu::get_num_threads(), 512); + + uint32_t val; + uint32_t num_threads = static_cast<uint32_t>(gpu::get_num_threads()); + for (int i = 0; i < 256; ++i) { + EXPECT_TRUE(global_stack.push(UINT32_MAX)) + EXPECT_TRUE(global_stack.pop(val)) + ASSERT_TRUE(val < num_threads || val == UINT32_MAX); + } + + EXPECT_TRUE(global_stack.push(static_cast<uint32_t>(gpu::get_thread_id()))); + EXPECT_TRUE(global_stack.push(static_cast<uint32_t>(gpu::get_thread_id()))); + EXPECT_TRUE(global_stack.pop(val)); + ASSERT_TRUE(val < num_threads || val == UINT32_MAX); + + // Fill the rest of the stack with the default value. + while (!global_stack.push(UINT32_MAX)) + ; +} + +TEST_MAIN(int argc, char **argv, char **envp) { + run(); + + return 0; +} diff --git a/libc/test/integration/src/__support/GPU/match.cpp b/libc/test/integration/src/__support/GPU/match.cpp index 2d314c2..70c22b7 100644 --- a/libc/test/integration/src/__support/GPU/match.cpp +++ b/libc/test/integration/src/__support/GPU/match.cpp @@ -21,7 +21,9 @@ static void test_match() { gpu::match_any(mask, gpu::get_lane_id())); EXPECT_EQ(mask, gpu::match_any(mask, 1)); - uint64_t expected = gpu::get_lane_id() < 16 ? 0xffff : 0xffff0000; + uint64_t full_mask = + gpu::get_lane_size() > 32 ? 0xffffffffffffffff : 0xffffffff; + uint64_t expected = gpu::get_lane_id() < 16 ? 0xffff : full_mask & ~0xffff; EXPECT_EQ(expected, gpu::match_any(mask, gpu::get_lane_id() < 16)); EXPECT_EQ(mask, gpu::match_all(mask, 1)); EXPECT_EQ(0ull, gpu::match_all(mask, gpu::get_lane_id())); diff --git a/libc/test/integration/src/__support/threads/CMakeLists.txt b/libc/test/integration/src/__support/threads/CMakeLists.txt index 5a12d28..40e9668 100644 --- a/libc/test/integration/src/__support/threads/CMakeLists.txt +++ b/libc/test/integration/src/__support/threads/CMakeLists.txt @@ -25,3 +25,24 @@ add_integration_test( DEPENDS libc.src.__support.threads.thread ) + +add_integration_test( + main_exit_test + SUITE + libc-support-threads-integration-tests + SRCS + main_exit_test.cpp + DEPENDS + libc.src.__support.threads.thread +) + +add_integration_test( + double_exit_test + SUITE + libc-support-threads-integration-tests + SRCS + double_exit_test.cpp + DEPENDS + libc.src.__support.threads.thread + libc.src.stdlib.exit +) diff --git a/libc/test/integration/src/__support/threads/double_exit_test.cpp b/libc/test/integration/src/__support/threads/double_exit_test.cpp new file mode 100644 index 0000000..86749d9 --- /dev/null +++ b/libc/test/integration/src/__support/threads/double_exit_test.cpp @@ -0,0 +1,33 @@ +//===-- Test handling of thread local data --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/__support/threads/thread.h" +#include "src/stdlib/exit.h" +#include "test/IntegrationTest/test.h" + +extern "C" { +[[gnu::weak]] +void *__dso_handle = nullptr; +int __cxa_thread_atexit_impl(void (*func)(void *), void *arg, void *dso); +} + +int call_num = 0; + +[[gnu::destructor]] +void check() { + // This destructor should be called only once. + if (call_num != 1) + __builtin_trap(); +} + +TEST_MAIN() { + __cxa_thread_atexit_impl([](void *) { LIBC_NAMESPACE::exit(0); }, nullptr, + __dso_handle); + __cxa_thread_atexit_impl([](void *) { ++call_num; }, nullptr, __dso_handle); + LIBC_NAMESPACE::exit(1); +} diff --git a/libc/test/integration/src/__support/threads/main_exit_test.cpp b/libc/test/integration/src/__support/threads/main_exit_test.cpp new file mode 100644 index 0000000..c90e4e5 --- /dev/null +++ b/libc/test/integration/src/__support/threads/main_exit_test.cpp @@ -0,0 +1,30 @@ +//===-- Test handling of thread local data --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/__support/threads/thread.h" +#include "test/IntegrationTest/test.h" + +bool called = false; + +extern "C" { +[[gnu::weak]] +void *__dso_handle = nullptr; +int __cxa_thread_atexit_impl(void (*func)(void *), void *arg, void *dso); +} + +[[gnu::destructor]] +void destructor() { + if (!called) + __builtin_trap(); +} + +TEST_MAIN() { + __cxa_thread_atexit_impl([](void *) { called = true; }, nullptr, + __dso_handle); + return 0; +} diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt index f5ea510..48241d3 100644 --- a/libc/test/shared/CMakeLists.txt +++ b/libc/test/shared/CMakeLists.txt @@ -27,6 +27,14 @@ add_fp_unittest( libc.src.__support.math.atanhf libc.src.__support.math.atanhf16 libc.src.__support.math.cbrt + libc.src.__support.math.cbrtf + libc.src.__support.math.cos + libc.src.__support.math.cosf + libc.src.__support.math.cosf16 + libc.src.__support.math.coshf + libc.src.__support.math.coshf16 + libc.src.__support.math.cospif + libc.src.__support.math.cospif16 libc.src.__support.math.erff libc.src.__support.math.exp libc.src.__support.math.exp10 diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp index 3d64e5e..2e5a2d5 100644 --- a/libc/test/shared/shared_math_test.cpp +++ b/libc/test/shared/shared_math_test.cpp @@ -21,7 +21,9 @@ TEST(LlvmLibcSharedMathTest, AllFloat16) { EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::asinhf16(0.0f16)); EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::atanf16(0.0f16)); EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::atanhf16(0.0f16)); - + EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::cosf16(0.0f16)); + EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::coshf16(0.0f16)); + EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::cospif16(0.0f16)); EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::exp10f16(0.0f16)); EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::expf16(0.0f16)); @@ -49,6 +51,10 @@ TEST(LlvmLibcSharedMathTest, AllFloat) { EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::atan2f(0.0f, 0.0f)); EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::atanf(0.0f)); EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::atanhf(0.0f)); + EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::cbrtf(0.0f)); + EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::cosf(0.0f)); + EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::coshf(0.0f)); + EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::cospif(0.0f)); EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::erff(0.0f)); EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::exp10f(0.0f)); EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::expf(0.0f)); @@ -65,8 +71,9 @@ TEST(LlvmLibcSharedMathTest, AllDouble) { EXPECT_FP_EQ(0x1.921fb54442d18p+0, LIBC_NAMESPACE::shared::acos(0.0)); EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::asin(0.0)); EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::atan(0.0)); - EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::cbrt(0.0)); EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::atan2(0.0, 0.0)); + EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::cbrt(0.0)); + EXPECT_FP_EQ(0x1p+0, LIBC_NAMESPACE::shared::cos(0.0)); EXPECT_FP_EQ(0x1p+0, LIBC_NAMESPACE::shared::exp(0.0)); EXPECT_FP_EQ(0x1p+0, LIBC_NAMESPACE::shared::exp10(0.0)); } diff --git a/libc/test/src/__support/File/file_test.cpp b/libc/test/src/__support/File/file_test.cpp index b3c9f2b..17dad4d 100644 --- a/libc/test/src/__support/File/file_test.cpp +++ b/libc/test/src/__support/File/file_test.cpp @@ -493,3 +493,22 @@ TEST(LlvmLibcFileTest, WriteNothing) { ASSERT_EQ(f_lbf->close(), 0); ASSERT_EQ(f_nbf->close(), 0); } + +TEST(LlvmLibcFileTest, WriteSplit) { + constexpr size_t FILE_BUFFER_SIZE = 8; + char file_buffer[FILE_BUFFER_SIZE]; + StringFile *f = + new_string_file(file_buffer, FILE_BUFFER_SIZE, _IOFBF, false, "w"); + + static constexpr size_t AVAIL = 12; + f->seek(-AVAIL, SEEK_END); + + const char data[] = "hello"; + ASSERT_EQ(sizeof(data) - 1, f->write(data, sizeof(data) - 1).value); + + const char data2[] = " extra data"; + static constexpr size_t WR_EXPECTED = AVAIL - (sizeof(data) - 1); + ASSERT_EQ(WR_EXPECTED, f->write(data2, sizeof(data2) - 1).value); + EXPECT_TRUE(f->error()); + ASSERT_EQ(f->close(), 0); +} diff --git a/libc/test/src/__support/OSUtil/linux/vdso_test.cpp b/libc/test/src/__support/OSUtil/linux/vdso_test.cpp index 2f68470..71892a0 100644 --- a/libc/test/src/__support/OSUtil/linux/vdso_test.cpp +++ b/libc/test/src/__support/OSUtil/linux/vdso_test.cpp @@ -110,8 +110,8 @@ TEST(LlvmLibcOSUtilVDSOTest, RtSigReturn) { using namespace testing::ErrnoSetterMatcher; // must use struct since there is a function of the same name in the same // scope. - struct sigaction sa {}; - struct sigaction old_sa {}; + struct sigaction sa{}; + struct sigaction old_sa{}; sa.sa_handler = sigprof_handler; sa.sa_flags = SA_RESTORER; vdso::TypedSymbol<vdso::VDSOSym::RTSigReturn> symbol; @@ -158,4 +158,30 @@ TEST(LlvmLibcOSUtilVDSOTest, RiscvHwProbe) { } } +TEST(LlvmLibcOSUtilVDSOTest, GetRandom) { + using namespace testing::ErrnoSetterMatcher; + vdso::TypedSymbol<vdso::VDSOSym::GetRandom> symbol; + if (!symbol) + return; + // This structure exists in kernel UAPI header; but we define it on our own to + // make sure we can test it even on platform without support. + struct VGetrandomOpaqueParams { + uint32_t size_of_opaque_states; + uint32_t mmap_prot; + uint32_t mmap_flags; + uint32_t reserved[13]; + }; + VGetrandomOpaqueParams param{0, 0, 0, {}}; + // When getrandom vDSO symbol is called with special parameters (~0 for state + // size), it populates the desired configuration into VGetrandomOpaqueParams. + int res = symbol( + /*buf=*/nullptr, /*count=*/0, /*flags=*/0, + /*opaque_states=*/¶m, + /*size_of_opaque_states=*/~0); + // Test that the size of the states are correctly populated after a successful + // call. + EXPECT_EQ(res, 0); + EXPECT_GT(param.size_of_opaque_states, 0u); +} + } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/src/__support/wchar/string_converter_test.cpp b/libc/test/src/__support/wchar/string_converter_test.cpp index d514df9..e45358d 100644 --- a/libc/test/src/__support/wchar/string_converter_test.cpp +++ b/libc/test/src/__support/wchar/string_converter_test.cpp @@ -34,32 +34,32 @@ TEST(LlvmLibcStringConverterTest, UTF8To32) { LIBC_NAMESPACE::internal::StringConverter<char8_t> sc( reinterpret_cast<const char8_t *>(src), &state, SIZE_MAX); - auto res = sc.popUTF32(); + auto res = sc.pop<char32_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0x1f921); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 4); - res = sc.popUTF32(); + res = sc.pop<char32_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0x2211); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 7); - res = sc.popUTF32(); + res = sc.pop<char32_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xff); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 9); - res = sc.popUTF32(); + res = sc.pop<char32_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0x41); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 10); - res = sc.popUTF32(); + res = sc.pop<char32_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 11); - res = sc.popUTF32(); + res = sc.pop<char32_t>(); ASSERT_FALSE(res.has_value()); ASSERT_EQ(res.error(), -1); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 11); @@ -75,66 +75,66 @@ TEST(LlvmLibcStringConverterTest, UTF32To8) { LIBC_NAMESPACE::internal::StringConverter<char32_t> sc( reinterpret_cast<const char32_t *>(src), &state, SIZE_MAX); - auto res = sc.popUTF8(); + auto res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xF0); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0x9F); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xA4); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xA1); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); // end of clown emoji, sigma symbol begins - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xE2); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 2); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0x88); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 2); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0x91); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 2); // end of sigma symbol, y with diaeresis begins - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xC3); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 3); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xBF); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 3); // end of y with diaeresis, letter A begins - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0x41); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 4); // null byte - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 5); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_FALSE(res.has_value()); ASSERT_EQ(res.error(), -1); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 5); @@ -148,28 +148,28 @@ TEST(LlvmLibcStringConverterTest, UTF32To8PartialRead) { LIBC_NAMESPACE::internal::StringConverter<char32_t> sc( reinterpret_cast<const char32_t *>(src), &state, SIZE_MAX, 1); - auto res = sc.popUTF8(); + auto res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xF0); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0x9F); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xA4); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xA1); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); // can only read 1 character from source string, so error on next pop - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_FALSE(res.has_value()); ASSERT_EQ(res.error(), -1); } @@ -181,12 +181,12 @@ TEST(LlvmLibcStringConverterTest, UTF8To32PartialRead) { LIBC_NAMESPACE::internal::StringConverter<char8_t> sc( reinterpret_cast<const char8_t *>(src), &state, SIZE_MAX, 5); - auto res = sc.popUTF32(); + auto res = sc.pop<char32_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0x1f921); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 4); - res = sc.popUTF32(); + res = sc.pop<char32_t>(); ASSERT_FALSE(res.has_value()); ASSERT_EQ(static_cast<int>(res.error()), -1); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 5); @@ -200,27 +200,27 @@ TEST(LlvmLibcStringConverterTest, UTF32To8ErrorHandling) { LIBC_NAMESPACE::internal::StringConverter<char32_t> sc( reinterpret_cast<const char32_t *>(src), &state, SIZE_MAX); - auto res = sc.popUTF8(); + auto res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xF0); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0x9F); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xA4); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xA1); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_FALSE(res.has_value()); ASSERT_EQ(static_cast<int>(res.error()), EILSEQ); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); @@ -234,12 +234,12 @@ TEST(LlvmLibcStringConverterTest, UTF8To32ErrorHandling) { LIBC_NAMESPACE::internal::StringConverter<char8_t> sc( reinterpret_cast<const char8_t *>(src), &state, SIZE_MAX); - auto res = sc.popUTF32(); + auto res = sc.pop<char32_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0x1f921); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 4); - res = sc.popUTF32(); + res = sc.pop<char32_t>(); ASSERT_FALSE(res.has_value()); ASSERT_EQ(static_cast<int>(res.error()), EILSEQ); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 4); @@ -257,12 +257,12 @@ TEST(LlvmLibcStringConverterTest, InvalidCharacterOutsideBounds) { LIBC_NAMESPACE::internal::StringConverter<char8_t> sc1( reinterpret_cast<const char8_t *>(src1), &ps1, 1); - auto res1 = sc1.popUTF32(); + auto res1 = sc1.pop<char32_t>(); ASSERT_TRUE(res1.has_value()); ASSERT_EQ(static_cast<int>(res1.value()), 0x1f921); ASSERT_EQ(static_cast<int>(sc1.getSourceIndex()), 4); - res1 = sc1.popUTF32(); + res1 = sc1.pop<char32_t>(); ASSERT_FALSE(res1.has_value()); // no space to write error NOT invalid character error (EILSEQ) ASSERT_EQ(static_cast<int>(res1.error()), -1); @@ -275,27 +275,27 @@ TEST(LlvmLibcStringConverterTest, InvalidCharacterOutsideBounds) { LIBC_NAMESPACE::internal::StringConverter<char32_t> sc2( reinterpret_cast<const char32_t *>(src2), &ps2, 4); - auto res2 = sc2.popUTF8(); + auto res2 = sc2.pop<char8_t>(); ASSERT_TRUE(res2.has_value()); ASSERT_EQ(static_cast<int>(res2.value()), 0xF0); ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 1); - res2 = sc2.popUTF8(); + res2 = sc2.pop<char8_t>(); ASSERT_TRUE(res2.has_value()); ASSERT_EQ(static_cast<int>(res2.value()), 0x9F); ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 1); - res2 = sc2.popUTF8(); + res2 = sc2.pop<char8_t>(); ASSERT_TRUE(res2.has_value()); ASSERT_EQ(static_cast<int>(res2.value()), 0xA4); ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 1); - res2 = sc2.popUTF8(); + res2 = sc2.pop<char8_t>(); ASSERT_TRUE(res2.has_value()); ASSERT_EQ(static_cast<int>(res2.value()), 0xA1); ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 1); - res2 = sc2.popUTF8(); + res2 = sc2.pop<char8_t>(); ASSERT_FALSE(res2.has_value()); // no space to write error NOT invalid character error (EILSEQ) ASSERT_EQ(static_cast<int>(res2.error()), -1); @@ -315,22 +315,22 @@ TEST(LlvmLibcStringConverterTest, MultipleStringConverters32To8) { LIBC_NAMESPACE::internal::StringConverter<char32_t> sc1( reinterpret_cast<const char32_t *>(src), &state, SIZE_MAX, 1); - auto res = sc1.popUTF8(); + auto res = sc1.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xF0); ASSERT_EQ(static_cast<int>(sc1.getSourceIndex()), 1); - res = sc1.popUTF8(); + res = sc1.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0x9F); ASSERT_EQ(static_cast<int>(sc1.getSourceIndex()), 1); - res = sc1.popUTF8(); + res = sc1.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xA4); ASSERT_EQ(static_cast<int>(sc1.getSourceIndex()), 1); - res = sc1.popUTF8(); + res = sc1.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xA1); ASSERT_EQ(static_cast<int>(sc1.getSourceIndex()), 1); @@ -340,12 +340,12 @@ TEST(LlvmLibcStringConverterTest, MultipleStringConverters32To8) { reinterpret_cast<const char32_t *>(src) + sc1.getSourceIndex(), &state, SIZE_MAX, 1); - res = sc2.popUTF8(); + res = sc2.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xC3); ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 1); - res = sc2.popUTF8(); + res = sc2.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0xBF); ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 1); @@ -357,7 +357,7 @@ TEST(LlvmLibcStringConverterTest, MultipleStringConverters8To32) { LIBC_NAMESPACE::internal::StringConverter<char8_t> sc1( reinterpret_cast<const char8_t *>(src), &state, SIZE_MAX, 2); - auto res = sc1.popUTF32(); + auto res = sc1.pop<char32_t>(); ASSERT_FALSE(res.has_value()); ASSERT_EQ(static_cast<int>(res.error()), -1); ASSERT_EQ(static_cast<int>(sc1.getSourceIndex()), 2); @@ -367,12 +367,12 @@ TEST(LlvmLibcStringConverterTest, MultipleStringConverters8To32) { reinterpret_cast<const char8_t *>(src) + sc1.getSourceIndex(), &state, SIZE_MAX, 3); - res = sc2.popUTF32(); + res = sc2.pop<char32_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0x1f921); ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 2); - res = sc2.popUTF32(); + res = sc2.pop<char32_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(res.value()), 0); ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 3); @@ -384,11 +384,11 @@ TEST(LlvmLibcStringConverterTest, DestLimitUTF8To32) { LIBC_NAMESPACE::internal::StringConverter<char8_t> sc( reinterpret_cast<const char8_t *>(src), &state, 1); - auto res = sc.popUTF32(); + auto res = sc.pop<char32_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 4); - res = sc.popUTF32(); // no space to pop this into + res = sc.pop<char32_t>(); // no space to pop this into ASSERT_FALSE(res.has_value()); } @@ -399,23 +399,23 @@ TEST(LlvmLibcStringConverterTest, DestLimitUTF32To8) { LIBC_NAMESPACE::internal::StringConverter<char32_t> sc( reinterpret_cast<const char32_t *>(src), &state, 5); - auto res = sc.popUTF8(); + auto res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_TRUE(res.has_value()); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); - res = sc.popUTF8(); + res = sc.pop<char8_t>(); ASSERT_FALSE(res.has_value()); ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1); } diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt index 43cde0d..4e5563b 100644 --- a/libc/test/src/math/CMakeLists.txt +++ b/libc/test/src/math/CMakeLists.txt @@ -669,6 +669,25 @@ add_fp_unittest( ) add_fp_unittest( + lroundbf16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + lroundbf16_test.cpp + HDRS + RoundToIntegerTest.h + DEPENDS + libc.hdr.fenv_macros + libc.src.errno.errno + libc.src.math.lroundbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( llround_test NEED_MPFR SUITE @@ -741,6 +760,25 @@ add_fp_unittest( ) add_fp_unittest( + llroundbf16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + llroundbf16_test.cpp + HDRS + RoundToIntegerTest.h + DEPENDS + libc.hdr.fenv_macros + libc.src.errno.errno + libc.src.math.llroundbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( nearbyint_test NEED_MPFR SUITE @@ -801,6 +839,22 @@ add_fp_unittest( ) add_fp_unittest( + nearbyintbf16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + nearbyintbf16_test.cpp + HDRS + NearbyIntTest.h + DEPENDS + libc.src.math.nearbyintbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.CPP.array + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( rint_test NEED_MPFR SUITE @@ -869,6 +923,24 @@ add_fp_unittest( ) add_fp_unittest( + rintbf16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + rintbf16_test.cpp + HDRS + RIntTest.h + DEPENDS + libc.hdr.fenv_macros + libc.src.math.rintbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( lrint_test NEED_MPFR SUITE @@ -933,6 +1005,23 @@ add_fp_unittest( ) add_fp_unittest( + lrintbf16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + lrintbf16_test.cpp + HDRS + RoundToIntegerTest.h + DEPENDS + libc.src.math.lrintbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( llrint_test NEED_MPFR SUITE @@ -997,6 +1086,23 @@ add_fp_unittest( ) add_fp_unittest( + llrintbf16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + llrintbf16_test.cpp + HDRS + RoundToIntegerTest.h + DEPENDS + libc.src.math.llrintbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( exp_test NEED_MPFR SUITE @@ -2170,6 +2276,17 @@ add_fp_unittest( ) add_fp_unittest( + atanpif16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + atanpif16_test.cpp + DEPENDS + libc.src.math.atanpif16 +) + +add_fp_unittest( fmul_test NEED_MPFR SUITE @@ -2283,6 +2400,17 @@ add_fp_unittest( ) add_fp_unittest( + asinpif16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + asinpif16_test.cpp + DEPENDS + libc.src.math.asinpif16 +) + +add_fp_unittest( acosf_test NEED_MPFR SUITE @@ -2972,6 +3100,302 @@ add_fp_unittest( libc.src.__support.macros.properties.types ) +add_fp_unittest( + bf16add_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16add_test.cpp + HDRS + AddTest.h + DEPENDS + libc.src.math.bf16add + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16addf_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16addf_test.cpp + HDRS + AddTest.h + DEPENDS + libc.src.math.bf16addf + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16addl_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16addl_test.cpp + HDRS + AddTest.h + DEPENDS + libc.src.math.bf16addl + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16addf128_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16addf128_test.cpp + HDRS + AddTest.h + DEPENDS + libc.src.math.bf16addf128 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16div_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16div_test.cpp + HDRS + DivTest.h + DEPENDS + libc.src.math.bf16div + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16divf_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16divf_test.cpp + HDRS + DivTest.h + DEPENDS + libc.src.math.bf16divf + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16divl_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16divl_test.cpp + HDRS + DivTest.h + DEPENDS + libc.src.math.bf16divl + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16divf128_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16divf128_test.cpp + HDRS + DivTest.h + DEPENDS + libc.src.math.bf16divf128 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16fma_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16fma_test.cpp + HDRS + FmaTest.h + DEPENDS + libc.src.math.bf16fma + libc.src.stdlib.rand + libc.src.stdlib.srand + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16fmaf_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16fmaf_test.cpp + HDRS + FmaTest.h + DEPENDS + libc.src.math.bf16fmaf + libc.src.stdlib.rand + libc.src.stdlib.srand + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16fmal_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16fmal_test.cpp + HDRS + FmaTest.h + DEPENDS + libc.src.math.bf16fmal + libc.src.stdlib.rand + libc.src.stdlib.srand + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16fmaf128_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16fmaf128_test.cpp + HDRS + FmaTest.h + DEPENDS + libc.src.math.bf16fmaf128 + libc.src.stdlib.rand + libc.src.stdlib.srand + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16mul_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16mul_test.cpp + HDRS + MulTest.h + DEPENDS + libc.src.math.bf16mul + libc.src.stdlib.rand + libc.src.stdlib.srand + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16mulf_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16mulf_test.cpp + HDRS + MulTest.h + DEPENDS + libc.src.math.bf16mulf + libc.src.stdlib.rand + libc.src.stdlib.srand + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16mull_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16mull_test.cpp + HDRS + MulTest.h + DEPENDS + libc.src.math.bf16mull + libc.src.stdlib.rand + libc.src.stdlib.srand + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16mulf128_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16mulf128_test.cpp + HDRS + MulTest.h + DEPENDS + libc.src.math.bf16mulf128 + libc.src.stdlib.rand + libc.src.stdlib.srand + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16sub_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16sub_test.cpp + HDRS + SubTest.h + DEPENDS + libc.src.math.bf16sub + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16subf_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16subf_test.cpp + HDRS + SubTest.h + DEPENDS + libc.src.math.bf16subf + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16subl_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16subl_test.cpp + HDRS + SubTest.h + DEPENDS + libc.src.math.bf16subl + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16subf128_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + bf16subf128_test.cpp + HDRS + SubTest.h + DEPENDS + libc.src.math.bf16subf128 + libc.src.__support.FPUtil.bfloat16 +) + add_subdirectory(generic) add_subdirectory(smoke) diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h index 6af9cfe..e5e9386 100644 --- a/libc/test/src/math/RoundToIntegerTest.h +++ b/libc/test/src/math/RoundToIntegerTest.h @@ -127,8 +127,8 @@ public: test_one_input(func, FloatType(-1.0), IntType(-1), false); test_one_input(func, FloatType(10.0), IntType(10), false); test_one_input(func, FloatType(-10.0), IntType(-10), false); - test_one_input(func, FloatType(1234.0), IntType(1234), false); - test_one_input(func, FloatType(-1234.0), IntType(-1234), false); + test_one_input(func, FloatType(1232.0), IntType(1232), false); + test_one_input(func, FloatType(-1232.0), IntType(-1232), false); // The rest of this function compares with an equivalent MPFR function // which rounds floating point numbers to long values. There is no MPFR diff --git a/libc/test/src/math/asinpif16_test.cpp b/libc/test/src/math/asinpif16_test.cpp new file mode 100644 index 0000000..3718f39 --- /dev/null +++ b/libc/test/src/math/asinpif16_test.cpp @@ -0,0 +1,40 @@ +//===-- Exhaustive test for asinpif16 -------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/asinpif16.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +using LlvmLibcAsinpif16Test = LIBC_NAMESPACE::testing::FPTest<float16>; + +namespace mpfr = LIBC_NAMESPACE::testing::mpfr; + +// Range: [0, Inf] +static constexpr uint16_t POS_START = 0x0000U; +static constexpr uint16_t POS_STOP = 0x7c00U; + +// Range: [-Inf, 0] +static constexpr uint16_t NEG_START = 0x8000U; +static constexpr uint16_t NEG_STOP = 0xfc00U; + +TEST_F(LlvmLibcAsinpif16Test, PositiveRange) { + for (uint16_t v = POS_START; v <= POS_STOP; ++v) { + float16 x = FPBits(v).get_val(); + EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Asinpi, x, + LIBC_NAMESPACE::asinpif16(x), 0.5); + } +} + +TEST_F(LlvmLibcAsinpif16Test, NegativeRange) { + for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) { + float16 x = FPBits(v).get_val(); + EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Asinpi, x, + LIBC_NAMESPACE::asinpif16(x), 0.5); + } +} diff --git a/libc/test/src/math/atanpif16_test.cpp b/libc/test/src/math/atanpif16_test.cpp new file mode 100644 index 0000000..38771f0 --- /dev/null +++ b/libc/test/src/math/atanpif16_test.cpp @@ -0,0 +1,40 @@ +//===-- Exhaustive test for atanpif16 -------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/math/atanpif16.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +using LlvmLibcAtanpif16Test = LIBC_NAMESPACE::testing::FPTest<float16>; + +namespace mpfr = LIBC_NAMESPACE::testing::mpfr; + +// Range: [0, Inf] +static constexpr uint16_t POS_START = 0x0000U; +static constexpr uint16_t POS_STOP = 0x7c00U; + +// Range: [-Inf, 0] +static constexpr uint16_t NEG_START = 0x8000U; +static constexpr uint16_t NEG_STOP = 0xfc00U; + +TEST_F(LlvmLibcAtanpif16Test, PositiveRange) { + for (uint16_t v = POS_START; v <= POS_STOP; ++v) { + float16 x = FPBits(v).get_val(); + EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atanpi, x, + LIBC_NAMESPACE::atanpif16(x), 0.5); + } +} + +TEST_F(LlvmLibcAtanpif16Test, NegativeRange) { + for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) { + float16 x = FPBits(v).get_val(); + EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atanpi, x, + LIBC_NAMESPACE::atanpif16(x), 0.5); + } +} diff --git a/libc/test/src/math/bf16add_test.cpp b/libc/test/src/math/bf16add_test.cpp new file mode 100644 index 0000000..9e9c594 --- /dev/null +++ b/libc/test/src/math/bf16add_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16add ---------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "AddTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16add.h" + +LIST_ADD_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16add) diff --git a/libc/test/src/math/bf16addf128_test.cpp b/libc/test/src/math/bf16addf128_test.cpp new file mode 100644 index 0000000..46f7ad3 --- /dev/null +++ b/libc/test/src/math/bf16addf128_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16addf128 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "AddTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16addf128.h" + +LIST_ADD_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16addf128) diff --git a/libc/test/src/math/bf16addf_test.cpp b/libc/test/src/math/bf16addf_test.cpp new file mode 100644 index 0000000..06d56cf --- /dev/null +++ b/libc/test/src/math/bf16addf_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16addf --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "AddTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16addf.h" + +LIST_ADD_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16addf) diff --git a/libc/test/src/math/bf16addl_test.cpp b/libc/test/src/math/bf16addl_test.cpp new file mode 100644 index 0000000..bf54827 --- /dev/null +++ b/libc/test/src/math/bf16addl_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16addl --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "AddTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16addl.h" + +LIST_ADD_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16addl) diff --git a/libc/test/src/math/bf16div_test.cpp b/libc/test/src/math/bf16div_test.cpp new file mode 100644 index 0000000..4516351 --- /dev/null +++ b/libc/test/src/math/bf16div_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16div ---------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "DivTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16div.h" + +LIST_DIV_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16div) diff --git a/libc/test/src/math/bf16divf128_test.cpp b/libc/test/src/math/bf16divf128_test.cpp new file mode 100644 index 0000000..c42c5bb --- /dev/null +++ b/libc/test/src/math/bf16divf128_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16divf128 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "DivTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16divf128.h" + +LIST_DIV_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16divf128) diff --git a/libc/test/src/math/bf16divf_test.cpp b/libc/test/src/math/bf16divf_test.cpp new file mode 100644 index 0000000..873920b --- /dev/null +++ b/libc/test/src/math/bf16divf_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16divf --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "DivTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16divf.h" + +LIST_DIV_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16divf) diff --git a/libc/test/src/math/bf16divl_test.cpp b/libc/test/src/math/bf16divl_test.cpp new file mode 100644 index 0000000..32ecd62 --- /dev/null +++ b/libc/test/src/math/bf16divl_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16divl --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "DivTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16divl.h" + +LIST_DIV_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16divl) diff --git a/libc/test/src/math/bf16fma_test.cpp b/libc/test/src/math/bf16fma_test.cpp new file mode 100644 index 0000000..81c73a0c --- /dev/null +++ b/libc/test/src/math/bf16fma_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16fma ---------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FmaTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16fma.h" + +LIST_NARROWING_FMA_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16fma) diff --git a/libc/test/src/math/bf16fmaf128_test.cpp b/libc/test/src/math/bf16fmaf128_test.cpp new file mode 100644 index 0000000..dd8f473 --- /dev/null +++ b/libc/test/src/math/bf16fmaf128_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16fmaf128 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FmaTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16fmaf128.h" + +LIST_NARROWING_FMA_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16fmaf128) diff --git a/libc/test/src/math/bf16fmaf_test.cpp b/libc/test/src/math/bf16fmaf_test.cpp new file mode 100644 index 0000000..04c6748 --- /dev/null +++ b/libc/test/src/math/bf16fmaf_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16fmaf --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FmaTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16fmaf.h" + +LIST_NARROWING_FMA_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16fmaf) diff --git a/libc/test/src/math/bf16fmal_test.cpp b/libc/test/src/math/bf16fmal_test.cpp new file mode 100644 index 0000000..4c45e2c --- /dev/null +++ b/libc/test/src/math/bf16fmal_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16fmal --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FmaTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16fmal.h" + +LIST_NARROWING_FMA_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16fmal) diff --git a/libc/test/src/math/bf16mul_test.cpp b/libc/test/src/math/bf16mul_test.cpp new file mode 100644 index 0000000..3682705 --- /dev/null +++ b/libc/test/src/math/bf16mul_test.cpp @@ -0,0 +1,15 @@ +//===-- Unittests for bf16mul ---------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "MulTest.h" + +#include "src/math/bf16mul.h" + +#include "src/__support/FPUtil/bfloat16.h" + +LIST_MUL_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16mul) diff --git a/libc/test/src/math/bf16mulf128_test.cpp b/libc/test/src/math/bf16mulf128_test.cpp new file mode 100644 index 0000000..6aee2687 --- /dev/null +++ b/libc/test/src/math/bf16mulf128_test.cpp @@ -0,0 +1,15 @@ +//===-- Unittests for bf16mulf128 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "MulTest.h" + +#include "src/math/bf16mulf128.h" + +#include "src/__support/FPUtil/bfloat16.h" + +LIST_MUL_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16mulf128) diff --git a/libc/test/src/math/bf16mulf_test.cpp b/libc/test/src/math/bf16mulf_test.cpp new file mode 100644 index 0000000..048b60f --- /dev/null +++ b/libc/test/src/math/bf16mulf_test.cpp @@ -0,0 +1,15 @@ +//===-- Unittests for bf16mulf --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "MulTest.h" + +#include "src/math/bf16mulf.h" + +#include "src/__support/FPUtil/bfloat16.h" + +LIST_MUL_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16mulf) diff --git a/libc/test/src/math/bf16mull_test.cpp b/libc/test/src/math/bf16mull_test.cpp new file mode 100644 index 0000000..b8439b2 --- /dev/null +++ b/libc/test/src/math/bf16mull_test.cpp @@ -0,0 +1,15 @@ +//===-- Unittests for bf16mull --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "MulTest.h" + +#include "src/math/bf16mull.h" + +#include "src/__support/FPUtil/bfloat16.h" + +LIST_MUL_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16mull) diff --git a/libc/test/src/math/bf16sub_test.cpp b/libc/test/src/math/bf16sub_test.cpp new file mode 100644 index 0000000..4a793dc --- /dev/null +++ b/libc/test/src/math/bf16sub_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16sub ---------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "SubTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16sub.h" + +LIST_SUB_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16sub) diff --git a/libc/test/src/math/bf16subf128_test.cpp b/libc/test/src/math/bf16subf128_test.cpp new file mode 100644 index 0000000..25d6711 --- /dev/null +++ b/libc/test/src/math/bf16subf128_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16subf128 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "SubTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16subf128.h" + +LIST_SUB_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16subf128) diff --git a/libc/test/src/math/bf16subf_test.cpp b/libc/test/src/math/bf16subf_test.cpp new file mode 100644 index 0000000..e8c7440 --- /dev/null +++ b/libc/test/src/math/bf16subf_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16subf --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "SubTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16subf.h" + +LIST_SUB_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16subf) diff --git a/libc/test/src/math/bf16subl_test.cpp b/libc/test/src/math/bf16subl_test.cpp new file mode 100644 index 0000000..2997369 --- /dev/null +++ b/libc/test/src/math/bf16subl_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16subl --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "SubTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16subl.h" + +LIST_SUB_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16subl) diff --git a/libc/test/src/math/exhaustive/CMakeLists.txt b/libc/test/src/math/exhaustive/CMakeLists.txt index 5246337..07c36f424 100644 --- a/libc/test/src/math/exhaustive/CMakeLists.txt +++ b/libc/test/src/math/exhaustive/CMakeLists.txt @@ -378,6 +378,22 @@ add_fp_unittest( ) add_fp_unittest( + fmodbf16_test + NO_RUN_POSTBUILD + NEED_MPFR + SUITE + libc_math_exhaustive_tests + SRCS + fmodbf16_test.cpp + DEPENDS + .exhaustive_test + libc.src.math.fmodbf16 + libc.src.__support.FPUtil.bfloat16 + LINK_LIBRARIES + -lpthread +) + +add_fp_unittest( coshf_test NO_RUN_POSTBUILD NEED_MPFR @@ -567,3 +583,75 @@ add_fp_unittest( LINK_LIBRARIES -lpthread ) + +add_fp_unittest( + bfloat16_add_test + NO_RUN_POSTBUILD + NEED_MPFR + SUITE + libc_math_exhaustive_tests + SRCS + bfloat16_add_test.cpp + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + .exhaustive_test + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits + LINK_LIBRARIES + -lpthread +) + +add_fp_unittest( + bfloat16_div_test + NO_RUN_POSTBUILD + NEED_MPFR + SUITE + libc_math_exhaustive_tests + SRCS + bfloat16_div_test.cpp + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + .exhaustive_test + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits + LINK_LIBRARIES + -lpthread +) + +add_fp_unittest( + bfloat16_mul_test + NO_RUN_POSTBUILD + NEED_MPFR + SUITE + libc_math_exhaustive_tests + SRCS + bfloat16_mul_test.cpp + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + .exhaustive_test + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits + LINK_LIBRARIES + -lpthread +) + +add_fp_unittest( + bfloat16_sub_test + NO_RUN_POSTBUILD + NEED_MPFR + SUITE + libc_math_exhaustive_tests + SRCS + bfloat16_sub_test.cpp + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + .exhaustive_test + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits + LINK_LIBRARIES + -lpthread +) diff --git a/libc/test/src/math/exhaustive/bfloat16_add_test.cpp b/libc/test/src/math/exhaustive/bfloat16_add_test.cpp new file mode 100644 index 0000000..3f4c779 --- /dev/null +++ b/libc/test/src/math/exhaustive/bfloat16_add_test.cpp @@ -0,0 +1,65 @@ +//===-- Exhaustive tests for bfloat16 addition ----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "exhaustive_test.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "test/UnitTest/FPMatcher.h" +#include "utils/MPFRWrapper/MPCommon.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +namespace mpfr = LIBC_NAMESPACE::testing::mpfr; +using LIBC_NAMESPACE::fputil::BFloat16; + +static BFloat16 add_func(BFloat16 x, BFloat16 y) { return x + y; } + +struct Bfloat16AddChecker : public virtual LIBC_NAMESPACE::testing::Test { + using FloatType = BFloat16; + using FPBits = LIBC_NAMESPACE::fputil::FPBits<bfloat16>; + using StorageType = typename FPBits::StorageType; + + uint64_t check(uint16_t x_start, uint16_t x_stop, uint16_t y_start, + uint16_t y_stop, mpfr::RoundingMode rounding) { + mpfr::ForceRoundingMode r(rounding); + if (!r.success) + return true; + uint16_t xbits = x_start; + uint64_t failed = 0; + do { + BFloat16 x = FPBits(xbits).get_val(); + uint16_t ybits = xbits; + do { + BFloat16 y = FPBits(ybits).get_val(); + mpfr::BinaryInput<BFloat16> input{x, y}; + bool correct = TEST_MPFR_MATCH_ROUNDING_SILENTLY( + mpfr::Operation::Add, input, add_func(x, y), 0.5, rounding); + failed += (!correct); + } while (ybits++ < y_stop); + } while (xbits++ < x_stop); + return failed; + } +}; + +using LlvmLibcBfloat16ExhaustiveAddTest = + LlvmLibcExhaustiveMathTest<Bfloat16AddChecker, 1 << 2>; + +// range: [0, inf] +static constexpr uint16_t POS_START = 0x0000U; +static constexpr uint16_t POS_STOP = 0x7f80U; + +// range: [-0, -inf] +static constexpr uint16_t NEG_START = 0x8000U; +static constexpr uint16_t NEG_STOP = 0xff80U; + +TEST_F(LlvmLibcBfloat16ExhaustiveAddTest, PositiveRange) { + test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP); +} + +TEST_F(LlvmLibcBfloat16ExhaustiveAddTest, NegativeRange) { + test_full_range_all_roundings(NEG_START, NEG_STOP, NEG_START, NEG_STOP); +} diff --git a/libc/test/src/math/exhaustive/bfloat16_div_test.cpp b/libc/test/src/math/exhaustive/bfloat16_div_test.cpp new file mode 100644 index 0000000..2648d5f --- /dev/null +++ b/libc/test/src/math/exhaustive/bfloat16_div_test.cpp @@ -0,0 +1,65 @@ +//===-- Exhaustive tests for bfloat16 division ----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "exhaustive_test.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "test/UnitTest/FPMatcher.h" +#include "utils/MPFRWrapper/MPCommon.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +namespace mpfr = LIBC_NAMESPACE::testing::mpfr; +using LIBC_NAMESPACE::fputil::BFloat16; + +static BFloat16 div_func(BFloat16 x, BFloat16 y) { return x / y; } + +struct Bfloat16DivChecker : public virtual LIBC_NAMESPACE::testing::Test { + using FloatType = BFloat16; + using FPBits = LIBC_NAMESPACE::fputil::FPBits<bfloat16>; + using StorageType = typename FPBits::StorageType; + + uint64_t check(uint16_t x_start, uint16_t x_stop, uint16_t y_start, + uint16_t y_stop, mpfr::RoundingMode rounding) { + mpfr::ForceRoundingMode r(rounding); + if (!r.success) + return true; + uint16_t xbits = x_start; + uint64_t failed = 0; + do { + BFloat16 x = FPBits(xbits).get_val(); + uint16_t ybits = xbits; + do { + BFloat16 y = FPBits(ybits).get_val(); + mpfr::BinaryInput<BFloat16> input{x, y}; + bool correct = TEST_MPFR_MATCH_ROUNDING_SILENTLY( + mpfr::Operation::Div, input, div_func(x, y), 0.5, rounding); + failed += (!correct); + } while (ybits++ < y_stop); + } while (xbits++ < x_stop); + return failed; + } +}; + +using LlvmLibcBfloat16ExhaustiveDivTest = + LlvmLibcExhaustiveMathTest<Bfloat16DivChecker, 1 << 2>; + +// range: [0, inf] +static constexpr uint16_t POS_START = 0x0000U; +static constexpr uint16_t POS_STOP = 0x7f80U; + +// range: [-0, -inf] +static constexpr uint16_t NEG_START = 0x8000U; +static constexpr uint16_t NEG_STOP = 0xff80U; + +TEST_F(LlvmLibcBfloat16ExhaustiveDivTest, PositiveRange) { + test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP); +} + +TEST_F(LlvmLibcBfloat16ExhaustiveDivTest, NegativeRange) { + test_full_range_all_roundings(NEG_START, NEG_STOP, NEG_START, NEG_STOP); +} diff --git a/libc/test/src/math/exhaustive/bfloat16_mul_test.cpp b/libc/test/src/math/exhaustive/bfloat16_mul_test.cpp new file mode 100644 index 0000000..3cbbcb5 --- /dev/null +++ b/libc/test/src/math/exhaustive/bfloat16_mul_test.cpp @@ -0,0 +1,65 @@ +//===-- Exhaustive tests for bfloat16 multiplication ----------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "exhaustive_test.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "test/UnitTest/FPMatcher.h" +#include "utils/MPFRWrapper/MPCommon.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +namespace mpfr = LIBC_NAMESPACE::testing::mpfr; +using LIBC_NAMESPACE::fputil::BFloat16; + +static BFloat16 mul_func(BFloat16 x, BFloat16 y) { return x * y; } + +struct Bfloat16MulChecker : public virtual LIBC_NAMESPACE::testing::Test { + using FloatType = BFloat16; + using FPBits = LIBC_NAMESPACE::fputil::FPBits<bfloat16>; + using StorageType = typename FPBits::StorageType; + + uint64_t check(uint16_t x_start, uint16_t x_stop, uint16_t y_start, + uint16_t y_stop, mpfr::RoundingMode rounding) { + mpfr::ForceRoundingMode r(rounding); + if (!r.success) + return true; + uint16_t xbits = x_start; + uint64_t failed = 0; + do { + BFloat16 x = FPBits(xbits).get_val(); + uint16_t ybits = xbits; + do { + BFloat16 y = FPBits(ybits).get_val(); + mpfr::BinaryInput<BFloat16> input{x, y}; + bool correct = TEST_MPFR_MATCH_ROUNDING_SILENTLY( + mpfr::Operation::Mul, input, mul_func(x, y), 0.5, rounding); + failed += (!correct); + } while (ybits++ < y_stop); + } while (xbits++ < x_stop); + return failed; + } +}; + +using LlvmLibcBfloat16ExhaustiveMulTest = + LlvmLibcExhaustiveMathTest<Bfloat16MulChecker, 1 << 2>; + +// range: [0, inf] +static constexpr uint16_t POS_START = 0x0000U; +static constexpr uint16_t POS_STOP = 0x7f80U; + +// range: [-0, -inf] +static constexpr uint16_t NEG_START = 0x8000U; +static constexpr uint16_t NEG_STOP = 0xff80U; + +TEST_F(LlvmLibcBfloat16ExhaustiveMulTest, PositiveRange) { + test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP); +} + +TEST_F(LlvmLibcBfloat16ExhaustiveMulTest, NegativeRange) { + test_full_range_all_roundings(NEG_START, NEG_STOP, NEG_START, NEG_STOP); +} diff --git a/libc/test/src/math/exhaustive/bfloat16_sub_test.cpp b/libc/test/src/math/exhaustive/bfloat16_sub_test.cpp new file mode 100644 index 0000000..11bc6f5 --- /dev/null +++ b/libc/test/src/math/exhaustive/bfloat16_sub_test.cpp @@ -0,0 +1,65 @@ +//===-- Exhaustive tests for bfloat16 subtraction -------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "exhaustive_test.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "test/UnitTest/FPMatcher.h" +#include "utils/MPFRWrapper/MPCommon.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +namespace mpfr = LIBC_NAMESPACE::testing::mpfr; +using LIBC_NAMESPACE::fputil::BFloat16; + +static BFloat16 sub_func(BFloat16 x, BFloat16 y) { return x - y; } + +struct Bfloat16SubChecker : public virtual LIBC_NAMESPACE::testing::Test { + using FloatType = BFloat16; + using FPBits = LIBC_NAMESPACE::fputil::FPBits<bfloat16>; + using StorageType = typename FPBits::StorageType; + + uint64_t check(uint16_t x_start, uint16_t x_stop, uint16_t y_start, + uint16_t y_stop, mpfr::RoundingMode rounding) { + mpfr::ForceRoundingMode r(rounding); + if (!r.success) + return true; + uint16_t xbits = x_start; + uint64_t failed = 0; + do { + BFloat16 x = FPBits(xbits).get_val(); + uint16_t ybits = xbits; + do { + BFloat16 y = FPBits(ybits).get_val(); + mpfr::BinaryInput<BFloat16> input{x, y}; + bool correct = TEST_MPFR_MATCH_ROUNDING_SILENTLY( + mpfr::Operation::Sub, input, sub_func(x, y), 0.5, rounding); + failed += (!correct); + } while (ybits++ < y_stop); + } while (xbits++ < x_stop); + return failed; + } +}; + +using LlvmLibcBfloat16ExhaustiveSubTest = + LlvmLibcExhaustiveMathTest<Bfloat16SubChecker, 1 << 2>; + +// range: [0, inf] +static constexpr uint16_t POS_START = 0x0000U; +static constexpr uint16_t POS_STOP = 0x7f80U; + +// range: [-0, -inf] +static constexpr uint16_t NEG_START = 0x8000U; +static constexpr uint16_t NEG_STOP = 0xff80U; + +TEST_F(LlvmLibcBfloat16ExhaustiveSubTest, PositiveRange) { + test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP); +} + +TEST_F(LlvmLibcBfloat16ExhaustiveSubTest, NegativeRange) { + test_full_range_all_roundings(NEG_START, NEG_STOP, NEG_START, NEG_STOP); +} diff --git a/libc/test/src/math/exhaustive/exhaustive_test.h b/libc/test/src/math/exhaustive/exhaustive_test.h index cdf459c..8be65ba 100644 --- a/libc/test/src/math/exhaustive/exhaustive_test.h +++ b/libc/test/src/math/exhaustive/exhaustive_test.h @@ -164,7 +164,7 @@ struct LlvmLibcExhaustiveMathTest range_begin = current_value; if (stop >= Increment && stop - Increment >= current_value) { - range_end = current_value + Increment; + range_end = static_cast<StorageType>(current_value + Increment); } else { range_end = stop; } diff --git a/libc/test/src/math/exhaustive/fmodbf16_test.cpp b/libc/test/src/math/exhaustive/fmodbf16_test.cpp new file mode 100644 index 0000000..122be7a --- /dev/null +++ b/libc/test/src/math/exhaustive/fmodbf16_test.cpp @@ -0,0 +1,42 @@ +//===-- Exhaustive test for fmodbf16 --------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "exhaustive_test.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fmodbf16.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +namespace mpfr = LIBC_NAMESPACE::testing::mpfr; + +using LlvmLibcFmodf16ExhaustiveTest = + LlvmLibcBinaryOpExhaustiveMathTest<bfloat16, mpfr::Operation::Fmod, + LIBC_NAMESPACE::fmodbf16>; + +// range: [0, inf] +static constexpr uint16_t POS_START = 0x0000U; +static constexpr uint16_t POS_STOP = 0x7f80U; + +// range: [-0, -inf] +static constexpr uint16_t NEG_START = 0x8000U; +static constexpr uint16_t NEG_STOP = 0xff80U; + +TEST_F(LlvmLibcFmodf16ExhaustiveTest, PostivePositiveRange) { + test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP); +} + +TEST_F(LlvmLibcFmodf16ExhaustiveTest, PostiveNegativeRange) { + test_full_range_all_roundings(POS_START, POS_STOP, NEG_START, NEG_STOP); +} + +TEST_F(LlvmLibcFmodf16ExhaustiveTest, NegativePositiveRange) { + test_full_range_all_roundings(NEG_START, NEG_STOP, POS_START, POS_STOP); +} + +TEST_F(LlvmLibcFmodf16ExhaustiveTest, NegativeNegativeRange) { + test_full_range_all_roundings(NEG_START, NEG_STOP, NEG_START, NEG_STOP); +} diff --git a/libc/test/src/math/explogxf_test.cpp b/libc/test/src/math/explogxf_test.cpp index 49cc962..4d35309 100644 --- a/libc/test/src/math/explogxf_test.cpp +++ b/libc/test/src/math/explogxf_test.cpp @@ -9,11 +9,11 @@ #include "hdr/math_macros.h" #include "in_float_range_test_helper.h" #include "src/__support/FPUtil/FPBits.h" +#include "src/__support/math/acoshf_utils.h" +#include "src/__support/math/exp10f_utils.h" #include "src/math/fabs.h" #include "src/math/fabsf.h" -#include "src/math/generic/explogxf.h" #include "test/UnitTest/FPMatcher.h" -#include "test/UnitTest/Test.h" #include "utils/MPFRWrapper/MPFRUtils.h" using LlvmLibcExplogfTest = LIBC_NAMESPACE::testing::FPTest<float>; diff --git a/libc/test/src/math/llrintbf16_test.cpp b/libc/test/src/math/llrintbf16_test.cpp new file mode 100644 index 0000000..e841e62 --- /dev/null +++ b/libc/test/src/math/llrintbf16_test.cpp @@ -0,0 +1,15 @@ +//===-- Unittests for llrintbf16 ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "RoundToIntegerTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/llrintbf16.h" + +LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(bfloat16, long long, + LIBC_NAMESPACE::llrintbf16) diff --git a/libc/test/src/math/llroundbf16_test.cpp b/libc/test/src/math/llroundbf16_test.cpp new file mode 100644 index 0000000..c3b7ea4 --- /dev/null +++ b/libc/test/src/math/llroundbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for llroundbf16 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "RoundToIntegerTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/llroundbf16.h" + +LIST_ROUND_TO_INTEGER_TESTS(bfloat16, long long, LIBC_NAMESPACE::llroundbf16) diff --git a/libc/test/src/math/lrintbf16_test.cpp b/libc/test/src/math/lrintbf16_test.cpp new file mode 100644 index 0000000..65a5633b8 --- /dev/null +++ b/libc/test/src/math/lrintbf16_test.cpp @@ -0,0 +1,15 @@ +//===-- Unittests for lrintbf16 -------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "RoundToIntegerTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/lrintbf16.h" + +LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(bfloat16, long, + LIBC_NAMESPACE::lrintbf16) diff --git a/libc/test/src/math/lroundbf16_test.cpp b/libc/test/src/math/lroundbf16_test.cpp new file mode 100644 index 0000000..2f2b7b1 --- /dev/null +++ b/libc/test/src/math/lroundbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for lroundbf16 ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "RoundToIntegerTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/lroundbf16.h" + +LIST_ROUND_TO_INTEGER_TESTS(bfloat16, long, LIBC_NAMESPACE::lroundbf16) diff --git a/libc/test/src/math/nearbyintbf16_test.cpp b/libc/test/src/math/nearbyintbf16_test.cpp new file mode 100644 index 0000000..2d64fc5 --- /dev/null +++ b/libc/test/src/math/nearbyintbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for nearbyintbf16 ---------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "NearbyIntTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/nearbyintbf16.h" + +LIST_NEARBYINT_TESTS(bfloat16, LIBC_NAMESPACE::nearbyintbf16) diff --git a/libc/test/src/math/rintbf16_test.cpp b/libc/test/src/math/rintbf16_test.cpp new file mode 100644 index 0000000..c78dcf6 --- /dev/null +++ b/libc/test/src/math/rintbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for rintbf16 --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "RIntTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/rintbf16.h" + +LIST_RINT_TESTS(bfloat16, LIBC_NAMESPACE::rintbf16) diff --git a/libc/test/src/math/smoke/AddTest.h b/libc/test/src/math/smoke/AddTest.h index 68a4bbe..4bd794c 100644 --- a/libc/test/src/math/smoke/AddTest.h +++ b/libc/test/src/math/smoke/AddTest.h @@ -47,6 +47,10 @@ public: EXPECT_FP_EQ(neg_inf, func(in.neg_inf, in.zero)); EXPECT_FP_EQ(inf, func(in.inf, in.neg_zero)); EXPECT_FP_EQ(neg_inf, func(in.neg_inf, in.neg_zero)); + EXPECT_FP_EQ(inf, func(in.zero, in.inf)); + EXPECT_FP_EQ(inf, func(in.neg_zero, in.inf)); + EXPECT_FP_EQ(neg_inf, func(in.zero, in.neg_inf)); + EXPECT_FP_EQ(neg_inf, func(in.neg_zero, in.neg_inf)); } void test_invalid_operations(AddFunc func) { diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt index 40b7a342..152f38d 100644 --- a/libc/test/src/math/smoke/CMakeLists.txt +++ b/libc/test/src/math/smoke/CMakeLists.txt @@ -345,6 +345,19 @@ add_fp_unittest( ) add_fp_unittest( + truncbf16_test + SUITE + libc-math-smoke-tests + SRCS + truncbf16_test.cpp + HDRS + TruncTest.h + DEPENDS + libc.src.math.truncbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( canonicalize_test SUITE libc-math-smoke-tests @@ -420,6 +433,22 @@ add_fp_unittest( ) add_fp_unittest( + canonicalizebf16_test + SUITE + libc-math-smoke-tests + SRCS + canonicalizebf16_test.cpp + HDRS + CanonicalizeTest.h + DEPENDS + libc.src.math.canonicalizebf16 + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.integer_literals +) + +add_fp_unittest( iscanonical_test SUITE libc-math-smoke-tests @@ -480,6 +509,19 @@ add_fp_unittest( ) add_fp_unittest( + iscanonicalbf16_test + SUITE + libc-math-smoke-tests + SRCS + iscanonicalbf16_test.cpp + HDRS + IsCanonicalTest.h + DEPENDS + libc.src.math.iscanonicalbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( ceil_test SUITE libc-math-smoke-tests @@ -544,6 +586,19 @@ add_fp_unittest( ) add_fp_unittest( + ceilbf16_test + SUITE + libc-math-smoke-tests + SRCS + ceilbf16_test.cpp + HDRS + CeilTest.h + DEPENDS + libc.src.math.ceilbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( dfmal_test SUITE libc-math-smoke-tests @@ -664,6 +719,19 @@ add_fp_unittest( ) add_fp_unittest( + floorbf16_test + SUITE + libc-math-smoke-tests + SRCS + floorbf16_test.cpp + HDRS + FloorTest.h + DEPENDS + libc.src.math.floorbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( round_test SUITE libc-math-smoke-tests @@ -728,6 +796,19 @@ add_fp_unittest( ) add_fp_unittest( + roundbf16_test + SUITE + libc-math-smoke-tests + SRCS + roundbf16_test.cpp + HDRS + RoundTest.h + DEPENDS + libc.src.math.roundbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( roundeven_test SUITE libc-math-smoke-tests @@ -792,6 +873,19 @@ add_fp_unittest( ) add_fp_unittest( + roundevenbf16_test + SUITE + libc-math-smoke-tests + SRCS + roundevenbf16_test.cpp + HDRS + RoundEvenTest.h + DEPENDS + libc.src.math.roundevenbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( lround_test SUITE libc-math-smoke-tests @@ -872,6 +966,23 @@ add_fp_unittest( ) add_fp_unittest( + lroundbf16_test + SUITE + libc-math-smoke-tests + SRCS + lroundbf16_test.cpp + HDRS + RoundToIntegerTest.h + DEPENDS + libc.src.errno.errno + libc.src.math.lroundbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( llround_test SUITE libc-math-smoke-tests @@ -952,6 +1063,23 @@ add_fp_unittest( ) add_fp_unittest( + llroundbf16_test + SUITE + libc-math-smoke-tests + SRCS + llroundbf16_test.cpp + HDRS + RoundToIntegerTest.h + DEPENDS + libc.src.errno.errno + libc.src.math.llroundbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( rint_test SUITE libc-math-smoke-tests @@ -1022,6 +1150,21 @@ add_fp_unittest( ) add_fp_unittest( + rintbf16_test + SUITE + libc-math-smoke-tests + SRCS + rintbf16_test.cpp + HDRS + RIntTest.h + DEPENDS + libc.src.math.rintbf16 + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( lrint_test SUITE libc-math-smoke-tests @@ -1102,6 +1245,23 @@ add_fp_unittest( ) add_fp_unittest( + lrintbf16_test + SUITE + libc-math-smoke-tests + SRCS + lrintbf16_test.cpp + HDRS + RoundToIntegerTest.h + DEPENDS + libc.src.errno.errno + libc.src.math.lrintbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( llrint_test SUITE libc-math-smoke-tests @@ -1182,6 +1342,23 @@ add_fp_unittest( ) add_fp_unittest( + llrintbf16_test + SUITE + libc-math-smoke-tests + SRCS + llrintbf16_test.cpp + HDRS + RoundToIntegerTest.h + DEPENDS + libc.src.errno.errno + libc.src.math.llrintbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( exp_test SUITE libc-math-smoke-tests @@ -1412,6 +1589,21 @@ add_fp_unittest( ) add_fp_unittest( + copysignbf16_test + SUITE + libc-math-smoke-tests + SRCS + copysignbf16_test.cpp + HDRS + CopySignTest.h + DEPENDS + libc.src.math.copysignbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( frexp_test SUITE libc-math-smoke-tests @@ -1472,6 +1664,19 @@ add_fp_unittest( ) add_fp_unittest( + frexpbf16_test + SUITE + libc-math-smoke-tests + SRCS + frexpbf16_test.cpp + HDRS + FrexpTest.h + DEPENDS + libc.src.math.frexpbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( fromfp_test SUITE libc-math-smoke-tests @@ -1532,6 +1737,19 @@ add_fp_unittest( ) add_fp_unittest( + fromfpbf16_test + SUITE + libc-math-smoke-tests + SRCS + fromfpbf16_test.cpp + HDRS + FromfpTest.h + DEPENDS + libc.src.math.fromfpbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( fromfpx_test SUITE libc-math-smoke-tests @@ -1592,6 +1810,20 @@ add_fp_unittest( ) add_fp_unittest( + fromfpxbf16_test + SUITE + libc-math-smoke-tests + SRCS + fromfpxbf16_test.cpp + HDRS + FromfpxTest.h + DEPENDS + libc.src.math.fromfpxbf16 + libc.src.__support.FPUtil.bfloat16 +) + + +add_fp_unittest( ufromfp_test SUITE libc-math-smoke-tests @@ -1652,6 +1884,19 @@ add_fp_unittest( ) add_fp_unittest( + ufromfpbf16_test + SUITE + libc-math-smoke-tests + SRCS + ufromfpbf16_test.cpp + HDRS + UfromfpTest.h + DEPENDS + libc.src.math.ufromfpbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( ufromfpx_test SUITE libc-math-smoke-tests @@ -1712,6 +1957,19 @@ add_fp_unittest( ) add_fp_unittest( + ufromfpxbf16_test + SUITE + libc-math-smoke-tests + SRCS + ufromfpxbf16_test.cpp + HDRS + UfromfpxTest.h + DEPENDS + libc.src.math.ufromfpxbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( ilogb_test SUITE libc-math-smoke-tests @@ -1787,6 +2045,22 @@ add_fp_unittest( ) add_fp_unittest( + ilogbbf16_test + SUITE + libc-math-smoke-tests + SRCS + ilogbbf16_test.cpp + HDRS + ILogbTest.h + DEPENDS + libc.src.math.ilogbbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.manipulation_functions +) + +add_fp_unittest( issignaling_test SUITE libc-math-smoke-tests @@ -1847,6 +2121,19 @@ add_fp_unittest( ) add_fp_unittest( + issignalingbf16_test + SUITE + libc-math-smoke-tests + SRCS + issignalingbf16_test.cpp + HDRS + IsSignalingTest.h + DEPENDS + libc.src.math.issignalingbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( llogb_test SUITE libc-math-smoke-tests @@ -1922,6 +2209,22 @@ add_fp_unittest( ) add_fp_unittest( + llogbbf16_test + SUITE + libc-math-smoke-tests + SRCS + llogbbf16_test.cpp + HDRS + ILogbTest.h + DEPENDS + libc.src.math.llogbbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.manipulation_functions +) + +add_fp_unittest( ldexp_test SUITE libc-math-smoke-tests @@ -1931,6 +2234,7 @@ add_fp_unittest( LdExpTest.h DEPENDS libc.src.math.ldexp + libc.src.__support.CPP.algorithm libc.src.__support.CPP.limits libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.normal_float @@ -1946,6 +2250,7 @@ add_fp_unittest( LdExpTest.h DEPENDS libc.src.math.ldexpf + libc.src.__support.CPP.algorithm libc.src.__support.CPP.limits libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.normal_float @@ -1961,6 +2266,7 @@ add_fp_unittest( LdExpTest.h DEPENDS libc.src.math.ldexpl + libc.src.__support.CPP.algorithm libc.src.__support.CPP.limits libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.normal_float @@ -1976,6 +2282,7 @@ add_fp_unittest( LdExpTest.h DEPENDS libc.src.math.ldexpf16 + libc.src.__support.CPP.algorithm libc.src.__support.CPP.limits libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.normal_float @@ -1991,12 +2298,30 @@ add_fp_unittest( LdExpTest.h DEPENDS libc.src.math.ldexpf128 + libc.src.__support.CPP.algorithm libc.src.__support.CPP.limits libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.normal_float ) add_fp_unittest( + ldexpbf16_test + SUITE + libc-math-smoke-tests + SRCS + ldexpbf16_test.cpp + HDRS + LdExpTest.h + DEPENDS + libc.src.math.ldexpbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.CPP.limits + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.normal_float +) + +add_fp_unittest( logb_test SUITE libc-math-smoke-tests @@ -2067,6 +2392,21 @@ add_fp_unittest( ) add_fp_unittest( + logbbf16_test + SUITE + libc-math-smoke-tests + SRCS + logbbf16_test.cpp + HDRS + LogbTest.h + DEPENDS + libc.src.math.logbbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.manipulation_functions +) + +add_fp_unittest( modf_test SUITE libc-math-smoke-tests @@ -2142,6 +2482,22 @@ add_fp_unittest( ) add_fp_unittest( + modfbf16_test + SUITE + libc-math-smoke-tests + SRCS + modfbf16_test.cpp + HDRS + ModfTest.h + DEPENDS + libc.src.math.modfbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.nearest_integer_operations +) + +add_fp_unittest( fdimf_test SUITE libc-math-smoke-tests @@ -2212,6 +2568,21 @@ add_fp_unittest( ) add_fp_unittest( + fdimbf16_test + SUITE + libc-math-smoke-tests + SRCS + fdimbf16_test.cpp + HDRS + FDimTest.h + DEPENDS + libc.src.math.fdimbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( fminf_test SUITE libc-math-smoke-tests @@ -2282,6 +2653,21 @@ add_fp_unittest( ) add_fp_unittest( + fminbf16_test + SUITE + libc-math-smoke-tests + SRCS + fminbf16_test.cpp + HDRS + FMinTest.h + DEPENDS + libc.src.math.fminbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( fmaxf_test SUITE libc-math-smoke-tests @@ -2352,6 +2738,21 @@ add_fp_unittest( ) add_fp_unittest( + fmaxbf16_test + SUITE + libc-math-smoke-tests + SRCS + fmaxbf16_test.cpp + HDRS + FMaxTest.h + DEPENDS + libc.src.math.fmaxbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( fmaximuml_test SUITE libc-math-smoke-tests @@ -2436,6 +2837,21 @@ add_fp_unittest( ) add_fp_unittest( + fmaximumbf16_test + SUITE + libc-math-smoke-tests + SRCS + fmaximumbf16_test.cpp + HDRS + FMaximumTest.h + DEPENDS + libc.src.math.fmaximumbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( fmaximum_num_test SUITE libc-math-smoke-tests @@ -2492,6 +2908,21 @@ add_fp_unittest( ) add_fp_unittest( + fmaximum_numbf16_test + SUITE + libc-math-smoke-tests + SRCS + fmaximum_numbf16_test.cpp + HDRS + FMaximumTest.h + DEPENDS + libc.src.math.fmaximum_numbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( fmaximum_magf_test SUITE libc-math-smoke-tests @@ -2567,6 +2998,21 @@ add_fp_unittest( ) add_fp_unittest( + fmaximum_magbf16_test + SUITE + libc-math-smoke-tests + SRCS + fmaximum_magbf16_test.cpp + HDRS + FMaximumTest.h + DEPENDS + libc.src.math.fmaximum_magbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( fmaximum_mag_numf_test SUITE libc-math-smoke-tests @@ -2637,6 +3083,21 @@ add_fp_unittest( ) add_fp_unittest( + fmaximum_mag_numbf16_test + SUITE + libc-math-smoke-tests + SRCS + fmaximum_mag_numbf16_test.cpp + HDRS + FMaximumTest.h + DEPENDS + libc.src.math.fmaximum_mag_numbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( fminimuml_test SUITE libc-math-smoke-tests @@ -2707,6 +3168,21 @@ add_fp_unittest( ) add_fp_unittest( + fminimumbf16_test + SUITE + libc-math-smoke-tests + SRCS + fminimumbf16_test.cpp + HDRS + FMaximumTest.h + DEPENDS + libc.src.math.fminimumbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( fminimum_numf_test SUITE libc-math-smoke-tests @@ -2777,6 +3253,21 @@ add_fp_unittest( ) add_fp_unittest( + fminimum_numbf16_test + SUITE + libc-math-smoke-tests + SRCS + fminimum_numf16_test.cpp + HDRS + FMaximumTest.h + DEPENDS + libc.src.math.fminimum_numf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( fminimum_magf_test SUITE libc-math-smoke-tests @@ -2847,6 +3338,21 @@ add_fp_unittest( ) add_fp_unittest( + fminimum_magbf16_test + SUITE + libc-math-smoke-tests + SRCS + fminimum_magbf16_test.cpp + HDRS + FMaximumTest.h + DEPENDS + libc.src.math.fminimum_magbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( fminimum_mag_numf_test SUITE libc-math-smoke-tests @@ -2917,6 +3423,21 @@ add_fp_unittest( ) add_fp_unittest( + fminimum_mag_numbf16_test + SUITE + libc-math-smoke-tests + SRCS + fminimum_mag_numbf16_test.cpp + HDRS + FMaximumTest.h + DEPENDS + libc.src.math.fminimum_mag_numbf16 + libc.src.__support.CPP.algorithm + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( fmul_test SUITE libc-math-smoke-tests @@ -3132,6 +3653,20 @@ add_fp_unittest( ) add_fp_unittest( + remquobf16_test + SUITE + libc-math-smoke-tests + SRCS + remquobf16_test.cpp + HDRS + RemQuoTest.h + DEPENDS + libc.src.math.remquobf16 + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( hypotf_test SUITE libc-math-smoke-tests @@ -3248,6 +3783,22 @@ add_fp_unittest( ) add_fp_unittest( + nanbf16_test + SUITE + libc-math-smoke-tests + SRCS + nanbf16_test.cpp + DEPENDS + libc.hdr.signal_macros + libc.src.math.nanbf16 + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits + # FIXME: The nan tests currently have death tests, which aren't supported for + # hermetic tests. + UNIT_TEST_ONLY +) + +add_fp_unittest( nearbyint_test SUITE libc-math-smoke-tests @@ -3313,6 +3864,20 @@ add_fp_unittest( ) add_fp_unittest( + nearbyintbf16_test + SUITE + libc-math-smoke-tests + SRCS + nearbyintbf16_test.cpp + HDRS + NearbyIntTest.h + DEPENDS + libc.hdr.fenv_macros + libc.src.math.nearbyintbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( nextafter_test SUITE libc-math-smoke-tests @@ -3392,6 +3957,23 @@ add_fp_unittest( libc.src.__support.FPUtil.fp_bits ) +add_fp_unittest( + nextafterbf16_test + SUITE + libc-math-smoke-tests + SRCS + nextafterbf16_test.cpp + HDRS + NextAfterTest.h + DEPENDS + libc.hdr.fenv_macros + libc.src.math.nextafterbf16 + libc.src.__support.CPP.bit + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + # FIXME: These tests are currently spurious for the GPU. if(NOT LIBC_TARGET_OS_IS_GPU) add_fp_unittest( @@ -3460,6 +4042,23 @@ add_fp_unittest( ) add_fp_unittest( + nexttowardbf16_test + SUITE + libc-math-smoke-tests + SRCS + nexttowardbf16_test.cpp + HDRS + NextTowardTest.h + DEPENDS + libc.hdr.fenv_macros + libc.src.math.nexttowardbf16 + libc.src.__support.CPP.bit + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits +) + +add_fp_unittest( nextdown_test SUITE libc-math-smoke-tests @@ -3520,6 +4119,19 @@ add_fp_unittest( ) add_fp_unittest( + nextdownbf16_test + SUITE + libc-math-smoke-tests + SRCS + nextdownbf16_test.cpp + HDRS + NextDownTest.h + DEPENDS + libc.src.math.nextdownbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( nextup_test SUITE libc-math-smoke-tests @@ -3579,6 +4191,19 @@ add_fp_unittest( libc.src.math.nextupf128 ) +add_fp_unittest( + nextupbf16_test + SUITE + libc-math-smoke-tests + SRCS + nextupbf16_test.cpp + HDRS + NextUpTest.h + DEPENDS + libc.src.math.nextupbf16 + libc.src.__support.FPUtil.bfloat16 +) + # TODO(lntue): The current implementation of fputil::general::fma<float> is only # correctly rounded for the default rounding mode round-to-nearest tie-to-even. add_fp_unittest( @@ -3879,6 +4504,23 @@ add_fp_unittest( ) add_fp_unittest( + fmodbf16_test + SUITE + libc-math-smoke-tests + SRCS + fmodbf16_test.cpp + HDRS + FModTest.h + DEPENDS + libc.hdr.fenv_macros + libc.src.errno.errno + libc.src.math.fmodbf16 + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fenv_impl + UNIT_TEST_ONLY +) + +add_fp_unittest( coshf_test SUITE libc-math-smoke-tests @@ -3979,6 +4621,18 @@ add_fp_unittest( ) add_fp_unittest( + atanpif16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + atanpif16_test.cpp + DEPENDS + libc.src.math.atanpif16 + libc.src.errno.errno +) + +add_fp_unittest( asinhf_test SUITE libc-math-smoke-tests @@ -4002,6 +4656,18 @@ add_fp_unittest( ) add_fp_unittest( + asinpif16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + asinpif16_test.cpp + DEPENDS + libc.src.math.asinpif16 + libc.src.errno.errno +) + +add_fp_unittest( acoshf_test SUITE libc-math-smoke-tests @@ -4245,6 +4911,22 @@ add_fp_unittest( ) add_fp_unittest( + scalblnbf16_test + SUITE + libc-math-smoke-tests + SRCS + scalblnbf16_test.cpp + HDRS + ScalbnTest.h + DEPENDS + libc.src.math.scalblnbf16 + libc.src.__support.CPP.limits + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.normal_float +) + +add_fp_unittest( scalbn_test SUITE libc-math-smoke-tests @@ -4320,6 +5002,22 @@ add_fp_unittest( ) add_fp_unittest( + scalbnbf16_test + SUITE + libc-math-smoke-tests + SRCS + scalbnbf16_test.cpp + HDRS + ScalbnTest.h + DEPENDS + libc.src.math.scalbnbf16 + libc.src.__support.CPP.limits + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.normal_float +) + +add_fp_unittest( erff_test SUITE libc-math-smoke-tests @@ -4414,6 +5112,19 @@ add_fp_unittest( ) add_fp_unittest( + totalorderbf16_test + SUITE + libc-math-smoke-tests + SRCS + totalorderbf16_test.cpp + HDRS + TotalOrderTest.h + DEPENDS + libc.src.math.totalorderbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( totalordermag_test SUITE libc-math-smoke-tests @@ -4474,6 +5185,19 @@ add_fp_unittest( ) add_fp_unittest( + totalordermagbf16_test + SUITE + libc-math-smoke-tests + SRCS + totalordermagbf16_test.cpp + HDRS + TotalOrderMagTest.h + DEPENDS + libc.src.math.totalordermagbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( getpayload_test SUITE libc-math-smoke-tests @@ -4534,6 +5258,19 @@ add_fp_unittest( ) add_fp_unittest( + getpayloadbf16_test + SUITE + libc-math-smoke-tests + SRCS + getpayloadbf16_test.cpp + HDRS + GetPayloadTest.h + DEPENDS + libc.src.math.getpayloadbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( setpayload_test SUITE libc-math-smoke-tests @@ -4594,6 +5331,19 @@ add_fp_unittest( ) add_fp_unittest( + setpayloadbf16_test + SUITE + libc-math-smoke-tests + SRCS + setpayloadbf16_test.cpp + HDRS + SetPayloadTest.h + DEPENDS + libc.src.math.setpayloadbf16 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( setpayloadsig_test SUITE libc-math-smoke-tests @@ -4653,6 +5403,18 @@ add_fp_unittest( libc.src.math.setpayloadsigf128 ) +add_fp_unittest( + setpayloadsigbf16_test + SUITE + libc-math-smoke-tests + SRCS + setpayloadsigbf16_test.cpp + HDRS + SetPayloadTest.h + DEPENDS + libc.src.math.setpayloadsigbf16 + libc.src.__support.FPUtil.bfloat16 +) add_fp_unittest( f16add_test @@ -5307,6 +6069,69 @@ add_fp_unittest( ) add_fp_unittest( + bfloat16_add_test + SUITE + libc-math-smoke-tests + SRCS + bfloat16_add_test.cpp + HDRS + AddTest.h + DEPENDS + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.macros.properties.os + libc.src.__support.macros.properties.types + libc.hdr.errno_macros + libc.hdr.fenv_macros +) + +add_fp_unittest( + bfloat16_div_test + SUITE + libc-math-smoke-tests + SRCS + bfloat16_div_test.cpp + HDRS + DivTest.h + DEPENDS + libc.src.__support.FPUtil.bfloat16 + libc.hdr.errno_macros + libc.hdr.fenv_macros +) + +add_fp_unittest( + bfloat16_mul_test + SUITE + libc-math-smoke-tests + SRCS + bfloat16_mul_test.cpp + HDRS + MulTest.h + DEPENDS + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.bfloat16 + libc.hdr.errno_macros + libc.hdr.fenv_macros +) + +add_fp_unittest( + bfloat16_sub_test + SUITE + libc-math-smoke-tests + SRCS + bfloat16_sub_test.cpp + HDRS + SubTest.h + DEPENDS + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.macros.properties.os + libc.src.__support.macros.properties.types + libc.hdr.errno_macros + libc.hdr.fenv_macros +) + +add_fp_unittest( add_same_type_test SUITE libc-math-smoke-tests @@ -5337,3 +6162,312 @@ add_fp_unittest( libc.src.__support.macros.properties.os libc.src.__support.macros.properties.types ) + +add_fp_unittest( + bf16add_test + SUITE + libc-math-smoke-tests + SRCS + bf16add_test.cpp + HDRS + AddTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16add + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.properties.os +) + +add_fp_unittest( + bf16addf_test + SUITE + libc-math-smoke-tests + SRCS + bf16addf_test.cpp + HDRS + AddTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16addf + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.properties.os +) + +add_fp_unittest( + bf16addl_test + SUITE + libc-math-smoke-tests + SRCS + bf16addl_test.cpp + HDRS + AddTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16addl + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.properties.os +) + +add_fp_unittest( + bf16addf128_test + SUITE + libc-math-smoke-tests + SRCS + bf16addf128_test.cpp + HDRS + AddTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16addf128 + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.properties.os +) + +add_fp_unittest( + bf16fma_test + SUITE + libc-math-smoke-tests + SRCS + bf16fma_test.cpp + HDRS + FmaTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16fma + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16fmaf_test + SUITE + libc-math-smoke-tests + SRCS + bf16fmaf_test.cpp + HDRS + FmaTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16fmaf + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16fmal_test + SUITE + libc-math-smoke-tests + SRCS + bf16fmal_test.cpp + HDRS + FmaTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16fmal + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16fmaf128_test + SUITE + libc-math-smoke-tests + SRCS + bf16fmaf128_test.cpp + HDRS + FmaTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16fmaf128 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16div_test + SUITE + libc-math-smoke-tests + SRCS + bf16div_test.cpp + HDRS + DivTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16div + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16divf_test + SUITE + libc-math-smoke-tests + SRCS + bf16divf_test.cpp + HDRS + DivTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16divf + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16divl_test + SUITE + libc-math-smoke-tests + SRCS + bf16divl_test.cpp + HDRS + DivTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16divl + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16divf128_test + SUITE + libc-math-smoke-tests + SRCS + bf16divf128_test.cpp + HDRS + DivTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16divf128 + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16mul_test + SUITE + libc-math-smoke-tests + SRCS + bf16mul_test.cpp + HDRS + MulTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16mul + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16mulf_test + SUITE + libc-math-smoke-tests + SRCS + bf16mulf_test.cpp + HDRS + MulTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16mulf + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16mull_test + SUITE + libc-math-smoke-tests + SRCS + bf16mull_test.cpp + HDRS + MulTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16mull + libc.src.__support.FPUtil.bfloat16 +) + +add_fp_unittest( + bf16mulf128_test + SUITE + libc-math-smoke-tests + SRCS + bf16mulf128_test.cpp + HDRS + MulTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16mulf128 + libc.src.__support.FPUtil.bfloat16 +) + + +add_fp_unittest( + bf16sub_test + SUITE + libc-math-smoke-tests + SRCS + bf16sub_test.cpp + HDRS + SubTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16sub + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.properties.os +) + +add_fp_unittest( + bf16subf_test + SUITE + libc-math-smoke-tests + SRCS + bf16subf_test.cpp + HDRS + SubTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16subf + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.properties.os +) + +add_fp_unittest( + bf16subl_test + SUITE + libc-math-smoke-tests + SRCS + bf16subl_test.cpp + HDRS + SubTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16subl + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.properties.os +) + +add_fp_unittest( + bf16subf128_test + SUITE + libc-math-smoke-tests + SRCS + bf16subf128_test.cpp + HDRS + SubTest.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.bf16subf128 + libc.src.__support.FPUtil.bfloat16 + libc.src.__support.macros.properties.os +) diff --git a/libc/test/src/math/smoke/CeilTest.h b/libc/test/src/math/smoke/CeilTest.h index 7998eab..1839db9 100644 --- a/libc/test/src/math/smoke/CeilTest.h +++ b/libc/test/src/math/smoke/CeilTest.h @@ -59,10 +59,12 @@ public: EXPECT_FP_EQ(T(-10.0), func(T(-10.32))); EXPECT_FP_EQ(T(11.0), func(T(10.65))); EXPECT_FP_EQ(T(-10.0), func(T(-10.65))); + EXPECT_FP_EQ(T(50.0), func(T(49.62))); + EXPECT_FP_EQ(T(-50.0), func(T(-50.31))); EXPECT_FP_EQ(T(124.0), func(T(123.38))); EXPECT_FP_EQ(T(-123.0), func(T(-123.38))); EXPECT_FP_EQ(T(124.0), func(T(123.96))); - EXPECT_FP_EQ(T(-123.0), func(T(-123.96))); + EXPECT_FP_EQ(T(-123.0), func(T(-123.5))); } }; diff --git a/libc/test/src/math/smoke/DivTest.h b/libc/test/src/math/smoke/DivTest.h index d807479..ff82f68 100644 --- a/libc/test/src/math/smoke/DivTest.h +++ b/libc/test/src/math/smoke/DivTest.h @@ -47,6 +47,11 @@ public: EXPECT_FP_EQ(neg_inf, func(in.neg_inf, in.zero)); EXPECT_FP_EQ(neg_inf, func(in.inf, in.neg_zero)); EXPECT_FP_EQ(inf, func(in.neg_inf, in.neg_zero)); + EXPECT_FP_EQ(zero, func(in.min_normal, in.inf)); + EXPECT_FP_EQ(zero, func(in.zero, in.inf)); + EXPECT_FP_EQ(zero, func(in.neg_zero, in.neg_inf)); + EXPECT_FP_EQ(neg_zero, func(in.min_normal, in.neg_inf)); + EXPECT_FP_EQ(neg_zero, func(in.zero, in.neg_inf)); } void test_division_by_zero(DivFunc func) { diff --git a/libc/test/src/math/smoke/FModTest.h b/libc/test/src/math/smoke/FModTest.h index 04cbc65..e74ee09 100644 --- a/libc/test/src/math/smoke/FModTest.h +++ b/libc/test/src/math/smoke/FModTest.h @@ -31,12 +31,22 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { DECLARE_SPECIAL_CONSTANTS(T) + static constexpr T one = T(1.0); + static constexpr T two = T(2.0); + static constexpr T neg_two = T(-2.0); + static constexpr T three = T(3.0); + static constexpr T val_neg_1_1 = T(-1.1); + static constexpr T val_6_5 = T(6.5); + static constexpr T val_neg_6_5 = T(-6.5); + static constexpr T val_2_25 = T(2.25); + static constexpr T val_neg_2_25 = T(-2.25); + public: typedef T (*FModFunc)(T, T); void testSpecialNumbers(FModFunc f) { // fmod (+0, y) == +0 for y != 0. - TEST_SPECIAL(zero, T(3.0), zero, false, 0); + TEST_SPECIAL(zero, three, zero, false, 0); TEST_SPECIAL(zero, min_denormal, zero, false, 0); TEST_SPECIAL(zero, -min_denormal, zero, false, 0); TEST_SPECIAL(zero, min_normal, zero, false, 0); @@ -45,7 +55,7 @@ public: TEST_SPECIAL(zero, -max_normal, zero, false, 0); // fmod (-0, y) == -0 for y != 0. - TEST_SPECIAL(neg_zero, T(3.0), neg_zero, false, 0); + TEST_SPECIAL(neg_zero, three, neg_zero, false, 0); TEST_SPECIAL(neg_zero, min_denormal, neg_zero, false, 0); TEST_SPECIAL(neg_zero, -min_denormal, neg_zero, false, 0); TEST_SPECIAL(neg_zero, min_normal, neg_zero, false, 0); @@ -54,8 +64,8 @@ public: TEST_SPECIAL(neg_zero, -max_normal, neg_zero, false, 0); // fmod (+inf, y) == aNaN plus invalid exception. - TEST_SPECIAL(inf, T(3.0), aNaN, true, FE_INVALID); - TEST_SPECIAL(inf, T(-1.1), aNaN, true, FE_INVALID); + TEST_SPECIAL(inf, three, aNaN, true, FE_INVALID); + TEST_SPECIAL(inf, val_neg_1_1, aNaN, true, FE_INVALID); TEST_SPECIAL(inf, zero, aNaN, true, FE_INVALID); TEST_SPECIAL(inf, neg_zero, aNaN, true, FE_INVALID); TEST_SPECIAL(inf, min_denormal, aNaN, true, FE_INVALID); @@ -65,8 +75,8 @@ public: TEST_SPECIAL(inf, neg_inf, aNaN, true, FE_INVALID); // fmod (-inf, y) == aNaN plus invalid exception. - TEST_SPECIAL(neg_inf, T(3.0), aNaN, true, FE_INVALID); - TEST_SPECIAL(neg_inf, T(-1.1), aNaN, true, FE_INVALID); + TEST_SPECIAL(neg_inf, three, aNaN, true, FE_INVALID); + TEST_SPECIAL(neg_inf, val_neg_1_1, aNaN, true, FE_INVALID); TEST_SPECIAL(neg_inf, zero, aNaN, true, FE_INVALID); TEST_SPECIAL(neg_inf, neg_zero, aNaN, true, FE_INVALID); TEST_SPECIAL(neg_inf, min_denormal, aNaN, true, FE_INVALID); @@ -76,8 +86,8 @@ public: TEST_SPECIAL(neg_inf, neg_inf, aNaN, true, FE_INVALID); // fmod (x, +0) == aNaN plus invalid exception. - TEST_SPECIAL(T(3.0), zero, aNaN, true, FE_INVALID); - TEST_SPECIAL(T(-1.1), zero, aNaN, true, FE_INVALID); + TEST_SPECIAL(three, zero, aNaN, true, FE_INVALID); + TEST_SPECIAL(val_neg_1_1, zero, aNaN, true, FE_INVALID); TEST_SPECIAL(zero, zero, aNaN, true, FE_INVALID); TEST_SPECIAL(neg_zero, zero, aNaN, true, FE_INVALID); TEST_SPECIAL(min_denormal, zero, aNaN, true, FE_INVALID); @@ -85,8 +95,8 @@ public: TEST_SPECIAL(max_normal, zero, aNaN, true, FE_INVALID); // fmod (x, -0) == aNaN plus invalid exception. - TEST_SPECIAL(T(3.0), neg_zero, aNaN, true, FE_INVALID); - TEST_SPECIAL(T(-1.1), neg_zero, aNaN, true, FE_INVALID); + TEST_SPECIAL(three, neg_zero, aNaN, true, FE_INVALID); + TEST_SPECIAL(val_neg_1_1, neg_zero, aNaN, true, FE_INVALID); TEST_SPECIAL(zero, neg_zero, aNaN, true, FE_INVALID); TEST_SPECIAL(neg_zero, neg_zero, aNaN, true, FE_INVALID); TEST_SPECIAL(min_denormal, neg_zero, aNaN, true, FE_INVALID); @@ -99,21 +109,21 @@ public: TEST_SPECIAL(min_denormal, inf, min_denormal, false, 0); TEST_SPECIAL(min_normal, inf, min_normal, false, 0); TEST_SPECIAL(max_normal, inf, max_normal, false, 0); - TEST_SPECIAL(T(3.0), inf, T(3.0), false, 0); + TEST_SPECIAL(three, inf, three, false, 0); // fmod (x, -inf) == x for x not infinite. TEST_SPECIAL(zero, neg_inf, zero, false, 0); TEST_SPECIAL(neg_zero, neg_inf, neg_zero, false, 0); TEST_SPECIAL(min_denormal, neg_inf, min_denormal, false, 0); TEST_SPECIAL(min_normal, neg_inf, min_normal, false, 0); TEST_SPECIAL(max_normal, neg_inf, max_normal, false, 0); - TEST_SPECIAL(T(3.0), neg_inf, T(3.0), false, 0); + TEST_SPECIAL(three, neg_inf, three, false, 0); TEST_SPECIAL(zero, aNaN, aNaN, false, 0); TEST_SPECIAL(zero, neg_aNaN, aNaN, false, 0); TEST_SPECIAL(neg_zero, aNaN, aNaN, false, 0); TEST_SPECIAL(neg_zero, neg_aNaN, aNaN, false, 0); - TEST_SPECIAL(T(1.0), aNaN, aNaN, false, 0); - TEST_SPECIAL(T(1.0), neg_aNaN, aNaN, false, 0); + TEST_SPECIAL(one, aNaN, aNaN, false, 0); + TEST_SPECIAL(one, neg_aNaN, aNaN, false, 0); TEST_SPECIAL(inf, aNaN, aNaN, false, 0); TEST_SPECIAL(inf, neg_aNaN, aNaN, false, 0); TEST_SPECIAL(neg_inf, aNaN, aNaN, false, 0); @@ -122,8 +132,8 @@ public: TEST_SPECIAL(zero, neg_sNaN, aNaN, false, FE_INVALID); TEST_SPECIAL(neg_zero, sNaN, aNaN, false, FE_INVALID); TEST_SPECIAL(neg_zero, neg_sNaN, aNaN, false, FE_INVALID); - TEST_SPECIAL(T(1.0), sNaN, aNaN, false, FE_INVALID); - TEST_SPECIAL(T(1.0), neg_sNaN, aNaN, false, FE_INVALID); + TEST_SPECIAL(one, sNaN, aNaN, false, FE_INVALID); + TEST_SPECIAL(one, neg_sNaN, aNaN, false, FE_INVALID); TEST_SPECIAL(inf, sNaN, aNaN, false, FE_INVALID); TEST_SPECIAL(inf, neg_sNaN, aNaN, false, FE_INVALID); TEST_SPECIAL(neg_inf, sNaN, aNaN, false, FE_INVALID); @@ -132,8 +142,8 @@ public: TEST_SPECIAL(neg_aNaN, zero, aNaN, false, 0); TEST_SPECIAL(aNaN, neg_zero, aNaN, false, 0); TEST_SPECIAL(neg_aNaN, neg_zero, aNaN, false, 0); - TEST_SPECIAL(aNaN, T(1.0), aNaN, false, 0); - TEST_SPECIAL(neg_aNaN, T(1.0), aNaN, false, 0); + TEST_SPECIAL(aNaN, one, aNaN, false, 0); + TEST_SPECIAL(neg_aNaN, one, aNaN, false, 0); TEST_SPECIAL(aNaN, inf, aNaN, false, 0); TEST_SPECIAL(neg_aNaN, inf, aNaN, false, 0); TEST_SPECIAL(aNaN, neg_inf, aNaN, false, 0); @@ -142,8 +152,8 @@ public: TEST_SPECIAL(neg_sNaN, zero, aNaN, false, FE_INVALID); TEST_SPECIAL(sNaN, neg_zero, aNaN, false, FE_INVALID); TEST_SPECIAL(neg_sNaN, neg_zero, aNaN, false, FE_INVALID); - TEST_SPECIAL(sNaN, T(1.0), aNaN, false, FE_INVALID); - TEST_SPECIAL(neg_sNaN, T(1.0), aNaN, false, FE_INVALID); + TEST_SPECIAL(sNaN, one, aNaN, false, FE_INVALID); + TEST_SPECIAL(neg_sNaN, one, aNaN, false, FE_INVALID); TEST_SPECIAL(sNaN, inf, aNaN, false, FE_INVALID); TEST_SPECIAL(neg_sNaN, inf, aNaN, false, FE_INVALID); TEST_SPECIAL(sNaN, neg_inf, aNaN, false, FE_INVALID); @@ -165,10 +175,10 @@ public: TEST_SPECIAL(neg_sNaN, sNaN, aNaN, false, FE_INVALID); TEST_SPECIAL(neg_sNaN, neg_sNaN, aNaN, false, FE_INVALID); - TEST_SPECIAL(T(6.5), T(2.25), T(2.0), false, 0); - TEST_SPECIAL(T(-6.5), T(2.25), T(-2.0), false, 0); - TEST_SPECIAL(T(6.5), T(-2.25), T(2.0), false, 0); - TEST_SPECIAL(T(-6.5), T(-2.25), T(-2.0), false, 0); + TEST_SPECIAL(val_6_5, val_2_25, two, false, 0); + TEST_SPECIAL(val_neg_6_5, val_2_25, neg_two, false, 0); + TEST_SPECIAL(val_6_5, val_neg_2_25, two, false, 0); + TEST_SPECIAL(val_neg_6_5, val_neg_2_25, neg_two, false, 0); TEST_SPECIAL(max_normal, max_normal, zero, false, 0); TEST_SPECIAL(max_normal, -max_normal, zero, false, 0); diff --git a/libc/test/src/math/smoke/FloorTest.h b/libc/test/src/math/smoke/FloorTest.h index bc19e4f..cbcf276 100644 --- a/libc/test/src/math/smoke/FloorTest.h +++ b/libc/test/src/math/smoke/FloorTest.h @@ -59,10 +59,11 @@ public: EXPECT_FP_EQ(T(-11.0), func(T(-10.32))); EXPECT_FP_EQ(T(10.0), func(T(10.65))); EXPECT_FP_EQ(T(-11.0), func(T(-10.65))); + EXPECT_FP_EQ(T(50.0), func(T(50.31))); + EXPECT_FP_EQ(T(-50.0), func(T(-49.63))); EXPECT_FP_EQ(T(123.0), func(T(123.38))); EXPECT_FP_EQ(T(-124.0), func(T(-123.38))); - EXPECT_FP_EQ(T(123.0), func(T(123.96))); - EXPECT_FP_EQ(T(-124.0), func(T(-123.96))); + EXPECT_FP_EQ(T(-124.0), func(T(-123.5))); } }; diff --git a/libc/test/src/math/smoke/FromfpTest.h b/libc/test/src/math/smoke/FromfpTest.h index 5620518..708ec25 100644 --- a/libc/test/src/math/smoke/FromfpTest.h +++ b/libc/test/src/math/smoke/FromfpTest.h @@ -85,10 +85,10 @@ public: EXPECT_FP_EQ(T(-10.0), func(T(-10.32), FP_INT_UPWARD, 5U)); EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_UPWARD, 5U)); EXPECT_FP_EQ(T(-10.0), func(T(-10.65), FP_INT_UPWARD, 5U)); - EXPECT_FP_EQ(T(124.0), func(T(123.38), FP_INT_UPWARD, 8U)); - EXPECT_FP_EQ(T(-123.0), func(T(-123.38), FP_INT_UPWARD, 8U)); - EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_UPWARD, 8U)); - EXPECT_FP_EQ(T(-123.0), func(T(-123.96), FP_INT_UPWARD, 8U)); + EXPECT_FP_EQ(T(64.0), func(T(63.25), FP_INT_UPWARD, 8U)); + EXPECT_FP_EQ(T(-63.0), func(T(-63.25), FP_INT_UPWARD, 8U)); + EXPECT_FP_EQ(T(64.0), func(T(63.75), FP_INT_UPWARD, 8U)); + EXPECT_FP_EQ(T(-63.0), func(T(-63.75), FP_INT_UPWARD, 8U)); } void testFractionsUpwardOutsideRange(FromfpFunc func) { @@ -139,10 +139,10 @@ public: EXPECT_FP_EQ(T(-11.0), func(T(-10.32), FP_INT_DOWNWARD, 5U)); EXPECT_FP_EQ(T(10.0), func(T(10.65), FP_INT_DOWNWARD, 5U)); EXPECT_FP_EQ(T(-11.0), func(T(-10.65), FP_INT_DOWNWARD, 5U)); - EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_DOWNWARD, 8U)); - EXPECT_FP_EQ(T(-124.0), func(T(-123.38), FP_INT_DOWNWARD, 8U)); - EXPECT_FP_EQ(T(123.0), func(T(123.96), FP_INT_DOWNWARD, 8U)); - EXPECT_FP_EQ(T(-124.0), func(T(-123.96), FP_INT_DOWNWARD, 8U)); + EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_DOWNWARD, 8U)); + EXPECT_FP_EQ(T(-64.0), func(T(-63.25), FP_INT_DOWNWARD, 8U)); + EXPECT_FP_EQ(T(63.0), func(T(63.75), FP_INT_DOWNWARD, 8U)); + EXPECT_FP_EQ(T(-64.0), func(T(-63.75), FP_INT_DOWNWARD, 8U)); } void testFractionsDownwardOutsideRange(FromfpFunc func) { @@ -193,10 +193,10 @@ public: EXPECT_FP_EQ(T(-10.0), func(T(-10.32), FP_INT_TOWARDZERO, 5U)); EXPECT_FP_EQ(T(10.0), func(T(10.65), FP_INT_TOWARDZERO, 5U)); EXPECT_FP_EQ(T(-10.0), func(T(-10.65), FP_INT_TOWARDZERO, 5U)); - EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TOWARDZERO, 8U)); - EXPECT_FP_EQ(T(-123.0), func(T(-123.38), FP_INT_TOWARDZERO, 8U)); - EXPECT_FP_EQ(T(123.0), func(T(123.96), FP_INT_TOWARDZERO, 8U)); - EXPECT_FP_EQ(T(-123.0), func(T(-123.96), FP_INT_TOWARDZERO, 8U)); + EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_TOWARDZERO, 8U)); + EXPECT_FP_EQ(T(-63.0), func(T(-63.25), FP_INT_TOWARDZERO, 8U)); + EXPECT_FP_EQ(T(63.0), func(T(63.75), FP_INT_TOWARDZERO, 8U)); + EXPECT_FP_EQ(T(-63.0), func(T(-63.75), FP_INT_TOWARDZERO, 8U)); } void testFractionsTowardZeroOutsideRange(FromfpFunc func) { @@ -241,10 +241,10 @@ public: EXPECT_FP_EQ(T(-10.0), func(T(-10.32), FP_INT_TONEARESTFROMZERO, 5U)); EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_TONEARESTFROMZERO, 5U)); EXPECT_FP_EQ(T(-11.0), func(T(-10.65), FP_INT_TONEARESTFROMZERO, 5U)); - EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TONEARESTFROMZERO, 8U)); - EXPECT_FP_EQ(T(-123.0), func(T(-123.38), FP_INT_TONEARESTFROMZERO, 8U)); - EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_TONEARESTFROMZERO, 8U)); - EXPECT_FP_EQ(T(-124.0), func(T(-123.96), FP_INT_TONEARESTFROMZERO, 8U)); + EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_TONEARESTFROMZERO, 8U)); + EXPECT_FP_EQ(T(-63.0), func(T(-63.25), FP_INT_TONEARESTFROMZERO, 8U)); + EXPECT_FP_EQ(T(64.0), func(T(63.75), FP_INT_TONEARESTFROMZERO, 8U)); + EXPECT_FP_EQ(T(-64.0), func(T(-63.75), FP_INT_TONEARESTFROMZERO, 8U)); } void testFractionsToNearestFromZeroOutsideRange(FromfpFunc func) { @@ -297,10 +297,10 @@ public: EXPECT_FP_EQ(T(-10.0), func(T(-10.32), FP_INT_TONEAREST, 5U)); EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_TONEAREST, 5U)); EXPECT_FP_EQ(T(-11.0), func(T(-10.65), FP_INT_TONEAREST, 5U)); - EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TONEAREST, 8U)); - EXPECT_FP_EQ(T(-123.0), func(T(-123.38), FP_INT_TONEAREST, 8U)); - EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_TONEAREST, 8U)); - EXPECT_FP_EQ(T(-124.0), func(T(-123.96), FP_INT_TONEAREST, 8U)); + EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_TONEAREST, 8U)); + EXPECT_FP_EQ(T(-63.0), func(T(-63.25), FP_INT_TONEAREST, 8U)); + EXPECT_FP_EQ(T(64.0), func(T(63.75), FP_INT_TONEAREST, 8U)); + EXPECT_FP_EQ(T(-64.0), func(T(-63.75), FP_INT_TONEAREST, 8U)); EXPECT_FP_EQ(T(2.0), func(T(2.3), FP_INT_TONEAREST, 3U)); EXPECT_FP_EQ(T(-2.0), func(T(-2.3), FP_INT_TONEAREST, 2U)); @@ -391,14 +391,12 @@ public: EXPECT_FP_EQ(T(11.0), func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 5U)); EXPECT_FP_EQ(T(-11.0), func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 5U)); - EXPECT_FP_EQ(T(123.0), - func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U)); - EXPECT_FP_EQ(T(-123.0), - func(T(-123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U)); - EXPECT_FP_EQ(T(124.0), - func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U)); - EXPECT_FP_EQ(T(-124.0), - func(T(-123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U)); + EXPECT_FP_EQ(T(63.0), func(T(63.25), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U)); + EXPECT_FP_EQ(T(-63.0), + func(T(-63.25), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U)); + EXPECT_FP_EQ(T(64.0), func(T(63.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U)); + EXPECT_FP_EQ(T(-64.0), + func(T(-63.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U)); EXPECT_FP_EQ(T(2.0), func(T(2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U)); EXPECT_FP_EQ(T(-2.0), func(T(-2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U)); diff --git a/libc/test/src/math/smoke/FromfpxTest.h b/libc/test/src/math/smoke/FromfpxTest.h index a175a66..1930b22 100644 --- a/libc/test/src/math/smoke/FromfpxTest.h +++ b/libc/test/src/math/smoke/FromfpxTest.h @@ -101,13 +101,13 @@ public: FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION(T(-10.0), func(T(-10.65), FP_INT_UPWARD, 5U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.38), FP_INT_UPWARD, 8U), + EXPECT_FP_EQ_WITH_EXCEPTION(T(64.0), func(T(63.25), FP_INT_UPWARD, 8U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION(T(-123.0), func(T(-123.38), FP_INT_UPWARD, 8U), + EXPECT_FP_EQ_WITH_EXCEPTION(T(-63.0), func(T(-63.25), FP_INT_UPWARD, 8U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.96), FP_INT_UPWARD, 8U), + EXPECT_FP_EQ_WITH_EXCEPTION(T(64.0), func(T(63.75), FP_INT_UPWARD, 8U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION(T(-123.0), func(T(-123.96), FP_INT_UPWARD, 8U), + EXPECT_FP_EQ_WITH_EXCEPTION(T(-63.0), func(T(-63.75), FP_INT_UPWARD, 8U), FE_INEXACT); } @@ -175,14 +175,14 @@ public: FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION(T(-11.0), func(T(-10.65), FP_INT_DOWNWARD, 5U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.38), FP_INT_DOWNWARD, 8U), + EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.25), FP_INT_DOWNWARD, 8U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION( - T(-124.0), func(T(-123.38), FP_INT_DOWNWARD, 8U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.96), FP_INT_DOWNWARD, 8U), + EXPECT_FP_EQ_WITH_EXCEPTION(T(-64.0), func(T(-63.25), FP_INT_DOWNWARD, 8U), + FE_INEXACT); + EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.75), FP_INT_DOWNWARD, 8U), + FE_INEXACT); + EXPECT_FP_EQ_WITH_EXCEPTION(T(-64.0), func(T(-63.75), FP_INT_DOWNWARD, 8U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION( - T(-124.0), func(T(-123.96), FP_INT_DOWNWARD, 8U), FE_INEXACT); } void testFractionsDownwardOutsideRange(FromfpxFunc func) { @@ -249,14 +249,14 @@ public: FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( T(-10.0), func(T(-10.65), FP_INT_TOWARDZERO, 5U), FE_INEXACT); + EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.25), FP_INT_TOWARDZERO, 8U), + FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( - T(123.0), func(T(123.38), FP_INT_TOWARDZERO, 8U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION( - T(-123.0), func(T(-123.38), FP_INT_TOWARDZERO, 8U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION( - T(123.0), func(T(123.96), FP_INT_TOWARDZERO, 8U), FE_INEXACT); + T(-63.0), func(T(-63.25), FP_INT_TOWARDZERO, 8U), FE_INEXACT); + EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.75), FP_INT_TOWARDZERO, 8U), + FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( - T(-123.0), func(T(-123.96), FP_INT_TOWARDZERO, 8U), FE_INEXACT); + T(-63.0), func(T(-63.75), FP_INT_TOWARDZERO, 8U), FE_INEXACT); } void testFractionsTowardZeroOutsideRange(FromfpxFunc func) { @@ -318,13 +318,13 @@ public: EXPECT_FP_EQ_WITH_EXCEPTION( T(-11.0), func(T(-10.65), FP_INT_TONEARESTFROMZERO, 5U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( - T(123.0), func(T(123.38), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT); + T(63.0), func(T(63.25), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( - T(-123.0), func(T(-123.38), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT); + T(-63.0), func(T(-63.25), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( - T(124.0), func(T(123.96), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT); + T(64.0), func(T(63.75), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( - T(-124.0), func(T(-123.96), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT); + T(-64.0), func(T(-63.75), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT); } void testFractionsToNearestFromZeroOutsideRange(FromfpxFunc func) { @@ -393,14 +393,14 @@ public: FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION(T(-11.0), func(T(-10.65), FP_INT_TONEAREST, 5U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.38), FP_INT_TONEAREST, 8U), + EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.25), FP_INT_TONEAREST, 8U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION( - T(-123.0), func(T(-123.38), FP_INT_TONEAREST, 8U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.96), FP_INT_TONEAREST, 8U), + EXPECT_FP_EQ_WITH_EXCEPTION(T(-63.0), func(T(-63.25), FP_INT_TONEAREST, 8U), + FE_INEXACT); + EXPECT_FP_EQ_WITH_EXCEPTION(T(64.0), func(T(63.75), FP_INT_TONEAREST, 8U), + FE_INEXACT); + EXPECT_FP_EQ_WITH_EXCEPTION(T(-64.0), func(T(-63.75), FP_INT_TONEAREST, 8U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION( - T(-124.0), func(T(-123.96), FP_INT_TONEAREST, 8U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(2.3), FP_INT_TONEAREST, 3U), FE_INEXACT); @@ -530,16 +530,16 @@ public: T(-11.0), func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 5U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( - T(123.0), func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U), + T(63.0), func(T(63.25), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( - T(-123.0), func(T(-123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U), + T(-63.0), func(T(-63.25), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( - T(124.0), func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U), + T(64.0), func(T(63.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( - T(-124.0), func(T(-123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U), + T(-64.0), func(T(-63.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( diff --git a/libc/test/src/math/smoke/GetPayloadTest.h b/libc/test/src/math/smoke/GetPayloadTest.h index 1b1bf4f..486ea42 100644 --- a/libc/test/src/math/smoke/GetPayloadTest.h +++ b/libc/test/src/math/smoke/GetPayloadTest.h @@ -51,23 +51,50 @@ public: EXPECT_FP_EQ(default_snan_payload, funcWrapper(func, sNaN)); EXPECT_FP_EQ(default_snan_payload, funcWrapper(func, neg_sNaN)); - T qnan_42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val(); - T neg_qnan_42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val(); - T snan_42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val(); - T neg_snan_42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val(); - EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, qnan_42)); - EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, neg_qnan_42)); - EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, snan_42)); - EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, neg_snan_42)); - - T qnan_123 = FPBits::quiet_nan(Sign::POS, 0x123).get_val(); - T neg_qnan_123 = FPBits::quiet_nan(Sign::NEG, 0x123).get_val(); - T snan_123 = FPBits::signaling_nan(Sign::POS, 0x123).get_val(); - T neg_snan_123 = FPBits::signaling_nan(Sign::NEG, 0x123).get_val(); - EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, qnan_123)); - EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, neg_qnan_123)); - EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, snan_123)); - EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, neg_snan_123)); + if constexpr (FPBits::FRACTION_LEN - 1 >= 6) { + // [S] [E..E] [QM..M] -> number of M bits should be at least 6 + // 0x31 = 0b110001 = 6 bits + T qnan_31 = FPBits::quiet_nan(Sign::POS, 0x31).get_val(); + T neg_qnan_31 = FPBits::quiet_nan(Sign::NEG, 0x31).get_val(); + T snan_31 = FPBits::signaling_nan(Sign::POS, 0x31).get_val(); + T neg_snan_31 = FPBits::signaling_nan(Sign::NEG, 0x31).get_val(); + EXPECT_FP_EQ(T(0x31.0p+0), funcWrapper(func, qnan_31)); + EXPECT_FP_EQ(T(0x31.0p+0), funcWrapper(func, neg_qnan_31)); + EXPECT_FP_EQ(T(0x31.0p+0), funcWrapper(func, snan_31)); + EXPECT_FP_EQ(T(0x31.0p+0), funcWrapper(func, neg_snan_31)); + + // 0x15 = 0b10101 = 5 bits + T qnan_15 = FPBits::quiet_nan(Sign::POS, 0x15).get_val(); + T neg_qnan_15 = FPBits::quiet_nan(Sign::NEG, 0x15).get_val(); + T snan_15 = FPBits::signaling_nan(Sign::POS, 0x15).get_val(); + T neg_snan_15 = FPBits::signaling_nan(Sign::NEG, 0x15).get_val(); + EXPECT_FP_EQ(T(0x15.0p+0), funcWrapper(func, qnan_15)); + EXPECT_FP_EQ(T(0x15.0p+0), funcWrapper(func, neg_qnan_15)); + EXPECT_FP_EQ(T(0x15.0p+0), funcWrapper(func, snan_15)); + EXPECT_FP_EQ(T(0x15.0p+0), funcWrapper(func, neg_snan_15)); + } + + if constexpr (FPBits::FRACTION_LEN - 1 >= 7) { + T qnan_42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val(); + T neg_qnan_42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val(); + T snan_42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val(); + T neg_snan_42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val(); + EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, qnan_42)); + EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, neg_qnan_42)); + EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, snan_42)); + EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, neg_snan_42)); + } + + if constexpr (FPBits::FRACTION_LEN - 1 >= 9) { + T qnan_123 = FPBits::quiet_nan(Sign::POS, 0x123).get_val(); + T neg_qnan_123 = FPBits::quiet_nan(Sign::NEG, 0x123).get_val(); + T snan_123 = FPBits::signaling_nan(Sign::POS, 0x123).get_val(); + T neg_snan_123 = FPBits::signaling_nan(Sign::NEG, 0x123).get_val(); + EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, qnan_123)); + EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, neg_qnan_123)); + EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, snan_123)); + EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, neg_snan_123)); + } } }; diff --git a/libc/test/src/math/smoke/LdExpTest.h b/libc/test/src/math/smoke/LdExpTest.h index 8de70ad..d005f05 100644 --- a/libc/test/src/math/smoke/LdExpTest.h +++ b/libc/test/src/math/smoke/LdExpTest.h @@ -10,7 +10,8 @@ #define LLVM_LIBC_TEST_SRC_MATH_LDEXPTEST_H #include "hdr/stdint_proxy.h" -#include "src/__support/CPP/limits.h" // INT_MAX +#include "src/__support/CPP/algorithm.h" // cpp::min +#include "src/__support/CPP/limits.h" // INT_MAX #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/NormalFloat.h" #include "test/UnitTest/FEnvSafeTest.h" @@ -135,8 +136,8 @@ public: // Normal which trigger mantissa overflow. T x = NormalFloat(Sign::POS, -FPBits::EXP_BIAS + 1, StorageType(2) * NormalFloat::ONE - StorageType(1)); - ASSERT_FP_EQ(func(x, -1), x / 2); - ASSERT_FP_EQ(func(-x, -1), -x / 2); + ASSERT_FP_EQ(func(x, -1), T(x / 2)); + ASSERT_FP_EQ(func(-x, -1), -T(x / 2)); // Start with a normal number high exponent but pass a very low number for // exp. The result should be a subnormal number. @@ -154,7 +155,9 @@ public: // Start with a subnormal number but pass a very high number for exponent. // The result should not be infinity. - x = NormalFloat(Sign::POS, -FPBits::EXP_BIAS + 1, NormalFloat::ONE >> 10); + x = NormalFloat(Sign::POS, -FPBits::EXP_BIAS + 1, + NormalFloat::ONE >> + LIBC_NAMESPACE::cpp::min(FPBits::FRACTION_LEN, 10)); exp = FPBits::MAX_BIASED_EXPONENT + 5; ASSERT_FALSE(FPBits(func(x, exp)).is_inf()); // But if the exp is large enough to oversome than the normalization shift, diff --git a/libc/test/src/math/smoke/ModfTest.h b/libc/test/src/math/smoke/ModfTest.h index 24cfb115..71f1c6b 100644 --- a/libc/test/src/math/smoke/ModfTest.h +++ b/libc/test/src/math/smoke/ModfTest.h @@ -76,10 +76,16 @@ public: EXPECT_FP_EQ(T(-0.75), func(T(-10.75), &integral)); EXPECT_FP_EQ(integral, T(-10.0)); - EXPECT_FP_EQ(T(0.125), func(T(100.125), &integral)); + EXPECT_FP_EQ(T(0.125), func(T(31.125), &integral)); + EXPECT_FP_EQ(integral, T(31.0)); + + EXPECT_FP_EQ(T(-0.125), func(T(-31.125), &integral)); + EXPECT_FP_EQ(integral, T(-31.0)); + + EXPECT_FP_EQ(T(0.5), func(T(100.5), &integral)); EXPECT_FP_EQ(integral, T(100.0)); - EXPECT_FP_EQ(T(-0.125), func(T(-100.125), &integral)); + EXPECT_FP_EQ(T(-0.5), func(T(-100.5), &integral)); EXPECT_FP_EQ(integral, T(-100.0)); } diff --git a/libc/test/src/math/smoke/MulTest.h b/libc/test/src/math/smoke/MulTest.h index cf7f41a..5020067 100644 --- a/libc/test/src/math/smoke/MulTest.h +++ b/libc/test/src/math/smoke/MulTest.h @@ -53,10 +53,12 @@ public: EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, func(in.zero, in.neg_zero)); EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, func(in.neg_zero, in.zero)); - EXPECT_FP_EQ_ALL_ROUNDING(OutType(1.0), func(1.0, 1.0)); - EXPECT_FP_EQ_ALL_ROUNDING(OutType(15.0), func(3.0, 5.0)); - EXPECT_FP_EQ_ALL_ROUNDING(OutType(0x1.0p-13), func(0x1.0p+1, 0x1.0p-14)); - EXPECT_FP_EQ_ALL_ROUNDING(OutType(0x1.0p-10), func(0x1.0p+2, 0x1.0p-12)); + EXPECT_FP_EQ_ALL_ROUNDING(OutType(1.0), func(InType(1.0), InType(1.0))); + EXPECT_FP_EQ_ALL_ROUNDING(OutType(15.0), func(InType(3.0), InType(5.0))); + EXPECT_FP_EQ_ALL_ROUNDING(OutType(0x1.0p-13), + func(InType(0x1.0p+1), InType(0x1.0p-14))); + EXPECT_FP_EQ_ALL_ROUNDING(OutType(0x1.0p-10), + func(InType(0x1.0p+2), InType(0x1.0p-12))); } void test_invalid_operations(MulFunc func) { diff --git a/libc/test/src/math/smoke/NextAfterTest.h b/libc/test/src/math/smoke/NextAfterTest.h index be27c9f..b7e59f7 100644 --- a/libc/test/src/math/smoke/NextAfterTest.h +++ b/libc/test/src/math/smoke/NextAfterTest.h @@ -12,6 +12,7 @@ #include "src/__support/CPP/bit.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" +#include "src/__support/sign.h" #include "test/UnitTest/FEnvSafeTest.h" #include "test/UnitTest/FPMatcher.h" #include "test/UnitTest/Test.h" @@ -42,6 +43,8 @@ class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest { const T neg_inf = FPBits::inf(Sign::NEG).get_val(); const T zero = FPBits::zero(Sign::POS).get_val(); const T neg_zero = FPBits::zero(Sign::NEG).get_val(); + const T one = FPBits::one(Sign::POS).get_val(); + const T neg_one = FPBits::one(Sign::NEG).get_val(); const T nan = FPBits::quiet_nan().get_val(); static constexpr StorageType min_subnormal = @@ -55,8 +58,8 @@ public: typedef T (*NextAfterFunc)(T, T); void testNaN(NextAfterFunc func) { - ASSERT_FP_EQ(func(nan, 0), nan); - ASSERT_FP_EQ(func(0, nan), nan); + ASSERT_FP_EQ(func(nan, zero), nan); + ASSERT_FP_EQ(func(zero, nan), nan); } void testBoundaries(NextAfterFunc func) { @@ -65,68 +68,68 @@ public: // 'from' is zero|neg_zero. T x = zero; - T result = func(x, T(1)); + T result = func(x, one); StorageType expected_bits = 1; T expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); - result = func(x, T(-1)); + result = func(x, neg_one); expected_bits = FPBits::SIGN_MASK + 1; expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); x = neg_zero; - result = func(x, 1); + result = func(x, one); expected_bits = 1; expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); - result = func(x, -1); + result = func(x, neg_one); expected_bits = FPBits::SIGN_MASK + 1; expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); // 'from' is max subnormal value. x = LIBC_NAMESPACE::cpp::bit_cast<T>(max_subnormal); - result = func(x, 1); + result = func(x, one); expected = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal); ASSERT_FP_EQ(result, expected); - result = func(x, 0); + result = func(x, zero); expected_bits = max_subnormal - 1; expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); x = -x; - result = func(x, -1); + result = func(x, neg_one); expected_bits = FPBits::SIGN_MASK + min_normal; expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); ASSERT_FP_EQ(result, expected); - result = func(x, 0); + result = func(x, zero); expected_bits = FPBits::SIGN_MASK + max_subnormal - 1; expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); // 'from' is min subnormal value. x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_subnormal); - result = func(x, 1); + result = func(x, one); expected_bits = min_subnormal + 1; expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); - ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), zero); + ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, zero), zero); x = -x; - result = func(x, -1); + result = func(x, neg_one); expected_bits = FPBits::SIGN_MASK + min_subnormal + 1; expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); - ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), T(-0.0)); + ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, zero), neg_zero); // 'from' is min normal. x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal); - result = func(x, 0); + result = func(x, zero); expected_bits = max_subnormal; expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); @@ -137,7 +140,7 @@ public: ASSERT_FP_EQ(result, expected); x = -x; - result = func(x, 0); + result = func(x, zero); expected_bits = FPBits::SIGN_MASK + max_subnormal; expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected); @@ -157,14 +160,14 @@ public: // 'from' is infinity. x = inf; - result = func(x, 0); + result = func(x, zero); expected_bits = max_normal; expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); ASSERT_FP_EQ(result, expected); ASSERT_FP_EQ(func(x, inf), inf); x = neg_inf; - result = func(x, 0); + result = func(x, zero); expected_bits = FPBits::SIGN_MASK + max_normal; expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); ASSERT_FP_EQ(result, expected); @@ -172,7 +175,7 @@ public: // 'from' is a power of 2. x = T(32.0); - result = func(x, 0); + result = func(x, zero); FPBits x_bits = FPBits(x); FPBits result_bits = FPBits(result); ASSERT_EQ(result_bits.get_biased_exponent(), @@ -187,7 +190,7 @@ public: x = -x; - result = func(x, 0); + result = func(x, zero); result_bits = FPBits(result); ASSERT_EQ(result_bits.get_biased_exponent(), uint16_t(x_bits.get_biased_exponent() - 1)); diff --git a/libc/test/src/math/smoke/NextTowardTest.h b/libc/test/src/math/smoke/NextTowardTest.h index d2f352c..43e71c6 100644 --- a/libc/test/src/math/smoke/NextTowardTest.h +++ b/libc/test/src/math/smoke/NextTowardTest.h @@ -62,8 +62,8 @@ public: typedef T (*NextTowardFunc)(T, long double); void testNaN(NextTowardFunc func) { - ASSERT_FP_EQ(func(nan, 0), nan); - ASSERT_FP_EQ(func(0, to_nan), nan); + ASSERT_FP_EQ(func(nan, to_zero), nan); + ASSERT_FP_EQ(func(zero, to_nan), nan); } void testBoundaries(NextTowardFunc func) { diff --git a/libc/test/src/math/smoke/RoundTest.h b/libc/test/src/math/smoke/RoundTest.h index beb7000..72889da 100644 --- a/libc/test/src/math/smoke/RoundTest.h +++ b/libc/test/src/math/smoke/RoundTest.h @@ -59,8 +59,10 @@ public: EXPECT_FP_EQ(T(-10.0), func(T(-10.32))); EXPECT_FP_EQ(T(11.0), func(T(10.65))); EXPECT_FP_EQ(T(-11.0), func(T(-10.65))); - EXPECT_FP_EQ(T(123.0), func(T(123.38))); - EXPECT_FP_EQ(T(-123.0), func(T(-123.38))); + EXPECT_FP_EQ(T(50.0), func(T(49.63))); + EXPECT_FP_EQ(T(-50.0), func(T(-50.31))); + EXPECT_FP_EQ(T(124.0), func(T(123.5))); + EXPECT_FP_EQ(T(-124.0), func(T(-123.5))); EXPECT_FP_EQ(T(124.0), func(T(123.96))); EXPECT_FP_EQ(T(-124.0), func(T(-123.96))); } diff --git a/libc/test/src/math/smoke/RoundToIntegerTest.h b/libc/test/src/math/smoke/RoundToIntegerTest.h index 2b460ae..6866e91 100644 --- a/libc/test/src/math/smoke/RoundToIntegerTest.h +++ b/libc/test/src/math/smoke/RoundToIntegerTest.h @@ -97,8 +97,8 @@ public: test_one_input(func, F(-1.0), I(-1), false); test_one_input(func, F(10.0), I(10), false); test_one_input(func, F(-10.0), I(-10), false); - test_one_input(func, F(1234.0), I(1234), false); - test_one_input(func, F(-1234.0), I(-1234), false); + test_one_input(func, F(1232.0), I(1232), false); + test_one_input(func, F(-1232.0), I(-1232), false); } void testRoundNumbers(RoundToIntegerFunc func) { @@ -124,7 +124,7 @@ public: continue; // All subnormal numbers should round to zero. if (TestModes) { - if (x > 0) { + if (x > zero) { LIBC_NAMESPACE::fputil::set_round(FE_UPWARD); test_one_input(func, x, I(1), false); LIBC_NAMESPACE::fputil::set_round(FE_DOWNWARD); diff --git a/libc/test/src/math/smoke/SetPayloadSigTest.h b/libc/test/src/math/smoke/SetPayloadSigTest.h index f4804796..7b26c98 100644 --- a/libc/test/src/math/smoke/SetPayloadSigTest.h +++ b/libc/test/src/math/smoke/SetPayloadSigTest.h @@ -54,15 +54,31 @@ public: EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 1).uintval(), FPBits(res).uintval()); - EXPECT_EQ(0, func(&res, T(0x42.0p+0))); - EXPECT_TRUE(FPBits(res).is_signaling_nan()); - EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x42).uintval(), - FPBits(res).uintval()); - - EXPECT_EQ(0, func(&res, T(0x123.0p+0))); - EXPECT_TRUE(FPBits(res).is_signaling_nan()); - EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x123).uintval(), - FPBits(res).uintval()); + if constexpr (FPBits::FRACTION_LEN - 1 >= 6) { + EXPECT_EQ(0, func(&res, T(0x31.0p+0))); + EXPECT_TRUE(FPBits(res).is_signaling_nan()); + EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x31).uintval(), + FPBits(res).uintval()); + + EXPECT_EQ(0, func(&res, T(0x15.0p+0))); + EXPECT_TRUE(FPBits(res).is_signaling_nan()); + EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x15).uintval(), + FPBits(res).uintval()); + } + + if constexpr (FPBits::FRACTION_LEN - 1 >= 7) { + EXPECT_EQ(0, func(&res, T(0x42.0p+0))); + EXPECT_TRUE(FPBits(res).is_signaling_nan()); + EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x42).uintval(), + FPBits(res).uintval()); + } + + if constexpr (FPBits::FRACTION_LEN - 1 >= 9) { + EXPECT_EQ(0, func(&res, T(0x123.0p+0))); + EXPECT_TRUE(FPBits(res).is_signaling_nan()); + EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x123).uintval(), + FPBits(res).uintval()); + } FPBits nan_payload_bits = FPBits::one(); nan_payload_bits.set_biased_exponent(FPBits::FRACTION_LEN - 2 + diff --git a/libc/test/src/math/smoke/SetPayloadTest.h b/libc/test/src/math/smoke/SetPayloadTest.h index 9ede567..b86b325 100644 --- a/libc/test/src/math/smoke/SetPayloadTest.h +++ b/libc/test/src/math/smoke/SetPayloadTest.h @@ -54,15 +54,33 @@ public: EXPECT_TRUE(FPBits(res).is_quiet_nan()); EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 1).uintval(), FPBits(res).uintval()); - EXPECT_EQ(0, func(&res, T(0x42.0p+0))); - EXPECT_TRUE(FPBits(res).is_quiet_nan()); - EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x42).uintval(), - FPBits(res).uintval()); - - EXPECT_EQ(0, func(&res, T(0x123.0p+0))); - EXPECT_TRUE(FPBits(res).is_quiet_nan()); - EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x123).uintval(), - FPBits(res).uintval()); + if constexpr (FPBits::FRACTION_LEN - 1 >= 5) { + EXPECT_EQ(0, func(&res, T(0x15.0p+0))); + EXPECT_TRUE(FPBits(res).is_quiet_nan()); + EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x15).uintval(), + FPBits(res).uintval()); + } + + if constexpr (FPBits::FRACTION_LEN - 1 >= 6) { + EXPECT_EQ(0, func(&res, T(0x31.0p+0))); + EXPECT_TRUE(FPBits(res).is_quiet_nan()); + EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x31).uintval(), + FPBits(res).uintval()); + } + + if constexpr (FPBits::FRACTION_LEN - 1 >= 7) { + EXPECT_EQ(0, func(&res, T(0x42.0p+0))); + EXPECT_TRUE(FPBits(res).is_quiet_nan()); + EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x42).uintval(), + FPBits(res).uintval()); + } + + if constexpr (FPBits::FRACTION_LEN - 1 >= 9) { + EXPECT_EQ(0, func(&res, T(0x123.0p+0))); + EXPECT_TRUE(FPBits(res).is_quiet_nan()); + EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x123).uintval(), + FPBits(res).uintval()); + } // The following code is creating a NaN payload manually to prevent a // conversion from BigInt to float128. diff --git a/libc/test/src/math/smoke/SubTest.h b/libc/test/src/math/smoke/SubTest.h index c344db2..4ff4f3d 100644 --- a/libc/test/src/math/smoke/SubTest.h +++ b/libc/test/src/math/smoke/SubTest.h @@ -47,6 +47,10 @@ public: EXPECT_FP_EQ(neg_inf, func(in.neg_inf, in.zero)); EXPECT_FP_EQ(inf, func(in.inf, in.neg_zero)); EXPECT_FP_EQ(neg_inf, func(in.neg_inf, in.neg_zero)); + EXPECT_FP_EQ(neg_inf, func(in.zero, in.inf)); + EXPECT_FP_EQ(neg_inf, func(in.neg_zero, in.inf)); + EXPECT_FP_EQ(inf, func(in.zero, in.neg_inf)); + EXPECT_FP_EQ(inf, func(in.neg_zero, in.neg_inf)); } void test_invalid_operations(SubFunc func) { diff --git a/libc/test/src/math/smoke/TotalOrderMagTest.h b/libc/test/src/math/smoke/TotalOrderMagTest.h index 0a13fd2..8a389df 100644 --- a/libc/test/src/math/smoke/TotalOrderMagTest.h +++ b/libc/test/src/math/smoke/TotalOrderMagTest.h @@ -106,24 +106,45 @@ public: } void testNaNPayloads(TotalOrderMagFunc func) { - T qnan_0x42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val(); - T neg_qnan_0x42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val(); - T snan_0x42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val(); - T neg_snan_0x42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val(); - EXPECT_TRUE(funcWrapper(func, aNaN, aNaN)); EXPECT_TRUE(funcWrapper(func, sNaN, sNaN)); - EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x42)); - EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x42)); - EXPECT_FALSE(funcWrapper(func, qnan_0x42, aNaN)); - EXPECT_TRUE(funcWrapper(func, snan_0x42, sNaN)); EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_aNaN)); EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_sNaN)); - EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_qnan_0x42)); - EXPECT_FALSE(funcWrapper(func, neg_sNaN, neg_snan_0x42)); - EXPECT_FALSE(funcWrapper(func, neg_qnan_0x42, neg_aNaN)); - EXPECT_TRUE(funcWrapper(func, neg_snan_0x42, neg_sNaN)); + + if constexpr (FPBits::FRACTION_LEN - 1 >= 5) { + T qnan_0x15 = FPBits::quiet_nan(Sign::POS, 0x15).get_val(); + T neg_qnan_0x15 = FPBits::quiet_nan(Sign::NEG, 0x15).get_val(); + T snan_0x15 = FPBits::signaling_nan(Sign::POS, 0x15).get_val(); + T neg_snan_0x15 = FPBits::signaling_nan(Sign::NEG, 0x15).get_val(); + + EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x15)); + EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x15)); + EXPECT_FALSE(funcWrapper(func, qnan_0x15, aNaN)); + EXPECT_TRUE(funcWrapper(func, snan_0x15, sNaN)); + + EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_qnan_0x15)); + EXPECT_FALSE(funcWrapper(func, neg_sNaN, neg_snan_0x15)); + EXPECT_FALSE(funcWrapper(func, neg_qnan_0x15, neg_aNaN)); + EXPECT_TRUE(funcWrapper(func, neg_snan_0x15, neg_sNaN)); + } + + if constexpr (FPBits::FRACTION_LEN - 1 >= 7) { + T qnan_0x42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val(); + T neg_qnan_0x42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val(); + T snan_0x42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val(); + T neg_snan_0x42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val(); + + EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x42)); + EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x42)); + EXPECT_FALSE(funcWrapper(func, qnan_0x42, aNaN)); + EXPECT_TRUE(funcWrapper(func, snan_0x42, sNaN)); + + EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_qnan_0x42)); + EXPECT_FALSE(funcWrapper(func, neg_sNaN, neg_snan_0x42)); + EXPECT_FALSE(funcWrapper(func, neg_qnan_0x42, neg_aNaN)); + EXPECT_TRUE(funcWrapper(func, neg_snan_0x42, neg_sNaN)); + } } }; diff --git a/libc/test/src/math/smoke/TotalOrderTest.h b/libc/test/src/math/smoke/TotalOrderTest.h index e426eb3..50aac20 100644 --- a/libc/test/src/math/smoke/TotalOrderTest.h +++ b/libc/test/src/math/smoke/TotalOrderTest.h @@ -104,24 +104,45 @@ public: } void testNaNPayloads(TotalOrderFunc func) { - T qnan_0x42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val(); - T neg_qnan_0x42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val(); - T snan_0x42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val(); - T neg_snan_0x42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val(); - EXPECT_TRUE(funcWrapper(func, aNaN, aNaN)); EXPECT_TRUE(funcWrapper(func, sNaN, sNaN)); - EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x42)); - EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x42)); - EXPECT_FALSE(funcWrapper(func, qnan_0x42, aNaN)); - EXPECT_TRUE(funcWrapper(func, snan_0x42, sNaN)); EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_aNaN)); EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_sNaN)); - EXPECT_FALSE(funcWrapper(func, neg_aNaN, neg_qnan_0x42)); - EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_snan_0x42)); - EXPECT_TRUE(funcWrapper(func, neg_qnan_0x42, neg_aNaN)); - EXPECT_FALSE(funcWrapper(func, neg_snan_0x42, neg_sNaN)); + + if constexpr (FPBits::FRACTION_LEN - 1 >= 5) { + T qnan_0x15 = FPBits::quiet_nan(Sign::POS, 0x15).get_val(); + T neg_qnan_0x15 = FPBits::quiet_nan(Sign::NEG, 0x15).get_val(); + T snan_0x15 = FPBits::signaling_nan(Sign::POS, 0x15).get_val(); + T neg_snan_0x15 = FPBits::signaling_nan(Sign::NEG, 0x15).get_val(); + + EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x15)); + EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x15)); + EXPECT_FALSE(funcWrapper(func, qnan_0x15, aNaN)); + EXPECT_TRUE(funcWrapper(func, snan_0x15, sNaN)); + + EXPECT_FALSE(funcWrapper(func, neg_aNaN, neg_qnan_0x15)); + EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_snan_0x15)); + EXPECT_TRUE(funcWrapper(func, neg_qnan_0x15, neg_aNaN)); + EXPECT_FALSE(funcWrapper(func, neg_snan_0x15, neg_sNaN)); + } + + if constexpr (FPBits::FRACTION_LEN - 1 >= 7) { + T qnan_0x42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val(); + T neg_qnan_0x42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val(); + T snan_0x42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val(); + T neg_snan_0x42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val(); + + EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x42)); + EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x42)); + EXPECT_FALSE(funcWrapper(func, qnan_0x42, aNaN)); + EXPECT_TRUE(funcWrapper(func, snan_0x42, sNaN)); + + EXPECT_FALSE(funcWrapper(func, neg_aNaN, neg_qnan_0x42)); + EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_snan_0x42)); + EXPECT_TRUE(funcWrapper(func, neg_qnan_0x42, neg_aNaN)); + EXPECT_FALSE(funcWrapper(func, neg_snan_0x42, neg_sNaN)); + } } }; diff --git a/libc/test/src/math/smoke/TruncTest.h b/libc/test/src/math/smoke/TruncTest.h index 49688e8..e088f29 100644 --- a/libc/test/src/math/smoke/TruncTest.h +++ b/libc/test/src/math/smoke/TruncTest.h @@ -61,8 +61,8 @@ public: EXPECT_FP_EQ(T(-10.0), func(T(-10.65))); EXPECT_FP_EQ(T(123.0), func(T(123.38))); EXPECT_FP_EQ(T(-123.0), func(T(-123.38))); - EXPECT_FP_EQ(T(123.0), func(T(123.96))); - EXPECT_FP_EQ(T(-123.0), func(T(-123.96))); + EXPECT_FP_EQ(T(123.0), func(T(123.5))); + EXPECT_FP_EQ(T(-123.0), func(T(-123.5))); } }; diff --git a/libc/test/src/math/smoke/UfromfpTest.h b/libc/test/src/math/smoke/UfromfpTest.h index 84c9f80..16785de 100644 --- a/libc/test/src/math/smoke/UfromfpTest.h +++ b/libc/test/src/math/smoke/UfromfpTest.h @@ -76,8 +76,8 @@ public: EXPECT_FP_EQ(T(2.0), func(T(1.75), FP_INT_UPWARD, 2U)); EXPECT_FP_EQ(T(11.0), func(T(10.32), FP_INT_UPWARD, 4U)); EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_UPWARD, 4U)); - EXPECT_FP_EQ(T(124.0), func(T(123.38), FP_INT_UPWARD, 7U)); - EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_UPWARD, 7U)); + EXPECT_FP_EQ(T(64.0), func(T(63.25), FP_INT_UPWARD, 7U)); + EXPECT_FP_EQ(T(64.0), func(T(63.75), FP_INT_UPWARD, 7U)); } void testFractionsUpwardOutsideRange(UfromfpFunc func) { @@ -120,8 +120,8 @@ public: EXPECT_FP_EQ(T(1.0), func(T(1.75), FP_INT_DOWNWARD, 1U)); EXPECT_FP_EQ(T(10.0), func(T(10.32), FP_INT_DOWNWARD, 4U)); EXPECT_FP_EQ(T(10.0), func(T(10.65), FP_INT_DOWNWARD, 4U)); - EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_DOWNWARD, 7U)); - EXPECT_FP_EQ(T(123.0), func(T(123.96), FP_INT_DOWNWARD, 7U)); + EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_DOWNWARD, 7U)); + EXPECT_FP_EQ(T(63.0), func(T(63.75), FP_INT_DOWNWARD, 7U)); } void testFractionsDownwardOutsideRange(UfromfpFunc func) { @@ -167,8 +167,8 @@ public: EXPECT_FP_EQ(T(1.0), func(T(1.75), FP_INT_TOWARDZERO, 1U)); EXPECT_FP_EQ(T(10.0), func(T(10.32), FP_INT_TOWARDZERO, 4U)); EXPECT_FP_EQ(T(10.0), func(T(10.65), FP_INT_TOWARDZERO, 4U)); - EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TOWARDZERO, 7U)); - EXPECT_FP_EQ(T(123.0), func(T(123.96), FP_INT_TOWARDZERO, 7U)); + EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_TOWARDZERO, 7U)); + EXPECT_FP_EQ(T(63.0), func(T(63.75), FP_INT_TOWARDZERO, 7U)); } void testFractionsTowardZeroOutsideRange(UfromfpFunc func) { @@ -206,8 +206,8 @@ public: EXPECT_FP_EQ(T(2.0), func(T(1.75), FP_INT_TONEARESTFROMZERO, 2U)); EXPECT_FP_EQ(T(10.0), func(T(10.32), FP_INT_TONEARESTFROMZERO, 4U)); EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_TONEARESTFROMZERO, 4U)); - EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TONEARESTFROMZERO, 7U)); - EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_TONEARESTFROMZERO, 7U)); + EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_TONEARESTFROMZERO, 7U)); + EXPECT_FP_EQ(T(64.0), func(T(63.75), FP_INT_TONEARESTFROMZERO, 7U)); } void testFractionsToNearestFromZeroOutsideRange(UfromfpFunc func) { @@ -254,8 +254,8 @@ public: EXPECT_FP_EQ(T(2.0), func(T(1.75), FP_INT_TONEAREST, 2U)); EXPECT_FP_EQ(T(10.0), func(T(10.32), FP_INT_TONEAREST, 4U)); EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_TONEAREST, 4U)); - EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TONEAREST, 7U)); - EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_TONEAREST, 7U)); + EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_TONEAREST, 7U)); + EXPECT_FP_EQ(T(64.0), func(T(63.75), FP_INT_TONEAREST, 7U)); EXPECT_FP_EQ(T(2.0), func(T(2.3), FP_INT_TONEAREST, 2U)); EXPECT_FP_EQ(T(2.0), func(T(2.5), FP_INT_TONEAREST, 2U)); @@ -332,10 +332,8 @@ public: EXPECT_FP_EQ(T(2.0), func(T(1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U)); EXPECT_FP_EQ(T(10.0), func(T(10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U)); EXPECT_FP_EQ(T(11.0), func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U)); - EXPECT_FP_EQ(T(123.0), - func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U)); - EXPECT_FP_EQ(T(124.0), - func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U)); + EXPECT_FP_EQ(T(63.0), func(T(63.25), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U)); + EXPECT_FP_EQ(T(64.0), func(T(63.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U)); EXPECT_FP_EQ(T(2.0), func(T(2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U)); EXPECT_FP_EQ(T(2.0), func(T(2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U)); diff --git a/libc/test/src/math/smoke/UfromfpxTest.h b/libc/test/src/math/smoke/UfromfpxTest.h index 5916492..1d4d3a3 100644 --- a/libc/test/src/math/smoke/UfromfpxTest.h +++ b/libc/test/src/math/smoke/UfromfpxTest.h @@ -87,9 +87,9 @@ public: FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION(T(11.0), func(T(10.65), FP_INT_UPWARD, 4U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.38), FP_INT_UPWARD, 7U), + EXPECT_FP_EQ_WITH_EXCEPTION(T(64.0), func(T(63.25), FP_INT_UPWARD, 7U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.96), FP_INT_UPWARD, 7U), + EXPECT_FP_EQ_WITH_EXCEPTION(T(64.0), func(T(63.75), FP_INT_UPWARD, 7U), FE_INEXACT); } @@ -141,9 +141,9 @@ public: FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.65), FP_INT_DOWNWARD, 4U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.38), FP_INT_DOWNWARD, 7U), + EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.25), FP_INT_DOWNWARD, 7U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.96), FP_INT_DOWNWARD, 7U), + EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.75), FP_INT_DOWNWARD, 7U), FE_INEXACT); } @@ -201,10 +201,10 @@ public: FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.65), FP_INT_TOWARDZERO, 4U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION( - T(123.0), func(T(123.38), FP_INT_TOWARDZERO, 7U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION( - T(123.0), func(T(123.96), FP_INT_TOWARDZERO, 7U), FE_INEXACT); + EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.25), FP_INT_TOWARDZERO, 7U), + FE_INEXACT); + EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.75), FP_INT_TOWARDZERO, 7U), + FE_INEXACT); } void testFractionsTowardZeroOutsideRange(UfromfpxFunc func) { @@ -252,9 +252,9 @@ public: EXPECT_FP_EQ_WITH_EXCEPTION( T(11.0), func(T(10.65), FP_INT_TONEARESTFROMZERO, 4U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( - T(123.0), func(T(123.38), FP_INT_TONEARESTFROMZERO, 7U), FE_INEXACT); + T(63.0), func(T(63.25), FP_INT_TONEARESTFROMZERO, 7U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( - T(124.0), func(T(123.96), FP_INT_TONEARESTFROMZERO, 7U), FE_INEXACT); + T(64.0), func(T(63.75), FP_INT_TONEARESTFROMZERO, 7U), FE_INEXACT); } void testFractionsToNearestFromZeroOutsideRange(UfromfpxFunc func) { @@ -311,9 +311,9 @@ public: FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION(T(11.0), func(T(10.65), FP_INT_TONEAREST, 4U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.38), FP_INT_TONEAREST, 7U), + EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.25), FP_INT_TONEAREST, 7U), FE_INEXACT); - EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.96), FP_INT_TONEAREST, 7U), + EXPECT_FP_EQ_WITH_EXCEPTION(T(64.0), func(T(63.75), FP_INT_TONEAREST, 7U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(2.3), FP_INT_TONEAREST, 2U), @@ -414,10 +414,10 @@ public: T(11.0), func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( - T(123.0), func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U), + T(63.0), func(T(63.25), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( - T(124.0), func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U), + T(64.0), func(T(63.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U), FE_INEXACT); EXPECT_FP_EQ_WITH_EXCEPTION( diff --git a/libc/test/src/math/smoke/asinpif16_test.cpp b/libc/test/src/math/smoke/asinpif16_test.cpp new file mode 100644 index 0000000..5303eed --- /dev/null +++ b/libc/test/src/math/smoke/asinpif16_test.cpp @@ -0,0 +1,86 @@ +//===-- Unittests for asinpif16 -------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/__support/libc_errno.h" +#include "src/math/asinpif16.h" +#include "test/UnitTest/FPMatcher.h" + +using LlvmLibcAsinpif16Test = LIBC_NAMESPACE::testing::FPTest<float16>; + +TEST_F(LlvmLibcAsinpif16Test, SpecialNumbers) { + // zero + EXPECT_FP_EQ(zero, LIBC_NAMESPACE::asinpif16(zero)); + + // +/-1 + EXPECT_FP_EQ(0.5f16, LIBC_NAMESPACE::asinpif16(1.0)); + EXPECT_FP_EQ(-0.5f16, LIBC_NAMESPACE::asinpif16(-1.0)); + + // NaN inputs + EXPECT_FP_EQ(FPBits::quiet_nan().get_val(), + LIBC_NAMESPACE::asinpif16(FPBits::quiet_nan().get_val())); + + EXPECT_FP_EQ(FPBits::quiet_nan().get_val(), + LIBC_NAMESPACE::asinpif16(FPBits::signaling_nan().get_val())); + + // infinity inputs -> should return NaN + libc_errno = 0; + EXPECT_FP_EQ(FPBits::quiet_nan().get_val(), LIBC_NAMESPACE::asinpif16(inf)); + EXPECT_MATH_ERRNO(EDOM); + + libc_errno = 0; + EXPECT_FP_EQ(FPBits::quiet_nan().get_val(), + LIBC_NAMESPACE::asinpif16(neg_inf)); + EXPECT_MATH_ERRNO(EDOM); +} + +TEST_F(LlvmLibcAsinpif16Test, OutOfRange) { + // Test values > 1 + libc_errno = 0; + EXPECT_FP_EQ(FPBits::quiet_nan().get_val(), + LIBC_NAMESPACE::asinpif16(1.5f16)); + EXPECT_MATH_ERRNO(EDOM); + + libc_errno = 0; + EXPECT_FP_EQ(FPBits::quiet_nan().get_val(), + LIBC_NAMESPACE::asinpif16(2.0f16)); + EXPECT_MATH_ERRNO(EDOM); + + // Test values < -1 + libc_errno = 0; + EXPECT_FP_EQ(FPBits::quiet_nan().get_val(), + LIBC_NAMESPACE::asinpif16(-1.5f16)); + EXPECT_MATH_ERRNO(EDOM); + + libc_errno = 0; + EXPECT_FP_EQ(FPBits::quiet_nan().get_val(), + LIBC_NAMESPACE::asinpif16(-2.0f16)); + EXPECT_MATH_ERRNO(EDOM); + + // Test maximum normal value (should be > 1 for float16) + libc_errno = 0; + EXPECT_FP_EQ(FPBits::quiet_nan().get_val(), + LIBC_NAMESPACE::asinpif16(FPBits::max_normal().get_val())); + EXPECT_MATH_ERRNO(EDOM); +} + +TEST_F(LlvmLibcAsinpif16Test, SymmetryProperty) { + // Test that asinpi(-x) = -asinpi(x) + constexpr float16 TEST_VALS[] = {0.1f16, 0.25f16, 0.5f16, 0.75f16, + 0.9f16, 0.99f16, 1.0f16}; + + for (float16 x : TEST_VALS) { + FPBits neg_x_bits(x); + neg_x_bits.set_sign(Sign::NEG); + float16 neg_x = neg_x_bits.get_val(); + + float16 pos_result = LIBC_NAMESPACE::asinpif16(x); + float16 neg_result = LIBC_NAMESPACE::asinpif16(neg_x); + + EXPECT_FP_EQ(pos_result, FPBits(neg_result).abs().get_val()); + } +} diff --git a/libc/test/src/math/smoke/atanpif16_test.cpp b/libc/test/src/math/smoke/atanpif16_test.cpp new file mode 100644 index 0000000..9eb1005a --- /dev/null +++ b/libc/test/src/math/smoke/atanpif16_test.cpp @@ -0,0 +1,64 @@ +//===-- Unittests for atanpif16 -------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/__support/libc_errno.h" +#include "src/math/atanpif16.h" +#include "test/UnitTest/FPMatcher.h" + +using LIBC_NAMESPACE::cpp::array; +using LlvmLibcAtanpif16Test = LIBC_NAMESPACE::testing::FPTest<float16>; + +TEST_F(LlvmLibcAtanpif16Test, SpecialNumbers) { + // zero + EXPECT_FP_EQ(zero, LIBC_NAMESPACE::atanpif16(zero)); + EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::atanpif16(neg_zero)); + + // NaN inputs + EXPECT_FP_EQ(FPBits::quiet_nan().get_val(), + LIBC_NAMESPACE::atanpif16(FPBits::quiet_nan().get_val())); + + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::atanpif16(aNaN)); + + // infinity inputs -> should return +/-0.5 + EXPECT_FP_EQ(0.5f16, LIBC_NAMESPACE::atanpif16(inf)); + EXPECT_FP_EQ(-0.5f16, LIBC_NAMESPACE::atanpif16(neg_inf)); +} + +TEST_F(LlvmLibcAtanpif16Test, SymmetryProperty) { + // Test that atanpi(-x) = -atanpi(x) + constexpr array<float16, 12> TEST_VALS = { + 0.1f16, 0.25f16, 0.5f16, 0.75f16, 1.0f16, 1.5f16, + 2.0f16, 5.0f16, 10.0f16, 50.0f16, 100.0f16, 1000.0f16}; + + for (float16 x : TEST_VALS) { + FPBits neg_x_bits(x); + neg_x_bits.set_sign(Sign::NEG); + float16 neg_x = neg_x_bits.get_val(); + + float16 pos_result = LIBC_NAMESPACE::atanpif16(x); + float16 neg_result = LIBC_NAMESPACE::atanpif16(neg_x); + + EXPECT_FP_EQ(pos_result, FPBits(neg_result).abs().get_val()); + } +} + +TEST_F(LlvmLibcAtanpif16Test, MonotonicityProperty) { + // Test that atanpi is monotonically increasing + constexpr array<float16, 15> TEST_VALS = { + -1000.0f16, -100.0f16, -10.0f16, -2.0f16, -1.0f16, + -0.5f16, -0.1f16, 0.0f16, 0.1f16, 0.5f16, + 1.0f16, 2.0f16, 10.0f16, 100.0f16, 1000.0f16}; + for (size_t i = 0; i < TEST_VALS.size() - 1; ++i) { + float16 x1 = TEST_VALS[i]; + float16 x2 = TEST_VALS[i + 1]; + float16 result1 = LIBC_NAMESPACE::atanpif16(x1); + float16 result2 = LIBC_NAMESPACE::atanpif16(x2); + + EXPECT_TRUE(result1 < result2); + } +} diff --git a/libc/test/src/math/smoke/bf16add_test.cpp b/libc/test/src/math/smoke/bf16add_test.cpp new file mode 100644 index 0000000..9e9c594 --- /dev/null +++ b/libc/test/src/math/smoke/bf16add_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16add ---------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "AddTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16add.h" + +LIST_ADD_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16add) diff --git a/libc/test/src/math/smoke/bf16addf128_test.cpp b/libc/test/src/math/smoke/bf16addf128_test.cpp new file mode 100644 index 0000000..46f7ad3 --- /dev/null +++ b/libc/test/src/math/smoke/bf16addf128_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16addf128 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "AddTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16addf128.h" + +LIST_ADD_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16addf128) diff --git a/libc/test/src/math/smoke/bf16addf_test.cpp b/libc/test/src/math/smoke/bf16addf_test.cpp new file mode 100644 index 0000000..06d56cf --- /dev/null +++ b/libc/test/src/math/smoke/bf16addf_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16addf --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "AddTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16addf.h" + +LIST_ADD_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16addf) diff --git a/libc/test/src/math/smoke/bf16addl_test.cpp b/libc/test/src/math/smoke/bf16addl_test.cpp new file mode 100644 index 0000000..bf54827 --- /dev/null +++ b/libc/test/src/math/smoke/bf16addl_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16addl --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "AddTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16addl.h" + +LIST_ADD_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16addl) diff --git a/libc/test/src/math/smoke/bf16div_test.cpp b/libc/test/src/math/smoke/bf16div_test.cpp new file mode 100644 index 0000000..4516351 --- /dev/null +++ b/libc/test/src/math/smoke/bf16div_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16div ---------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "DivTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16div.h" + +LIST_DIV_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16div) diff --git a/libc/test/src/math/smoke/bf16divf128_test.cpp b/libc/test/src/math/smoke/bf16divf128_test.cpp new file mode 100644 index 0000000..c42c5bb --- /dev/null +++ b/libc/test/src/math/smoke/bf16divf128_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16divf128 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "DivTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16divf128.h" + +LIST_DIV_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16divf128) diff --git a/libc/test/src/math/smoke/bf16divf_test.cpp b/libc/test/src/math/smoke/bf16divf_test.cpp new file mode 100644 index 0000000..873920b --- /dev/null +++ b/libc/test/src/math/smoke/bf16divf_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16divf --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "DivTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16divf.h" + +LIST_DIV_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16divf) diff --git a/libc/test/src/math/smoke/bf16divl_test.cpp b/libc/test/src/math/smoke/bf16divl_test.cpp new file mode 100644 index 0000000..32ecd62 --- /dev/null +++ b/libc/test/src/math/smoke/bf16divl_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16divl --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "DivTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16divl.h" + +LIST_DIV_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16divl) diff --git a/libc/test/src/math/smoke/bf16fma_test.cpp b/libc/test/src/math/smoke/bf16fma_test.cpp new file mode 100644 index 0000000..81c73a0c --- /dev/null +++ b/libc/test/src/math/smoke/bf16fma_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16fma ---------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FmaTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16fma.h" + +LIST_NARROWING_FMA_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16fma) diff --git a/libc/test/src/math/smoke/bf16fmaf128_test.cpp b/libc/test/src/math/smoke/bf16fmaf128_test.cpp new file mode 100644 index 0000000..dd8f473 --- /dev/null +++ b/libc/test/src/math/smoke/bf16fmaf128_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16fmaf128 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FmaTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16fmaf128.h" + +LIST_NARROWING_FMA_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16fmaf128) diff --git a/libc/test/src/math/smoke/bf16fmaf_test.cpp b/libc/test/src/math/smoke/bf16fmaf_test.cpp new file mode 100644 index 0000000..04c6748 --- /dev/null +++ b/libc/test/src/math/smoke/bf16fmaf_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16fmaf --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FmaTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16fmaf.h" + +LIST_NARROWING_FMA_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16fmaf) diff --git a/libc/test/src/math/smoke/bf16fmal_test.cpp b/libc/test/src/math/smoke/bf16fmal_test.cpp new file mode 100644 index 0000000..4c45e2c --- /dev/null +++ b/libc/test/src/math/smoke/bf16fmal_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16fmal --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FmaTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16fmal.h" + +LIST_NARROWING_FMA_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16fmal) diff --git a/libc/test/src/math/smoke/bf16mul_test.cpp b/libc/test/src/math/smoke/bf16mul_test.cpp new file mode 100644 index 0000000..db6f0cb --- /dev/null +++ b/libc/test/src/math/smoke/bf16mul_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16mul ---------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "MulTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16mul.h" + +LIST_MUL_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16mul) diff --git a/libc/test/src/math/smoke/bf16mulf128_test.cpp b/libc/test/src/math/smoke/bf16mulf128_test.cpp new file mode 100644 index 0000000..03cb9f2 --- /dev/null +++ b/libc/test/src/math/smoke/bf16mulf128_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16mulf128 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "MulTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16mulf128.h" + +LIST_MUL_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16mulf128) diff --git a/libc/test/src/math/smoke/bf16mulf_test.cpp b/libc/test/src/math/smoke/bf16mulf_test.cpp new file mode 100644 index 0000000..ec40e98 --- /dev/null +++ b/libc/test/src/math/smoke/bf16mulf_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16mulf --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "MulTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16mulf.h" + +LIST_MUL_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16mulf) diff --git a/libc/test/src/math/smoke/bf16mull_test.cpp b/libc/test/src/math/smoke/bf16mull_test.cpp new file mode 100644 index 0000000..4cb9c9c --- /dev/null +++ b/libc/test/src/math/smoke/bf16mull_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16mull --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "MulTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16mull.h" + +LIST_MUL_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16mull) diff --git a/libc/test/src/math/smoke/bf16sub_test.cpp b/libc/test/src/math/smoke/bf16sub_test.cpp new file mode 100644 index 0000000..4a793dc --- /dev/null +++ b/libc/test/src/math/smoke/bf16sub_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16sub ---------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "SubTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16sub.h" + +LIST_SUB_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16sub) diff --git a/libc/test/src/math/smoke/bf16subf128_test.cpp b/libc/test/src/math/smoke/bf16subf128_test.cpp new file mode 100644 index 0000000..25d6711 --- /dev/null +++ b/libc/test/src/math/smoke/bf16subf128_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16subf128 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "SubTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16subf128.h" + +LIST_SUB_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16subf128) diff --git a/libc/test/src/math/smoke/bf16subf_test.cpp b/libc/test/src/math/smoke/bf16subf_test.cpp new file mode 100644 index 0000000..e8c7440 --- /dev/null +++ b/libc/test/src/math/smoke/bf16subf_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16subf --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "SubTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16subf.h" + +LIST_SUB_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16subf) diff --git a/libc/test/src/math/smoke/bf16subl_test.cpp b/libc/test/src/math/smoke/bf16subl_test.cpp new file mode 100644 index 0000000..2997369 --- /dev/null +++ b/libc/test/src/math/smoke/bf16subl_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for bf16subl --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "SubTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/bf16subl.h" + +LIST_SUB_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16subl) diff --git a/libc/test/src/math/smoke/bfloat16_add_test.cpp b/libc/test/src/math/smoke/bfloat16_add_test.cpp new file mode 100644 index 0000000..1db65a9 --- /dev/null +++ b/libc/test/src/math/smoke/bfloat16_add_test.cpp @@ -0,0 +1,15 @@ +//===-- Unittests for bfloat16 addition -----------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "AddTest.h" + +#include "src/__support/FPUtil/bfloat16.h" + +static bfloat16 add_func(bfloat16 x, bfloat16 y) { return x + y; } + +LIST_ADD_TESTS(bfloat16, bfloat16, add_func) diff --git a/libc/test/src/math/smoke/bfloat16_div_test.cpp b/libc/test/src/math/smoke/bfloat16_div_test.cpp new file mode 100644 index 0000000..c1ab598 --- /dev/null +++ b/libc/test/src/math/smoke/bfloat16_div_test.cpp @@ -0,0 +1,15 @@ +//===-- Unittests for bfloat16 division -----------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "DivTest.h" + +#include "src/__support/FPUtil/bfloat16.h" + +static bfloat16 div_func(bfloat16 x, bfloat16 y) { return x / y; } + +LIST_DIV_TESTS(bfloat16, bfloat16, div_func) diff --git a/libc/test/src/math/smoke/bfloat16_mul_test.cpp b/libc/test/src/math/smoke/bfloat16_mul_test.cpp new file mode 100644 index 0000000..03e38d8 --- /dev/null +++ b/libc/test/src/math/smoke/bfloat16_mul_test.cpp @@ -0,0 +1,15 @@ +//===-- Unittests for bfloat16 multiplication -----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "MulTest.h" + +#include "src/__support/FPUtil/bfloat16.h" + +static bfloat16 mul_func(bfloat16 x, bfloat16 y) { return x * y; } + +LIST_MUL_TESTS(bfloat16, bfloat16, mul_func) diff --git a/libc/test/src/math/smoke/bfloat16_sub_test.cpp b/libc/test/src/math/smoke/bfloat16_sub_test.cpp new file mode 100644 index 0000000..5eb4a9b --- /dev/null +++ b/libc/test/src/math/smoke/bfloat16_sub_test.cpp @@ -0,0 +1,15 @@ +//===-- Unittests for bfloat16 subtraction --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "SubTest.h" + +#include "src/__support/FPUtil/bfloat16.h" + +static bfloat16 sub_func(bfloat16 x, bfloat16 y) { return x - y; } + +LIST_SUB_TESTS(bfloat16, bfloat16, sub_func) diff --git a/libc/test/src/math/smoke/canonicalizebf16_test.cpp b/libc/test/src/math/smoke/canonicalizebf16_test.cpp new file mode 100644 index 0000000..bf955c2 --- /dev/null +++ b/libc/test/src/math/smoke/canonicalizebf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for canonicalizebf16 ------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "CanonicalizeTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/canonicalizebf16.h" + +LIST_CANONICALIZE_TESTS(bfloat16, LIBC_NAMESPACE::canonicalizebf16) diff --git a/libc/test/src/math/smoke/ceilbf16_test.cpp b/libc/test/src/math/smoke/ceilbf16_test.cpp new file mode 100644 index 0000000..dcaf058 --- /dev/null +++ b/libc/test/src/math/smoke/ceilbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for ceilbf16 --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "CeilTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/ceilbf16.h" + +LIST_CEIL_TESTS(bfloat16, LIBC_NAMESPACE::ceilbf16) diff --git a/libc/test/src/math/smoke/copysignbf16_test.cpp b/libc/test/src/math/smoke/copysignbf16_test.cpp new file mode 100644 index 0000000..71a97e3 --- /dev/null +++ b/libc/test/src/math/smoke/copysignbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for copysignbf16 ----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "CopySignTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/copysignbf16.h" + +LIST_COPYSIGN_TESTS(bfloat16, LIBC_NAMESPACE::copysignbf16) diff --git a/libc/test/src/math/smoke/fdimbf16_test.cpp b/libc/test/src/math/smoke/fdimbf16_test.cpp new file mode 100644 index 0000000..43e8039 --- /dev/null +++ b/libc/test/src/math/smoke/fdimbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for fdimbf16 --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FDimTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fdimbf16.h" + +LIST_FDIM_TESTS(bfloat16, LIBC_NAMESPACE::fdimbf16); diff --git a/libc/test/src/math/smoke/floorbf16_test.cpp b/libc/test/src/math/smoke/floorbf16_test.cpp new file mode 100644 index 0000000..9cc77cd --- /dev/null +++ b/libc/test/src/math/smoke/floorbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for floorbf16 -------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FloorTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/floorbf16.h" + +LIST_FLOOR_TESTS(bfloat16, LIBC_NAMESPACE::floorbf16) diff --git a/libc/test/src/math/smoke/fmaxbf16_test.cpp b/libc/test/src/math/smoke/fmaxbf16_test.cpp new file mode 100644 index 0000000..8ff9313 --- /dev/null +++ b/libc/test/src/math/smoke/fmaxbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for fmaxbf16 --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FMaxTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fmaxbf16.h" + +LIST_FMAX_TESTS(bfloat16, LIBC_NAMESPACE::fmaxbf16) diff --git a/libc/test/src/math/smoke/fmaximum_mag_numbf16_test.cpp b/libc/test/src/math/smoke/fmaximum_mag_numbf16_test.cpp new file mode 100644 index 0000000..9e435cc --- /dev/null +++ b/libc/test/src/math/smoke/fmaximum_mag_numbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for fmaximum_mag_numbf16 --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FMaximumMagNumTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fmaximum_mag_numbf16.h" + +LIST_FMAXIMUM_MAG_NUM_TESTS(bfloat16, LIBC_NAMESPACE::fmaximum_mag_numbf16) diff --git a/libc/test/src/math/smoke/fmaximum_magbf16_test.cpp b/libc/test/src/math/smoke/fmaximum_magbf16_test.cpp new file mode 100644 index 0000000..22a0bc3 --- /dev/null +++ b/libc/test/src/math/smoke/fmaximum_magbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for fmaximum_magbf16 ------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FMaximumMagTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fmaximum_magbf16.h" + +LIST_FMAXIMUM_MAG_TESTS(bfloat16, LIBC_NAMESPACE::fmaximum_magbf16) diff --git a/libc/test/src/math/smoke/fmaximum_numbf16_test.cpp b/libc/test/src/math/smoke/fmaximum_numbf16_test.cpp new file mode 100644 index 0000000..25dbe9f --- /dev/null +++ b/libc/test/src/math/smoke/fmaximum_numbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for fmaximum_numbf16 ------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FMaximumNumTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fmaximum_numbf16.h" + +LIST_FMAXIMUM_NUM_TESTS(bfloat16, LIBC_NAMESPACE::fmaximum_numbf16) diff --git a/libc/test/src/math/smoke/fmaximumbf16_test.cpp b/libc/test/src/math/smoke/fmaximumbf16_test.cpp new file mode 100644 index 0000000..e2cf56b --- /dev/null +++ b/libc/test/src/math/smoke/fmaximumbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for fmaximumbf16 ----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FMaximumTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fmaximumbf16.h" + +LIST_FMAXIMUM_TESTS(bfloat16, LIBC_NAMESPACE::fmaximumbf16) diff --git a/libc/test/src/math/smoke/fminbf16_test.cpp b/libc/test/src/math/smoke/fminbf16_test.cpp new file mode 100644 index 0000000..195a0ac --- /dev/null +++ b/libc/test/src/math/smoke/fminbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for fminbf16 --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FMinTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fminbf16.h" + +LIST_FMIN_TESTS(bfloat16, LIBC_NAMESPACE::fminbf16) diff --git a/libc/test/src/math/smoke/fminimum_mag_numbf16_test.cpp b/libc/test/src/math/smoke/fminimum_mag_numbf16_test.cpp new file mode 100644 index 0000000..ed3d447 --- /dev/null +++ b/libc/test/src/math/smoke/fminimum_mag_numbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for fminimum_mag_numbf16 --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FMinimumMagNumTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fminimum_mag_numbf16.h" + +LIST_FMINIMUM_MAG_NUM_TESTS(bfloat16, LIBC_NAMESPACE::fminimum_mag_numbf16) diff --git a/libc/test/src/math/smoke/fminimum_magbf16_test.cpp b/libc/test/src/math/smoke/fminimum_magbf16_test.cpp new file mode 100644 index 0000000..94251e0 --- /dev/null +++ b/libc/test/src/math/smoke/fminimum_magbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for fminimum_magbf16 ------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FMinimumMagTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fminimum_magbf16.h" + +LIST_FMINIMUM_MAG_TESTS(bfloat16, LIBC_NAMESPACE::fminimum_magbf16) diff --git a/libc/test/src/math/smoke/fminimum_numbf16_test.cpp b/libc/test/src/math/smoke/fminimum_numbf16_test.cpp new file mode 100644 index 0000000..fe8bb51 --- /dev/null +++ b/libc/test/src/math/smoke/fminimum_numbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for fminimum_numbf16 ------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FMinimumNumTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fminimum_numbf16.h" + +LIST_FMINIMUM_NUM_TESTS(bfloat16, LIBC_NAMESPACE::fminimum_numbf16) diff --git a/libc/test/src/math/smoke/fminimumbf16_test.cpp b/libc/test/src/math/smoke/fminimumbf16_test.cpp new file mode 100644 index 0000000..3667e90 --- /dev/null +++ b/libc/test/src/math/smoke/fminimumbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for fminimumbf16 ----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FMinimumTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fminimumbf16.h" + +LIST_FMINIMUM_TESTS(bfloat16, LIBC_NAMESPACE::fminimumbf16) diff --git a/libc/test/src/math/smoke/fmodbf16_test.cpp b/libc/test/src/math/smoke/fmodbf16_test.cpp new file mode 100644 index 0000000..8f30941 --- /dev/null +++ b/libc/test/src/math/smoke/fmodbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for fmodbf16 --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FModTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fmodbf16.h" + +LIST_FMOD_TESTS(bfloat16, LIBC_NAMESPACE::fmodbf16) diff --git a/libc/test/src/math/smoke/frexpbf16_test.cpp b/libc/test/src/math/smoke/frexpbf16_test.cpp new file mode 100644 index 0000000..3c80edb --- /dev/null +++ b/libc/test/src/math/smoke/frexpbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for frexpbf16 -------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FrexpTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/frexpbf16.h" + +LIST_FREXP_TESTS(bfloat16, LIBC_NAMESPACE::frexpbf16); diff --git a/libc/test/src/math/smoke/fromfpbf16_test.cpp b/libc/test/src/math/smoke/fromfpbf16_test.cpp new file mode 100644 index 0000000..45d70b2 --- /dev/null +++ b/libc/test/src/math/smoke/fromfpbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for fromfpbf16 ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FromfpTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fromfpbf16.h" + +LIST_FROMFP_TESTS(bfloat16, LIBC_NAMESPACE::fromfpbf16) diff --git a/libc/test/src/math/smoke/fromfpxbf16_test.cpp b/libc/test/src/math/smoke/fromfpxbf16_test.cpp new file mode 100644 index 0000000..d930ba3 --- /dev/null +++ b/libc/test/src/math/smoke/fromfpxbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for fromfpxbf16 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "FromfpxTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/fromfpxbf16.h" + +LIST_FROMFPX_TESTS(bfloat16, LIBC_NAMESPACE::fromfpxbf16) diff --git a/libc/test/src/math/smoke/getpayloadbf16_test.cpp b/libc/test/src/math/smoke/getpayloadbf16_test.cpp new file mode 100644 index 0000000..51a5fad --- /dev/null +++ b/libc/test/src/math/smoke/getpayloadbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for getpayloadbf16 --------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "GetPayloadTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/getpayloadbf16.h" + +LIST_GETPAYLOAD_TESTS(bfloat16, LIBC_NAMESPACE::getpayloadbf16) diff --git a/libc/test/src/math/smoke/ilogbbf16_test.cpp b/libc/test/src/math/smoke/ilogbbf16_test.cpp new file mode 100644 index 0000000..d9fa03a --- /dev/null +++ b/libc/test/src/math/smoke/ilogbbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for ilogbbf16 -------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "ILogbTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/ilogbbf16.h" + +LIST_INTLOGB_TESTS(int, bfloat16, LIBC_NAMESPACE::ilogbbf16); diff --git a/libc/test/src/math/smoke/iscanonicalbf16_test.cpp b/libc/test/src/math/smoke/iscanonicalbf16_test.cpp new file mode 100644 index 0000000..3d73588 --- /dev/null +++ b/libc/test/src/math/smoke/iscanonicalbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for iscanonicalbf16 -------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "IsCanonicalTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/iscanonicalbf16.h" + +LIST_ISCANONICAL_TESTS(bfloat16, LIBC_NAMESPACE::iscanonicalbf16) diff --git a/libc/test/src/math/smoke/issignalingbf16_test.cpp b/libc/test/src/math/smoke/issignalingbf16_test.cpp new file mode 100644 index 0000000..ed7e5af --- /dev/null +++ b/libc/test/src/math/smoke/issignalingbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for issignalingbf16 -------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "IsSignalingTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/issignalingbf16.h" + +LIST_ISSIGNALING_TESTS(bfloat16, LIBC_NAMESPACE::issignalingbf16) diff --git a/libc/test/src/math/smoke/ldexpbf16_test.cpp b/libc/test/src/math/smoke/ldexpbf16_test.cpp new file mode 100644 index 0000000..2e57eb8 --- /dev/null +++ b/libc/test/src/math/smoke/ldexpbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for ldexpbf16 -------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "LdExpTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/ldexpbf16.h" + +LIST_LDEXP_TESTS(bfloat16, LIBC_NAMESPACE::ldexpbf16); diff --git a/libc/test/src/math/smoke/llogbbf16_test.cpp b/libc/test/src/math/smoke/llogbbf16_test.cpp new file mode 100644 index 0000000..4454fbf --- /dev/null +++ b/libc/test/src/math/smoke/llogbbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for llogbbf16 -------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "ILogbTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/llogbbf16.h" + +LIST_INTLOGB_TESTS(long, bfloat16, LIBC_NAMESPACE::llogbbf16); diff --git a/libc/test/src/math/smoke/llrintbf16_test.cpp b/libc/test/src/math/smoke/llrintbf16_test.cpp new file mode 100644 index 0000000..e841e62 --- /dev/null +++ b/libc/test/src/math/smoke/llrintbf16_test.cpp @@ -0,0 +1,15 @@ +//===-- Unittests for llrintbf16 ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "RoundToIntegerTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/llrintbf16.h" + +LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(bfloat16, long long, + LIBC_NAMESPACE::llrintbf16) diff --git a/libc/test/src/math/smoke/llroundbf16_test.cpp b/libc/test/src/math/smoke/llroundbf16_test.cpp new file mode 100644 index 0000000..c3b7ea4 --- /dev/null +++ b/libc/test/src/math/smoke/llroundbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for llroundbf16 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "RoundToIntegerTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/llroundbf16.h" + +LIST_ROUND_TO_INTEGER_TESTS(bfloat16, long long, LIBC_NAMESPACE::llroundbf16) diff --git a/libc/test/src/math/smoke/logbbf16_test.cpp b/libc/test/src/math/smoke/logbbf16_test.cpp new file mode 100644 index 0000000..4ceec3d --- /dev/null +++ b/libc/test/src/math/smoke/logbbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for logbbf16 --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "LogbTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/logbbf16.h" + +LIST_LOGB_TESTS(bfloat16, LIBC_NAMESPACE::logbbf16) diff --git a/libc/test/src/math/smoke/lrintbf16_test.cpp b/libc/test/src/math/smoke/lrintbf16_test.cpp new file mode 100644 index 0000000..65a5633b8 --- /dev/null +++ b/libc/test/src/math/smoke/lrintbf16_test.cpp @@ -0,0 +1,15 @@ +//===-- Unittests for lrintbf16 -------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "RoundToIntegerTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/lrintbf16.h" + +LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(bfloat16, long, + LIBC_NAMESPACE::lrintbf16) diff --git a/libc/test/src/math/smoke/lroundbf16_test.cpp b/libc/test/src/math/smoke/lroundbf16_test.cpp new file mode 100644 index 0000000..2f2b7b1 --- /dev/null +++ b/libc/test/src/math/smoke/lroundbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for lroundbf16 ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "RoundToIntegerTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/lroundbf16.h" + +LIST_ROUND_TO_INTEGER_TESTS(bfloat16, long, LIBC_NAMESPACE::lroundbf16) diff --git a/libc/test/src/math/smoke/modfbf16_test.cpp b/libc/test/src/math/smoke/modfbf16_test.cpp new file mode 100644 index 0000000..88ebed5 --- /dev/null +++ b/libc/test/src/math/smoke/modfbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for modfbf16 --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "ModfTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/modfbf16.h" + +LIST_MODF_TESTS(bfloat16, LIBC_NAMESPACE::modfbf16) diff --git a/libc/test/src/math/smoke/nanbf16_test.cpp b/libc/test/src/math/smoke/nanbf16_test.cpp new file mode 100644 index 0000000..4154f6ed --- /dev/null +++ b/libc/test/src/math/smoke/nanbf16_test.cpp @@ -0,0 +1,55 @@ +//===-- Unittests for nanbf16 ---------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "hdr/signal_macros.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/nanbf16.h" +#include "test/UnitTest/FEnvSafeTest.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" + +class LlvmLibcNanf16Test : public LIBC_NAMESPACE::testing::FEnvSafeTest { +public: + using StorageType = LIBC_NAMESPACE::fputil::FPBits<bfloat16>::StorageType; + + void run_test(const char *input_str, StorageType bits) { + bfloat16 result = LIBC_NAMESPACE::nanbf16(input_str); + auto actual_fp = LIBC_NAMESPACE::fputil::FPBits<bfloat16>(result); + auto expected_fp = LIBC_NAMESPACE::fputil::FPBits<bfloat16>(bits); + EXPECT_EQ(actual_fp.uintval(), expected_fp.uintval()); + } +}; + +TEST_F(LlvmLibcNanf16Test, NCharSeq) { + run_test("", 0x7fc0); + + // 0x7fc0 + 0x1f (31) = 0x7cdf + run_test("31", 0x7fdf); + + // 0x7fc0 + 0x15 = 0x7fd5 + run_test("0x15", 0x7fd5); + + run_test("1a", 0x7fc0); + run_test("1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_", + 0x7fc0); + run_test("10000000000000000000000000000", 0x7fc0); +} + +TEST_F(LlvmLibcNanf16Test, RandomString) { + run_test(" 1234", 0x7fc0); + run_test("-1234", 0x7fc0); + run_test("asd&f", 0x7fc0); + run_test("123 ", 0x7fc0); +} + +#if defined(LIBC_ADD_NULL_CHECKS) +TEST_F(LlvmLibcNanf16Test, InvalidInput) { + EXPECT_DEATH([] { LIBC_NAMESPACE::nanbf16(nullptr); }, WITH_SIGNAL(-1)); +} +#endif // LIBC_ADD_NULL_CHECKS diff --git a/libc/test/src/math/smoke/nearbyintbf16_test.cpp b/libc/test/src/math/smoke/nearbyintbf16_test.cpp new file mode 100644 index 0000000..2d64fc5 --- /dev/null +++ b/libc/test/src/math/smoke/nearbyintbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for nearbyintbf16 ---------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "NearbyIntTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/nearbyintbf16.h" + +LIST_NEARBYINT_TESTS(bfloat16, LIBC_NAMESPACE::nearbyintbf16) diff --git a/libc/test/src/math/smoke/nextafterbf16_test.cpp b/libc/test/src/math/smoke/nextafterbf16_test.cpp new file mode 100644 index 0000000..b73a3cb --- /dev/null +++ b/libc/test/src/math/smoke/nextafterbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for nextafterbf16 ---------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "NextAfterTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/nextafterbf16.h" + +LIST_NEXTAFTER_TESTS(bfloat16, LIBC_NAMESPACE::nextafterbf16) diff --git a/libc/test/src/math/smoke/nextdownbf16_test.cpp b/libc/test/src/math/smoke/nextdownbf16_test.cpp new file mode 100644 index 0000000..3002064 --- /dev/null +++ b/libc/test/src/math/smoke/nextdownbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for nextdownbf16 ----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "NextDownTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/nextdownbf16.h" + +LIST_NEXTDOWN_TESTS(bfloat16, LIBC_NAMESPACE::nextdownbf16) diff --git a/libc/test/src/math/smoke/nexttowardbf16_test.cpp b/libc/test/src/math/smoke/nexttowardbf16_test.cpp new file mode 100644 index 0000000..c1f35fc --- /dev/null +++ b/libc/test/src/math/smoke/nexttowardbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for nexttowardbf16 --------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "NextTowardTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/nexttowardbf16.h" + +LIST_NEXTTOWARD_TESTS(bfloat16, LIBC_NAMESPACE::nexttowardbf16) diff --git a/libc/test/src/math/smoke/nextupbf16_test.cpp b/libc/test/src/math/smoke/nextupbf16_test.cpp new file mode 100644 index 0000000..49ad2f7 --- /dev/null +++ b/libc/test/src/math/smoke/nextupbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for nextupbf16 ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "NextUpTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/nextupbf16.h" + +LIST_NEXTUP_TESTS(bfloat16, LIBC_NAMESPACE::nextupbf16) diff --git a/libc/test/src/math/smoke/remquobf16_test.cpp b/libc/test/src/math/smoke/remquobf16_test.cpp new file mode 100644 index 0000000..3f754bb --- /dev/null +++ b/libc/test/src/math/smoke/remquobf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for remquobf16 ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "RemQuoTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/remquobf16.h" + +LIST_REMQUO_TESTS(bfloat16, LIBC_NAMESPACE::remquobf16) diff --git a/libc/test/src/math/smoke/rintbf16_test.cpp b/libc/test/src/math/smoke/rintbf16_test.cpp new file mode 100644 index 0000000..c78dcf6 --- /dev/null +++ b/libc/test/src/math/smoke/rintbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for rintbf16 --------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "RIntTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/rintbf16.h" + +LIST_RINT_TESTS(bfloat16, LIBC_NAMESPACE::rintbf16) diff --git a/libc/test/src/math/smoke/roundbf16_test.cpp b/libc/test/src/math/smoke/roundbf16_test.cpp new file mode 100644 index 0000000..5163868 --- /dev/null +++ b/libc/test/src/math/smoke/roundbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for roundbf16 -------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "RoundTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/roundbf16.h" + +LIST_ROUND_TESTS(bfloat16, LIBC_NAMESPACE::roundbf16) diff --git a/libc/test/src/math/smoke/roundevenbf16_test.cpp b/libc/test/src/math/smoke/roundevenbf16_test.cpp new file mode 100644 index 0000000..711c37a --- /dev/null +++ b/libc/test/src/math/smoke/roundevenbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for roundevenbf16 ---------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "RoundEvenTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/roundevenbf16.h" + +LIST_ROUNDEVEN_TESTS(bfloat16, LIBC_NAMESPACE::roundevenbf16) diff --git a/libc/test/src/math/smoke/scalblnbf16_test.cpp b/libc/test/src/math/smoke/scalblnbf16_test.cpp new file mode 100644 index 0000000..c6fc3aa --- /dev/null +++ b/libc/test/src/math/smoke/scalblnbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for scalblnbf16 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "ScalbnTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/scalblnbf16.h" + +LIST_SCALBN_TESTS(bfloat16, long, LIBC_NAMESPACE::scalblnbf16) diff --git a/libc/test/src/math/smoke/scalbnbf16_test.cpp b/libc/test/src/math/smoke/scalbnbf16_test.cpp new file mode 100644 index 0000000..855fd75 --- /dev/null +++ b/libc/test/src/math/smoke/scalbnbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for scalbnbf16 ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "ScalbnTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/scalbnbf16.h" + +LIST_SCALBN_TESTS(bfloat16, int, LIBC_NAMESPACE::scalbnbf16) diff --git a/libc/test/src/math/smoke/setpayloadbf16_test.cpp b/libc/test/src/math/smoke/setpayloadbf16_test.cpp new file mode 100644 index 0000000..198b454 --- /dev/null +++ b/libc/test/src/math/smoke/setpayloadbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for setpayloadbf16 --------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "SetPayloadTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/setpayloadbf16.h" + +LIST_SETPAYLOAD_TESTS(bfloat16, LIBC_NAMESPACE::setpayloadbf16) diff --git a/libc/test/src/math/smoke/setpayloadsigbf16_test.cpp b/libc/test/src/math/smoke/setpayloadsigbf16_test.cpp new file mode 100644 index 0000000..aa6a3e9 --- /dev/null +++ b/libc/test/src/math/smoke/setpayloadsigbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for setpayloadsigbf16 -----------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "SetPayloadSigTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/setpayloadsigbf16.h" + +LIST_SETPAYLOADSIG_TESTS(bfloat16, LIBC_NAMESPACE::setpayloadsigbf16) diff --git a/libc/test/src/math/smoke/totalorderbf16_test.cpp b/libc/test/src/math/smoke/totalorderbf16_test.cpp new file mode 100644 index 0000000..11aeeac --- /dev/null +++ b/libc/test/src/math/smoke/totalorderbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for totalorderbf16 --------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "TotalOrderTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/totalorderbf16.h" + +LIST_TOTALORDER_TESTS(bfloat16, LIBC_NAMESPACE::totalorderbf16) diff --git a/libc/test/src/math/smoke/totalordermagbf16_test.cpp b/libc/test/src/math/smoke/totalordermagbf16_test.cpp new file mode 100644 index 0000000..b5a5a1b --- /dev/null +++ b/libc/test/src/math/smoke/totalordermagbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for totalordermagbf16 -----------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "TotalOrderMagTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/totalordermagbf16.h" + +LIST_TOTALORDERMAG_TESTS(bfloat16, LIBC_NAMESPACE::totalordermagbf16) diff --git a/libc/test/src/math/smoke/truncbf16_test.cpp b/libc/test/src/math/smoke/truncbf16_test.cpp new file mode 100644 index 0000000..970fa69 --- /dev/null +++ b/libc/test/src/math/smoke/truncbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for truncbf16 -------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "TruncTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/truncbf16.h" + +LIST_TRUNC_TESTS(bfloat16, LIBC_NAMESPACE::truncbf16) diff --git a/libc/test/src/math/smoke/ufromfpbf16_test.cpp b/libc/test/src/math/smoke/ufromfpbf16_test.cpp new file mode 100644 index 0000000..2c516b0 --- /dev/null +++ b/libc/test/src/math/smoke/ufromfpbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for ufromfpbf16 -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "UfromfpTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/ufromfpbf16.h" + +LIST_UFROMFP_TESTS(bfloat16, LIBC_NAMESPACE::ufromfpbf16) diff --git a/libc/test/src/math/smoke/ufromfpxbf16_test.cpp b/libc/test/src/math/smoke/ufromfpxbf16_test.cpp new file mode 100644 index 0000000..56e2727 --- /dev/null +++ b/libc/test/src/math/smoke/ufromfpxbf16_test.cpp @@ -0,0 +1,14 @@ +//===-- Unittests for ufromfpxbf16 ----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "UfromfpxTest.h" + +#include "src/__support/FPUtil/bfloat16.h" +#include "src/math/ufromfpxbf16.h" + +LIST_UFROMFPX_TESTS(bfloat16, LIBC_NAMESPACE::ufromfpxbf16) diff --git a/libc/test/src/stdfix/BitsFxTest.h b/libc/test/src/stdfix/BitsFxTest.h index eca6ab1..cdb363f 100644 --- a/libc/test/src/stdfix/BitsFxTest.h +++ b/libc/test/src/stdfix/BitsFxTest.h @@ -54,7 +54,7 @@ public: if (max >= 11 && FXRep::FRACTION_LEN >= kMinFbits) { // (10.71875)_10 = (1010.1011100)_2 - constexpr long long kExpected = 1372; + constexpr int64_t kExpected = 1372; EXPECT_EQ( static_cast<XType>(kExpected << (FXRep::FRACTION_LEN - kMinFbits)), func(special_num_t)); @@ -63,9 +63,11 @@ public: if constexpr (FXRep::SIGN_LEN > 0) { if (min <= -11 && FXRep::FRACTION_LEN >= kMinFbits) { // (-10.71875)_10 = (-1010.1011100)_2 - constexpr long long kExpected = -1372; - EXPECT_EQ(static_cast<XType>(kExpected - << (FXRep::FRACTION_LEN - kMinFbits)), + constexpr int64_t kExpected = + static_cast<int64_t>(static_cast<uint64_t>(-1372) + << (FXRep::FRACTION_LEN - kMinFbits)); + + EXPECT_EQ(static_cast<XType>(kExpected), func(negative_special_num_t)); } } diff --git a/libc/test/src/string/strcspn_test.cpp b/libc/test/src/string/strcspn_test.cpp index d83b3cf..ec98f72 100644 --- a/libc/test/src/string/strcspn_test.cpp +++ b/libc/test/src/string/strcspn_test.cpp @@ -48,3 +48,7 @@ TEST(LlvmLibcStrCSpnTest, DuplicatedCharactersNotPartOfComplementarySpan) { EXPECT_EQ(LIBC_NAMESPACE::strcspn("aaaa", "aa"), size_t{0}); EXPECT_EQ(LIBC_NAMESPACE::strcspn("aaaa", "baa"), size_t{0}); } + +TEST(LlvmLibcStrCSpnTest, TopBitSet) { + EXPECT_EQ(LIBC_NAMESPACE::strcspn("hello\x80world", "\x80"), size_t{5}); +} diff --git a/libc/test/src/string/strpbrk_test.cpp b/libc/test/src/string/strpbrk_test.cpp index fbe14da..cc80246 100644 --- a/libc/test/src/string/strpbrk_test.cpp +++ b/libc/test/src/string/strpbrk_test.cpp @@ -60,3 +60,7 @@ TEST(LlvmLibcStrPBrkTest, FindsFirstOfRepeated) { TEST(LlvmLibcStrPBrkTest, FindsFirstInBreakset) { EXPECT_STREQ(LIBC_NAMESPACE::strpbrk("12345", "34"), "345"); } + +TEST(LlvmLibcStrPBrkTest, TopBitSet) { + EXPECT_STREQ(LIBC_NAMESPACE::strpbrk("hello\x80world", "\x80 "), "\x80world"); +} diff --git a/libc/test/src/string/strsep_test.cpp b/libc/test/src/string/strsep_test.cpp index 06318de..553edd9 100644 --- a/libc/test/src/string/strsep_test.cpp +++ b/libc/test/src/string/strsep_test.cpp @@ -18,21 +18,21 @@ TEST(LlvmLibcStrsepTest, NullSrc) { TEST(LlvmLibcStrsepTest, NoTokenFound) { { char s[] = ""; - char *string = s, *orig = s; + char *string = s; EXPECT_STREQ(LIBC_NAMESPACE::strsep(&string, ""), nullptr); - EXPECT_EQ(orig, string); + EXPECT_TRUE(string == nullptr); } { char s[] = "abcde"; char *string = s, *orig = s; EXPECT_STREQ(LIBC_NAMESPACE::strsep(&string, ""), orig); - EXPECT_EQ(string, orig + 5); + EXPECT_TRUE(string == nullptr); } { char s[] = "abcde"; char *string = s, *orig = s; EXPECT_STREQ(LIBC_NAMESPACE::strsep(&string, "fghijk"), orig); - EXPECT_EQ(string, orig + 5); + EXPECT_TRUE(string == nullptr); } } @@ -53,6 +53,22 @@ TEST(LlvmLibcStrsepTest, DelimitersShouldNotBeIncludedInToken) { } } +TEST(LlvmLibcStrsepTest, SubsequentSearchesReturnNull) { + char s[] = "a"; + char *string = s; + ASSERT_STREQ(LIBC_NAMESPACE::strsep(&string, ":"), "a"); + ASSERT_EQ(LIBC_NAMESPACE::strsep(&string, ":"), nullptr); + ASSERT_EQ(LIBC_NAMESPACE::strsep(&string, ":"), nullptr); +} + +TEST(LlvmLibcStrsepTest, TopBitSet) { + char top_bit_set_str[] = "hello\x80world"; + char *p = top_bit_set_str; + ASSERT_STREQ(LIBC_NAMESPACE::strsep(&p, "\x80"), "hello"); + ASSERT_STREQ(LIBC_NAMESPACE::strsep(&p, "\x80"), "world"); + ASSERT_EQ(LIBC_NAMESPACE::strsep(&p, "\x80"), nullptr); +} + #if defined(LIBC_ADD_NULL_CHECKS) TEST(LlvmLibcStrsepTest, CrashOnNullPtr) { diff --git a/libc/test/src/string/strspn_test.cpp b/libc/test/src/string/strspn_test.cpp index 82f9b2a..813612f 100644 --- a/libc/test/src/string/strspn_test.cpp +++ b/libc/test/src/string/strspn_test.cpp @@ -85,6 +85,10 @@ TEST(LlvmLibcStrSpnTest, DuplicatedCharactersToBeSearchedForShouldStillMatch) { EXPECT_EQ(LIBC_NAMESPACE::strspn("aaaa", "aa"), size_t{4}); } +TEST(LlvmLibcStrSpnTest, TopBitSet) { + EXPECT_EQ(LIBC_NAMESPACE::strspn("hello\x80world", "helo\x80rld"), size_t{6}); +} + #if defined(LIBC_ADD_NULL_CHECKS) TEST(LlvmLibcStrSpnTest, CrashOnNullPtr) { diff --git a/libc/test/src/string/strtok_r_test.cpp b/libc/test/src/string/strtok_r_test.cpp index fdc27ba..8c4d3c36 100644 --- a/libc/test/src/string/strtok_r_test.cpp +++ b/libc/test/src/string/strtok_r_test.cpp @@ -122,3 +122,20 @@ TEST(LlvmLibcStrTokReentrantTest, DelimitersShouldNotBeIncludedInToken) { token = LIBC_NAMESPACE::strtok_r(nullptr, "_:,_", &reserve); ASSERT_STREQ(token, nullptr); } + +TEST(LlvmLibcStrTokReentrantTest, SubsequentSearchesReturnNull) { + char src[] = "a"; + char *reserve = nullptr; + char *token = LIBC_NAMESPACE::strtok_r(src, ":", &reserve); + ASSERT_STREQ(token, "a"); + ASSERT_EQ(LIBC_NAMESPACE::strtok_r(nullptr, ":", &reserve), nullptr); + ASSERT_EQ(LIBC_NAMESPACE::strtok_r(nullptr, ":", &reserve), nullptr); +} + +TEST(LlvmLibcStrTokReentrantTest, TopBitSet) { + char top_bit_set_str[] = "hello\x80world"; + char *p; + ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(top_bit_set_str, "\x80", &p), "hello"); + ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(nullptr, "\x80", &p), "world"); + ASSERT_EQ(LIBC_NAMESPACE::strtok_r(nullptr, "\x80", &p), nullptr); +} diff --git a/libc/test/src/string/strtok_test.cpp b/libc/test/src/string/strtok_test.cpp index b820653..3c097fde 100644 --- a/libc/test/src/string/strtok_test.cpp +++ b/libc/test/src/string/strtok_test.cpp @@ -76,3 +76,17 @@ TEST(LlvmLibcStrTokTest, DelimitersShouldNotBeIncludedInToken) { token = LIBC_NAMESPACE::strtok(nullptr, "_:,_"); ASSERT_STREQ(token, nullptr); } + +TEST(LlvmLibcStrTokTest, SubsequentSearchesReturnNull) { + char src[] = "a"; + ASSERT_STREQ("a", LIBC_NAMESPACE::strtok(src, ":")); + ASSERT_EQ(LIBC_NAMESPACE::strtok(nullptr, ":"), nullptr); + ASSERT_EQ(LIBC_NAMESPACE::strtok(nullptr, ":"), nullptr); +} + +TEST(LlvmLibcStrTokTest, TopBitSet) { + char top_bit_set_str[] = "hello\x80world"; + ASSERT_STREQ(LIBC_NAMESPACE::strtok(top_bit_set_str, "\x80"), "hello"); + ASSERT_STREQ(LIBC_NAMESPACE::strtok(nullptr, "\x80"), "world"); + ASSERT_EQ(LIBC_NAMESPACE::strtok(nullptr, "\x80"), nullptr); +} diff --git a/libc/test/src/sys/random/linux/getrandom_test.cpp b/libc/test/src/sys/random/linux/getrandom_test.cpp index 70ecfbf..249942d 100644 --- a/libc/test/src/sys/random/linux/getrandom_test.cpp +++ b/libc/test/src/sys/random/linux/getrandom_test.cpp @@ -19,11 +19,12 @@ using LlvmLibcGetRandomTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest; TEST_F(LlvmLibcGetRandomTest, InvalidFlag) { LIBC_NAMESPACE::cpp::array<char, 10> buffer; ASSERT_THAT(LIBC_NAMESPACE::getrandom(buffer.data(), buffer.size(), -1), - Fails(EINVAL)); + Fails<ssize_t>(EINVAL)); } TEST_F(LlvmLibcGetRandomTest, InvalidBuffer) { - ASSERT_THAT(LIBC_NAMESPACE::getrandom(nullptr, 65536, 0), Fails(EFAULT)); + ASSERT_THAT(LIBC_NAMESPACE::getrandom(nullptr, 65536, 0), + Fails<ssize_t>(EFAULT)); } TEST_F(LlvmLibcGetRandomTest, ReturnsSize) { diff --git a/libc/test/src/time/timespec_get_test.cpp b/libc/test/src/time/timespec_get_test.cpp index 327bfef..9758501 100644 --- a/libc/test/src/time/timespec_get_test.cpp +++ b/libc/test/src/time/timespec_get_test.cpp @@ -24,6 +24,8 @@ TEST(LlvmLibcTimespecGet, Utc) { #endif } +// Baremetal implementation currently only supports TIME_UTC +#ifndef LIBC_TARGET_OS_IS_BAREMETAL TEST(LlvmLibcTimespecGet, Monotonic) { timespec ts1, ts2; int result; @@ -37,6 +39,7 @@ TEST(LlvmLibcTimespecGet, Monotonic) { ASSERT_GE(ts2.tv_nsec, ts1.tv_nsec); } } +#endif TEST(LlvmLibcTimespecGet, Unknown) { timespec ts; diff --git a/libc/test/src/wchar/mbrtowc_test.cpp b/libc/test/src/wchar/mbrtowc_test.cpp index c406300..ddf8fc7 100644 --- a/libc/test/src/wchar/mbrtowc_test.cpp +++ b/libc/test/src/wchar/mbrtowc_test.cpp @@ -37,18 +37,18 @@ TEST_F(LlvmLibcMBRToWCTest, TwoByte) { const char ch[2] = {static_cast<char>(0xC2), static_cast<char>(0x8E)}; // car symbol wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, &mb); ASSERT_EQ(static_cast<int>(*dest), 142); ASSERT_EQ(static_cast<int>(n), 2); ASSERT_ERRNO_SUCCESS(); // Should fail since we have not read enough - n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &mb); ASSERT_EQ(static_cast<int>(n), -2); // Should pass after reading one more byte - n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 1, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 1, &mb); ASSERT_EQ(static_cast<int>(n), 1); ASSERT_EQ(static_cast<int>(*dest), 142); ASSERT_ERRNO_SUCCESS(); @@ -58,19 +58,19 @@ TEST_F(LlvmLibcMBRToWCTest, ThreeByte) { const char ch[3] = {static_cast<char>(0xE2), static_cast<char>(0x88), static_cast<char>(0x91)}; // ∑ sigma symbol wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 3, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 3, &mb); ASSERT_EQ(static_cast<int>(*dest), 8721); ASSERT_EQ(static_cast<int>(n), 3); ASSERT_ERRNO_SUCCESS(); // Should fail since we have not read enough - n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &mb); ASSERT_EQ(static_cast<int>(n), -2); ASSERT_ERRNO_SUCCESS(); // Should pass after reading two more bytes - n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 2, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 2, &mb); ASSERT_EQ(static_cast<int>(n), 2); ASSERT_EQ(static_cast<int>(*dest), 8721); ASSERT_ERRNO_SUCCESS(); @@ -81,18 +81,18 @@ TEST_F(LlvmLibcMBRToWCTest, FourByte) { static_cast<char>(0xA4), static_cast<char>(0xA1)}; // 🤡 clown emoji wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, &mb); ASSERT_EQ(static_cast<int>(*dest), 129313); ASSERT_EQ(static_cast<int>(n), 4); ASSERT_ERRNO_SUCCESS(); // Should fail since we have not read enough - n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, &mb); ASSERT_EQ(static_cast<int>(n), -2); ASSERT_ERRNO_SUCCESS(); // Should pass after reading two more bytes - n = LIBC_NAMESPACE::mbrtowc(dest, ch + 2, 2, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch + 2, 2, &mb); ASSERT_EQ(static_cast<int>(n), 2); ASSERT_EQ(static_cast<int>(*dest), 129313); ASSERT_ERRNO_SUCCESS(); @@ -101,9 +101,9 @@ TEST_F(LlvmLibcMBRToWCTest, FourByte) { TEST_F(LlvmLibcMBRToWCTest, InvalidByte) { const char ch[1] = {static_cast<char>(0x80)}; wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &mb); ASSERT_EQ(static_cast<int>(n), -1); ASSERT_ERRNO_EQ(EILSEQ); } @@ -113,18 +113,18 @@ TEST_F(LlvmLibcMBRToWCTest, InvalidMultiByte) { static_cast<char>(0x80), static_cast<char>(0x00)}; // invalid sequence of bytes wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); // Trying to push all 4 should error - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, &mb); ASSERT_EQ(static_cast<int>(n), -1); ASSERT_ERRNO_EQ(EILSEQ); // Trying to push just the first one should error - n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &mb); ASSERT_EQ(static_cast<int>(n), -1); ASSERT_ERRNO_EQ(EILSEQ); // Trying to push the second and third should correspond to null wc - n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 2, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 2, &mb); ASSERT_EQ(static_cast<int>(n), 0); ASSERT_TRUE(*dest == L'\0'); ASSERT_ERRNO_SUCCESS(); @@ -136,10 +136,10 @@ TEST_F(LlvmLibcMBRToWCTest, InvalidLastByte) { const char ch[4] = {static_cast<char>(0xF1), static_cast<char>(0x80), static_cast<char>(0x80), static_cast<char>(0xC0)}; wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); // Trying to push all 4 should error - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, &mb); ASSERT_EQ(static_cast<int>(n), -1); ASSERT_ERRNO_EQ(EILSEQ); } @@ -148,10 +148,10 @@ TEST_F(LlvmLibcMBRToWCTest, ValidTwoByteWithExtraRead) { const char ch[3] = {static_cast<char>(0xC2), static_cast<char>(0x8E), static_cast<char>(0x80)}; wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); // Trying to push all 3 should return valid 2 byte - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 3, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 3, &mb); ASSERT_EQ(static_cast<int>(n), 2); ASSERT_EQ(static_cast<int>(*dest), 142); ASSERT_ERRNO_SUCCESS(); @@ -161,14 +161,14 @@ TEST_F(LlvmLibcMBRToWCTest, TwoValidTwoBytes) { const char ch[4] = {static_cast<char>(0xC2), static_cast<char>(0x8E), static_cast<char>(0xC7), static_cast<char>(0x8C)}; wchar_t dest[2]; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); // mbstate should reset after reading first one - size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, &mb); ASSERT_EQ(static_cast<int>(n), 2); ASSERT_EQ(static_cast<int>(*dest), 142); ASSERT_ERRNO_SUCCESS(); - n = LIBC_NAMESPACE::mbrtowc(dest + 1, ch + 2, 2, mb); + n = LIBC_NAMESPACE::mbrtowc(dest + 1, ch + 2, 2, &mb); ASSERT_EQ(static_cast<int>(n), 2); ASSERT_EQ(static_cast<int>(*(dest + 1)), 460); ASSERT_ERRNO_SUCCESS(); @@ -176,16 +176,16 @@ TEST_F(LlvmLibcMBRToWCTest, TwoValidTwoBytes) { TEST_F(LlvmLibcMBRToWCTest, NullString) { wchar_t dest[2] = {L'O', L'K'}; - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); // reading on nullptr should return 0 - size_t n = LIBC_NAMESPACE::mbrtowc(dest, nullptr, 2, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(dest, nullptr, 2, &mb); ASSERT_EQ(static_cast<int>(n), 0); ASSERT_TRUE(dest[0] == L'O'); ASSERT_ERRNO_SUCCESS(); // reading a null terminator should return 0 const char *ch = "\0"; - n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb); + n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &mb); ASSERT_EQ(static_cast<int>(n), 0); ASSERT_ERRNO_SUCCESS(); } @@ -194,10 +194,10 @@ TEST_F(LlvmLibcMBRToWCTest, NullDest) { const char ch[4] = {static_cast<char>(0xF0), static_cast<char>(0x9F), static_cast<char>(0xA4), static_cast<char>(0xA1)}; // 🤡 clown emoji - mbstate_t *mb; + mbstate_t mb; LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t)); // reading nullptr should return correct size - size_t n = LIBC_NAMESPACE::mbrtowc(nullptr, ch, 10, mb); + size_t n = LIBC_NAMESPACE::mbrtowc(nullptr, ch, 10, &mb); ASSERT_EQ(static_cast<int>(n), 4); ASSERT_ERRNO_SUCCESS(); } diff --git a/libc/test/src/wctype/iswalpha_test.cpp b/libc/test/src/wctype/iswalpha_test.cpp index f3f75f4..a82c005 100644 --- a/libc/test/src/wctype/iswalpha_test.cpp +++ b/libc/test/src/wctype/iswalpha_test.cpp @@ -9,46 +9,48 @@ #include "src/__support/CPP/span.h" #include "src/wctype/iswalpha.h" -#include "test/UnitTest/LibcTest.h" #include "test/UnitTest/Test.h" -namespace { - -// TODO: Merge the wctype tests using this framework. -constexpr char WALPHA_ARRAY[] = { - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', -}; - -bool in_span(int ch, LIBC_NAMESPACE::cpp::span<const char> arr) { - for (size_t i = 0; i < arr.size(); ++i) - if (static_cast<int>(arr[i]) == ch) - return true; - return false; -} - -} // namespace - TEST(LlvmLibciswalpha, SimpleTest) { - EXPECT_TRUE(LIBC_NAMESPACE::iswalpha('a')); - EXPECT_TRUE(LIBC_NAMESPACE::iswalpha('B')); - - EXPECT_FALSE(LIBC_NAMESPACE::iswalpha('3')); - EXPECT_FALSE(LIBC_NAMESPACE::iswalpha(' ')); - EXPECT_FALSE(LIBC_NAMESPACE::iswalpha('?')); - EXPECT_FALSE(LIBC_NAMESPACE::iswalpha('\0')); - EXPECT_FALSE(LIBC_NAMESPACE::iswalpha(-1)); + EXPECT_NE(LIBC_NAMESPACE::iswalpha('a'), 0); + EXPECT_NE(LIBC_NAMESPACE::iswalpha('B'), 0); + + EXPECT_EQ(LIBC_NAMESPACE::iswalpha('3'), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswalpha(' '), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswalpha('?'), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswalpha('\0'), 0); + EXPECT_EQ(LIBC_NAMESPACE::iswalpha(-1), 0); } -TEST(LlvmLibciswalpha, DefaultLocale) { - // Loops through all characters, verifying that letters return - // true and everything else returns false. - for (int ch = -255; ch < 255; ++ch) { - if (in_span(ch, WALPHA_ARRAY)) - EXPECT_TRUE(LIBC_NAMESPACE::iswalpha(ch)); - else - EXPECT_FALSE(LIBC_NAMESPACE::iswalpha(ch)); - } -} +// TODO: once iswalpha supports more than just ascii-range characters add a +// proper test. + +// namespace { + +// // TODO: Merge the wctype tests using this framework. +// constexpr char WALPHA_ARRAY[] = { +// 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', +// 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', +// 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', +// 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', +// }; + +// bool in_span(int ch, LIBC_NAMESPACE::cpp::span<const char> arr) { +// for (size_t i = 0; i < arr.size(); ++i) +// if (static_cast<int>(arr[i]) == ch) +// return true; +// return false; +// } + +// } // namespace + +// TEST(LlvmLibciswalpha, DefaultLocale) { +// // Loops through all characters, verifying that letters return +// // true and everything else returns false. +// for (int ch = -255; ch < 255; ++ch) { +// if (in_span(ch, WALPHA_ARRAY)) +// EXPECT_TRUE(LIBC_NAMESPACE::iswalpha(ch)); +// else +// EXPECT_FALSE(LIBC_NAMESPACE::iswalpha(ch)); +// } +// } diff --git a/libc/utils/MPFRWrapper/CMakeLists.txt b/libc/utils/MPFRWrapper/CMakeLists.txt index 2669b23..73151c6 100644 --- a/libc/utils/MPFRWrapper/CMakeLists.txt +++ b/libc/utils/MPFRWrapper/CMakeLists.txt @@ -43,6 +43,7 @@ if(LIBC_TESTS_CAN_USE_MPFR) libc.hdr.stdint_proxy libc.src.__support.CPP.array libc.src.__support.CPP.stringstream + libc.src.__support.FPUtil.bfloat16 libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.fpbits_str LibcTest.unit diff --git a/libc/utils/MPFRWrapper/MPCommon.cpp b/libc/utils/MPFRWrapper/MPCommon.cpp index 07339a0..c255220 100644 --- a/libc/utils/MPFRWrapper/MPCommon.cpp +++ b/libc/utils/MPFRWrapper/MPCommon.cpp @@ -105,6 +105,21 @@ MPFRNumber MPFRNumber::asinh() const { return result; } +MPFRNumber MPFRNumber::asinpi() const { + MPFRNumber result(*this); +#if MPFR_VERSION >= MPFR_VERSION_NUM(4, 2, 0) + mpfr_asinpi(result.value, value, mpfr_rounding); + return result; +#else + MPFRNumber value_asin(0.0, 1280); + mpfr_asin(value_asin.value, value, MPFR_RNDN); + MPFRNumber value_pi(0.0, 1280); + mpfr_const_pi(value_pi.value, MPFR_RNDN); + mpfr_div(result.value, value_asin.value, value_pi.value, mpfr_rounding); + return result; +#endif +} + MPFRNumber MPFRNumber::atan() const { MPFRNumber result(*this); mpfr_atan(result.value, value, mpfr_rounding); @@ -123,6 +138,21 @@ MPFRNumber MPFRNumber::atanh() const { return result; } +MPFRNumber MPFRNumber::atanpi() const { + MPFRNumber result(*this); +#if MPFR_VERSION >= MPFR_VERSION_NUM(4, 2, 0) + mpfr_atanpi(result.value, value, mpfr_rounding); + return result; +#else + MPFRNumber value_atan(0.0, mpfr_precision * 3); + mpfr_atan(value_atan.value, value, MPFR_RNDN); + MPFRNumber value_pi(0.0, mpfr_precision * 3); + mpfr_const_pi(value_pi.value, MPFR_RNDN); + mpfr_div(result.value, value_atan.value, value_pi.value, mpfr_rounding); + return result; +#endif +} + MPFRNumber MPFRNumber::cbrt() const { MPFRNumber result(*this); mpfr_cbrt(result.value, value, mpfr_rounding); diff --git a/libc/utils/MPFRWrapper/MPCommon.h b/libc/utils/MPFRWrapper/MPCommon.h index 8bcc69c2..25bdc9b 100644 --- a/libc/utils/MPFRWrapper/MPCommon.h +++ b/libc/utils/MPFRWrapper/MPCommon.h @@ -189,9 +189,11 @@ public: MPFRNumber add(const MPFRNumber &b) const; MPFRNumber asin() const; MPFRNumber asinh() const; + MPFRNumber asinpi() const; MPFRNumber atan() const; MPFRNumber atan2(const MPFRNumber &b); MPFRNumber atanh() const; + MPFRNumber atanpi() const; MPFRNumber cbrt() const; MPFRNumber ceil() const; MPFRNumber cos() const; diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp index 8853f96..ed749f1 100644 --- a/libc/utils/MPFRWrapper/MPFRUtils.cpp +++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp @@ -11,6 +11,7 @@ #include "src/__support/CPP/array.h" #include "src/__support/CPP/stringstream.h" +#include "src/__support/FPUtil/bfloat16.h" #include "src/__support/FPUtil/fpbits_str.h" #include "src/__support/macros/config.h" #include "src/__support/macros/properties/types.h" @@ -38,10 +39,14 @@ unary_operation(Operation op, InputType input, unsigned int precision, return mpfrInput.asin(); case Operation::Asinh: return mpfrInput.asinh(); + case Operation::Asinpi: + return mpfrInput.asinpi(); case Operation::Atan: return mpfrInput.atan(); case Operation::Atanh: return mpfrInput.atanh(); + case Operation::Atanpi: + return mpfrInput.atanpi(); case Operation::Cbrt: return mpfrInput.cbrt(); case Operation::Ceil: @@ -408,6 +413,23 @@ template void explain_binary_operation_one_output_error( template void explain_binary_operation_one_output_error( Operation, const BinaryInput<float128> &, float128, double, RoundingMode); #endif +template void explain_binary_operation_one_output_error( + Operation, const BinaryInput<bfloat16> &, bfloat16, double, RoundingMode); +template void +explain_binary_operation_one_output_error(Operation, const BinaryInput<float> &, + bfloat16, double, RoundingMode); +template void explain_binary_operation_one_output_error( + Operation, const BinaryInput<double> &, bfloat16, double, RoundingMode); +template void +explain_binary_operation_one_output_error(Operation, + const BinaryInput<long double> &, + bfloat16, double, RoundingMode); +#if defined(LIBC_TYPES_HAS_FLOAT128) && \ + defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE) +template void explain_binary_operation_one_output_error( + Operation, const BinaryInput<float128> &, bfloat16, double, RoundingMode); +#endif // defined(LIBC_TYPES_HAS_FLOAT128) && + // defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE) template <typename InputType, typename OutputType> void explain_ternary_operation_one_output_error( @@ -468,6 +490,21 @@ explain_ternary_operation_one_output_error(Operation, float16, double, RoundingMode); #endif +template void explain_ternary_operation_one_output_error( + Operation, const TernaryInput<float> &, bfloat16, double, RoundingMode); +template void explain_ternary_operation_one_output_error( + Operation, const TernaryInput<double> &, bfloat16, double, RoundingMode); +template void +explain_ternary_operation_one_output_error(Operation, + const TernaryInput<long double> &, + bfloat16, double, RoundingMode); +#if defined(LIBC_TYPES_HAS_FLOAT128) && \ + defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE) +template void explain_ternary_operation_one_output_error( + Operation, const TernaryInput<float128> &, bfloat16, double, RoundingMode); +#endif // defined(LIBC_TYPES_HAS_FLOAT128) && + // defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE) + template <typename InputType, typename OutputType> bool compare_unary_operation_single_output(Operation op, InputType input, OutputType libc_result, @@ -641,7 +678,30 @@ template bool compare_binary_operation_one_output(Operation, float128, double, RoundingMode); #endif +template bool compare_binary_operation_one_output(Operation, + const BinaryInput<bfloat16> &, + bfloat16, double, + RoundingMode); +template bool compare_binary_operation_one_output(Operation, + const BinaryInput<float> &, + bfloat16, double, + RoundingMode); +template bool compare_binary_operation_one_output(Operation, + const BinaryInput<double> &, + bfloat16, double, + RoundingMode); +template bool +compare_binary_operation_one_output(Operation, const BinaryInput<long double> &, + bfloat16, double, RoundingMode); +#if defined(LIBC_TYPES_HAS_FLOAT128) && \ + defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE) +template bool compare_binary_operation_one_output(Operation, + const BinaryInput<float128> &, + bfloat16, double, + RoundingMode); +#endif // defined(LIBC_TYPES_HAS_FLOAT128) && + // defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE) template <typename InputType, typename OutputType> bool compare_ternary_operation_one_output(Operation op, const TernaryInput<InputType> &input, @@ -693,6 +753,27 @@ compare_ternary_operation_one_output(Operation, double, RoundingMode); #endif +template bool compare_ternary_operation_one_output(Operation, + const TernaryInput<float> &, + bfloat16, double, + RoundingMode); +template bool compare_ternary_operation_one_output(Operation, + const TernaryInput<double> &, + bfloat16, double, + RoundingMode); +template bool +compare_ternary_operation_one_output(Operation, + const TernaryInput<long double> &, + bfloat16, double, RoundingMode); + +#if defined(LIBC_TYPES_HAS_FLOAT128) && \ + defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE) +template bool +compare_ternary_operation_one_output(Operation, const TernaryInput<float128> &, + bfloat16, double, RoundingMode); +#endif // defined(LIBC_TYPES_HAS_FLOAT128) && + // defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE) + } // namespace internal template <typename T> bool round_to_long(T x, long &result) { @@ -712,6 +793,8 @@ template bool round_to_long<float16>(float16, long &); template bool round_to_long<float128>(float128, long &); #endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +template bool round_to_long<bfloat16>(bfloat16, long &); + template <typename T> bool round_to_long(T x, RoundingMode mode, long &result) { MPFRNumber mpfr(x); return mpfr.round_to_long(get_mpfr_rounding_mode(mode), result); @@ -729,6 +812,8 @@ template bool round_to_long<float16>(float16, RoundingMode, long &); template bool round_to_long<float128>(float128, RoundingMode, long &); #endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +template bool round_to_long<bfloat16>(bfloat16, RoundingMode, long &); + template <typename T> T round(T x, RoundingMode mode) { MPFRNumber mpfr(x); MPFRNumber result = mpfr.rint(get_mpfr_rounding_mode(mode)); @@ -747,6 +832,8 @@ template float16 round<float16>(float16, RoundingMode); template float128 round<float128>(float128, RoundingMode); #endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +template bfloat16 round<bfloat16>(bfloat16, RoundingMode); + } // namespace mpfr } // namespace testing } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/utils/MPFRWrapper/MPFRUtils.h b/libc/utils/MPFRWrapper/MPFRUtils.h index 45468c6..35d7942 100644 --- a/libc/utils/MPFRWrapper/MPFRUtils.h +++ b/libc/utils/MPFRWrapper/MPFRUtils.h @@ -30,8 +30,10 @@ enum class Operation : int { Acospi, Asin, Asinh, + Asinpi, Atan, Atanh, + Atanpi, Cbrt, Ceil, Cos, diff --git a/libc/utils/hdrgen/hdrgen/header.py b/libc/utils/hdrgen/hdrgen/header.py index b054ed4..2118db6 100644 --- a/libc/utils/hdrgen/hdrgen/header.py +++ b/libc/utils/hdrgen/hdrgen/header.py @@ -204,7 +204,7 @@ class HeaderFile: current_guard = None for function in self.functions: - if function.guard == None: + if function.guard == None and current_guard == None: content.append(str(function) + " __NOEXCEPT;") content.append("") else: @@ -221,7 +221,8 @@ class HeaderFile: content.append(f"#endif // {current_guard}") content.append("") current_guard = function.guard - content.append(f"#ifdef {current_guard}") + if current_guard is not None: + content.append(f"#ifdef {current_guard}") content.append(str(function) + " __NOEXCEPT;") content.append("") if current_guard != None: |