summaryrefslogtreecommitdiff
path: root/libc/src
diff options
context:
space:
mode:
Diffstat (limited to 'libc/src')
-rw-r--r--libc/src/__support/FPUtil/CMakeLists.txt27
-rw-r--r--libc/src/__support/FPUtil/ManipulationFunctions.h12
-rw-r--r--libc/src/__support/FPUtil/cast.h65
-rw-r--r--libc/src/__support/FPUtil/dyadic_float.h131
-rw-r--r--libc/src/__support/FPUtil/except_value_utils.h18
-rw-r--r--libc/src/__support/FPUtil/generic/CMakeLists.txt7
-rw-r--r--libc/src/__support/FPUtil/generic/FMA.h5
-rw-r--r--libc/src/__support/FPUtil/generic/add_sub.h5
-rw-r--r--libc/src/__support/FPUtil/generic/sqrt.h3
-rw-r--r--libc/src/math/generic/CMakeLists.txt24
-rw-r--r--libc/src/math/generic/ceilf16.cpp3
-rw-r--r--libc/src/math/generic/exp10f16.cpp11
-rw-r--r--libc/src/math/generic/exp2f16.cpp3
-rw-r--r--libc/src/math/generic/expf16.cpp5
-rw-r--r--libc/src/math/generic/expm1f16.cpp7
-rw-r--r--libc/src/math/generic/floorf16.cpp3
-rw-r--r--libc/src/math/generic/rintf16.cpp3
-rw-r--r--libc/src/math/generic/roundevenf16.cpp3
-rw-r--r--libc/src/math/generic/roundf16.cpp3
-rw-r--r--libc/src/math/generic/truncf16.cpp3
-rw-r--r--libc/src/stdlib/CMakeLists.txt7
-rw-r--r--libc/src/stdlib/gpu/CMakeLists.txt13
-rw-r--r--libc/src/stdlib/gpu/system.cpp29
-rw-r--r--libc/src/stdlib/system.h20
24 files changed, 368 insertions, 42 deletions
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index ea1e0e8b39d1..522b4afefd48 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -92,11 +92,14 @@ add_header_library(
HDRS
except_value_utils.h
DEPENDS
+ .cast
.fp_bits
.fenv_impl
.rounding_mode
libc.src.__support.CPP.optional
libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.macros.properties.types
)
@@ -175,9 +178,13 @@ add_header_library(
.fenv_impl
.fp_bits
.multiply_add
+ .rounding_mode
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
libc.src.__support.CPP.type_traits
libc.src.__support.big_int
libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.types
)
add_header_library(
@@ -217,18 +224,32 @@ add_header_library(
HDRS
ManipulationFunctions.h
DEPENDS
+ .cast
+ .dyadic_float
.fenv_impl
.fp_bits
- .dyadic_float
.nearest_integer_operations
.normal_float
libc.hdr.math_macros
+ libc.src.errno.errno
+ libc.src.__support.common
libc.src.__support.CPP.bit
libc.src.__support.CPP.limits
libc.src.__support.CPP.type_traits
- libc.src.__support.common
libc.src.__support.macros.optimization
- libc.src.errno.errno
+)
+
+add_header_library(
+ cast
+ HDRS
+ cast.h
+ DEPENDS
+ .dyadic_float
+ .fp_bits
+ libc.hdr.fenv_macros
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.CPP.type_traits
+ libc.src.__support.macros.properties.types
)
add_subdirectory(generic)
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index a14f35578999..66bfe2aa377f 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -12,6 +12,7 @@
#include "FPBits.h"
#include "NearestIntegerOperations.h"
#include "NormalFloat.h"
+#include "cast.h"
#include "dyadic_float.h"
#include "rounding_mode.h"
@@ -192,7 +193,8 @@ ldexp(T x, U exp) {
// For all other values, NormalFloat to T conversion handles it the right way.
DyadicFloat<FPBits<T>::STORAGE_LEN> normal(bits.get_val());
normal.exponent += static_cast<int>(exp);
- return static_cast<T>(normal);
+ // TODO: Add tests for exceptions.
+ return normal.template as<T, /*ShouldRaiseExceptions=*/true>();
}
template <typename T, typename U,
@@ -207,17 +209,17 @@ LIBC_INLINE T nextafter(T from, U to) {
FPBits<U> to_bits(to);
if (to_bits.is_nan())
- return static_cast<T>(to);
+ return cast<T>(to);
// NOTE: This would work only if `U` has a greater or equal precision than
// `T`. Otherwise `from` could loose its precision and the following statement
// could incorrectly evaluate to `true`.
- if (static_cast<U>(from) == to)
- return static_cast<T>(to);
+ if (cast<U>(from) == to)
+ return cast<T>(to);
using StorageType = typename FPBits<T>::StorageType;
if (from != T(0)) {
- if ((static_cast<U>(from) < to) == (from > T(0))) {
+ if ((cast<U>(from) < to) == (from > T(0))) {
from_bits = FPBits<T>(StorageType(from_bits.uintval() + 1));
} else {
from_bits = FPBits<T>(StorageType(from_bits.uintval() - 1));
diff --git a/libc/src/__support/FPUtil/cast.h b/libc/src/__support/FPUtil/cast.h
new file mode 100644
index 000000000000..126f3852137b
--- /dev/null
+++ b/libc/src/__support/FPUtil/cast.h
@@ -0,0 +1,65 @@
+//===-- Conversion between floating-point types -----------------*- 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_FPUTIL_CAST_H
+#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_CAST_H
+
+#include "FPBits.h"
+#include "dyadic_float.h"
+#include "hdr/fenv_macros.h"
+#include "src/__support/CPP/algorithm.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE::fputil {
+
+template <typename OutType, typename InType>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
+ cpp::is_floating_point_v<InType>,
+ OutType>
+cast(InType x) {
+#if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
+ if constexpr (cpp::is_same_v<OutType, float16> ||
+ cpp::is_same_v<InType, float16>) {
+ using InFPBits = FPBits<InType>;
+ using InStorageType = typename InFPBits::StorageType;
+ using OutFPBits = FPBits<OutType>;
+ using OutStorageType = typename OutFPBits::StorageType;
+
+ 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();
+ }
+
+ 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();
+
+ 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>();
+ }
+#endif
+
+ return static_cast<OutType>(x);
+}
+
+} // namespace LIBC_NAMESPACE::fputil
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_CAST_H
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 86346a47b35a..165ffc7c9220 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -11,11 +11,15 @@
#include "FEnvImpl.h"
#include "FPBits.h"
+#include "hdr/errno_macros.h"
+#include "hdr/fenv_macros.h"
#include "multiply_add.h"
+#include "rounding_mode.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/big_int.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/macros/properties/types.h"
#include <stddef.h>
@@ -97,13 +101,120 @@ template <size_t Bits> struct DyadicFloat {
return exponent + (Bits - 1);
}
- // Assume that it is already normalized.
- // Output is rounded correctly with respect to the current rounding mode.
+#ifdef LIBC_TYPES_HAS_FLOAT16
+ template <typename T, bool ShouldSignalExceptions>
+ LIBC_INLINE constexpr cpp::enable_if_t<
+ cpp::is_floating_point_v<T> && (FPBits<T>::FRACTION_LEN < Bits), T>
+ generic_as() const {
+ using FPBits = FPBits<float16>;
+ using StorageType = typename FPBits::StorageType;
+
+ constexpr int EXTRA_FRACTION_LEN = Bits - 1 - FPBits::FRACTION_LEN;
+
+ if (mantissa == 0)
+ return FPBits::zero(sign).get_val();
+
+ int unbiased_exp = get_unbiased_exponent();
+
+ if (unbiased_exp + FPBits::EXP_BIAS >= FPBits::MAX_BIASED_EXPONENT) {
+ if constexpr (ShouldSignalExceptions) {
+ set_errno_if_required(ERANGE);
+ raise_except_if_required(FE_OVERFLOW | FE_INEXACT);
+ }
+
+ switch (quick_get_round()) {
+ case FE_TONEAREST:
+ return FPBits::inf(sign).get_val();
+ case FE_TOWARDZERO:
+ return FPBits::max_normal(sign).get_val();
+ case FE_DOWNWARD:
+ if (sign.is_pos())
+ return FPBits::max_normal(Sign::POS).get_val();
+ return FPBits::inf(Sign::NEG).get_val();
+ case FE_UPWARD:
+ if (sign.is_neg())
+ return FPBits::max_normal(Sign::NEG).get_val();
+ return FPBits::inf(Sign::POS).get_val();
+ default:
+ __builtin_unreachable();
+ }
+ }
+
+ StorageType out_biased_exp = 0;
+ StorageType out_mantissa = 0;
+ bool round = false;
+ bool sticky = false;
+ bool underflow = false;
+
+ if (unbiased_exp < -FPBits::EXP_BIAS - FPBits::FRACTION_LEN) {
+ sticky = true;
+ underflow = true;
+ } else if (unbiased_exp == -FPBits::EXP_BIAS - FPBits::FRACTION_LEN) {
+ round = true;
+ MantissaType sticky_mask = (MantissaType(1) << (Bits - 1)) - 1;
+ sticky = (mantissa & sticky_mask) != 0;
+ } else {
+ int extra_fraction_len = EXTRA_FRACTION_LEN;
+
+ if (unbiased_exp < 1 - FPBits::EXP_BIAS) {
+ underflow = true;
+ extra_fraction_len += 1 - FPBits::EXP_BIAS - unbiased_exp;
+ } else {
+ out_biased_exp =
+ static_cast<StorageType>(unbiased_exp + FPBits::EXP_BIAS);
+ }
+
+ MantissaType round_mask = MantissaType(1) << (extra_fraction_len - 1);
+ round = (mantissa & round_mask) != 0;
+ MantissaType sticky_mask = round_mask - 1;
+ sticky = (mantissa & sticky_mask) != 0;
+
+ out_mantissa = static_cast<StorageType>(mantissa >> extra_fraction_len);
+ }
+
+ bool lsb = (out_mantissa & 1) != 0;
+
+ StorageType result =
+ FPBits::create_value(sign, out_biased_exp, out_mantissa).uintval();
+
+ switch (quick_get_round()) {
+ case FE_TONEAREST:
+ if (round && (lsb || sticky))
+ ++result;
+ break;
+ case FE_DOWNWARD:
+ if (sign.is_neg() && (round || sticky))
+ ++result;
+ break;
+ case FE_UPWARD:
+ if (sign.is_pos() && (round || sticky))
+ ++result;
+ break;
+ default:
+ break;
+ }
+
+ if (ShouldSignalExceptions && (round || sticky)) {
+ int excepts = FE_INEXACT;
+ if (FPBits(result).is_inf()) {
+ set_errno_if_required(ERANGE);
+ excepts |= FE_OVERFLOW;
+ } else if (underflow) {
+ set_errno_if_required(ERANGE);
+ excepts |= FE_UNDERFLOW;
+ }
+ raise_except_if_required(excepts);
+ }
+
+ return FPBits(result).get_val();
+ }
+#endif // LIBC_TYPES_HAS_FLOAT16
+
template <typename T, bool ShouldSignalExceptions,
typename = cpp::enable_if_t<cpp::is_floating_point_v<T> &&
(FPBits<T>::FRACTION_LEN < Bits),
void>>
- LIBC_INLINE constexpr T as() const {
+ LIBC_INLINE constexpr T fast_as() const {
if (LIBC_UNLIKELY(mantissa.is_zero()))
return FPBits<T>::zero(sign).get_val();
@@ -224,6 +335,20 @@ template <size_t Bits> struct DyadicFloat {
return r;
}
+ // Assume that it is already normalized.
+ // Output is rounded correctly with respect to the current rounding mode.
+ template <typename T, bool ShouldSignalExceptions,
+ typename = cpp::enable_if_t<cpp::is_floating_point_v<T> &&
+ (FPBits<T>::FRACTION_LEN < Bits),
+ void>>
+ LIBC_INLINE constexpr T as() const {
+#if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
+ if constexpr (cpp::is_same_v<T, float16>)
+ return generic_as<T, ShouldSignalExceptions>();
+#endif
+ return fast_as<T, ShouldSignalExceptions>();
+ }
+
template <typename T,
typename = cpp::enable_if_t<cpp::is_floating_point_v<T> &&
(FPBits<T>::FRACTION_LEN < Bits),
diff --git a/libc/src/__support/FPUtil/except_value_utils.h b/libc/src/__support/FPUtil/except_value_utils.h
index b9f54aa24e3a..f8e4e92d3e1f 100644
--- a/libc/src/__support/FPUtil/except_value_utils.h
+++ b/libc/src/__support/FPUtil/except_value_utils.h
@@ -11,10 +11,13 @@
#include "FEnvImpl.h"
#include "FPBits.h"
+#include "cast.h"
#include "rounding_mode.h"
#include "src/__support/CPP/optional.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/macros/properties/types.h"
namespace LIBC_NAMESPACE_DECL {
@@ -113,6 +116,21 @@ template <typename T> LIBC_INLINE T round_result_slightly_up(T value_rn) {
return tmp;
}
+#if defined(LIBC_TYPES_HAS_FLOAT16) && \
+ !defined(LIBC_TARGET_CPU_HAS_FAST_FLOAT16_OPS)
+template <> LIBC_INLINE float16 round_result_slightly_down(float16 value_rn) {
+ volatile float tmp = value_rn;
+ tmp -= FPBits<float16>::min_normal().get_val();
+ return cast<float16>(tmp);
+}
+
+template <> LIBC_INLINE float16 round_result_slightly_up(float16 value_rn) {
+ volatile float tmp = value_rn;
+ tmp += FPBits<float16>::min_normal().get_val();
+ return cast<float16>(tmp);
+}
+#endif
+
} // namespace fputil
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/FPUtil/generic/CMakeLists.txt b/libc/src/__support/FPUtil/generic/CMakeLists.txt
index 43096aa529fc..60434d6f6f11 100644
--- a/libc/src/__support/FPUtil/generic/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/generic/CMakeLists.txt
@@ -8,6 +8,7 @@ add_header_library(
libc.src.__support.common
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
+ libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.dyadic_float
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
@@ -21,16 +22,17 @@ add_header_library(
FMA.h
DEPENDS
libc.hdr.fenv_macros
+ libc.src.__support.big_int
libc.src.__support.common
libc.src.__support.CPP.bit
libc.src.__support.CPP.limits
libc.src.__support.CPP.type_traits
libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.dyadic_float
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.rounding_mode
- libc.src.__support.big_int
libc.src.__support.macros.optimization
libc.src.__support.uint128
)
@@ -60,9 +62,10 @@ add_header_library(
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.dyadic_float
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.dyadic_float
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.attributes
libc.src.__support.macros.optimization
diff --git a/libc/src/__support/FPUtil/generic/FMA.h b/libc/src/__support/FPUtil/generic/FMA.h
index e5683c8ff61e..bec312e44b1b 100644
--- a/libc/src/__support/FPUtil/generic/FMA.h
+++ b/libc/src/__support/FPUtil/generic/FMA.h
@@ -14,6 +14,7 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/big_int.h"
@@ -157,7 +158,7 @@ fma(InType x, InType y, InType z) {
}
if (LIBC_UNLIKELY(x == 0 || y == 0 || z == 0))
- return static_cast<OutType>(x * y + z);
+ return cast<OutType>(x * y + z);
int x_exp = 0;
int y_exp = 0;
@@ -198,7 +199,7 @@ fma(InType x, InType y, InType z) {
if (LIBC_UNLIKELY(x_exp == InFPBits::MAX_BIASED_EXPONENT ||
y_exp == InFPBits::MAX_BIASED_EXPONENT ||
z_exp == InFPBits::MAX_BIASED_EXPONENT))
- return static_cast<OutType>(x * y + z);
+ return cast<OutType>(x * y + z);
// Extract mantissa and append hidden leading bits.
InStorageType x_mant = x_bits.get_explicit_mantissa();
diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index 850db3f83209..6bc9dcd23baf 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -17,6 +17,7 @@
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/macros/attributes.h"
@@ -106,14 +107,14 @@ add_or_sub(InType x, InType y) {
volatile InType tmp = y;
if constexpr (IsSub)
tmp = -tmp;
- return static_cast<OutType>(tmp);
+ return cast<OutType>(tmp);
}
if (y_bits.is_zero()) {
volatile InType tmp = y;
if constexpr (IsSub)
tmp = -tmp;
- return static_cast<OutType>(tmp);
+ return cast<OutType>(tmp);
}
}
diff --git a/libc/src/__support/FPUtil/generic/sqrt.h b/libc/src/__support/FPUtil/generic/sqrt.h
index 4502cc07d32b..01af4bb7c900 100644
--- a/libc/src/__support/FPUtil/generic/sqrt.h
+++ b/libc/src/__support/FPUtil/generic/sqrt.h
@@ -14,6 +14,7 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
@@ -96,7 +97,7 @@ sqrt(InType x) {
// sqrt(-0) = -0
// sqrt(NaN) = NaN
// sqrt(-NaN) = -NaN
- return static_cast<OutType>(x);
+ return cast<OutType>(x);
} else if (bits.is_neg()) {
// sqrt(-Inf) = NaN
// sqrt(-x) = NaN
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 5a1ee3b8b83c..d0676d03420c 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -109,9 +109,10 @@ add_entrypoint_object(
COMPILE_OPTIONS
-O3
DEPENDS
- libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.macros.properties.types
FLAGS
ROUND_OPT
)
@@ -672,9 +673,10 @@ add_entrypoint_object(
COMPILE_OPTIONS
-O3
DEPENDS
- libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.macros.properties.types
FLAGS
ROUND_OPT
)
@@ -741,9 +743,10 @@ add_entrypoint_object(
COMPILE_OPTIONS
-O3
DEPENDS
- libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.macros.properties.types
FLAGS
ROUND_OPT
)
@@ -810,9 +813,10 @@ add_entrypoint_object(
COMPILE_OPTIONS
-O3
DEPENDS
- libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.macros.properties.types
FLAGS
ROUND_OPT
)
@@ -881,6 +885,7 @@ add_entrypoint_object(
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.FPUtil.cast
libc.src.__support.macros.properties.cpu_features
FLAGS
ROUND_OPT
@@ -1072,9 +1077,10 @@ add_entrypoint_object(
COMPILE_OPTIONS
-O3
DEPENDS
- libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.macros.properties.types
FLAGS
ROUND_OPT
)
@@ -1362,12 +1368,15 @@ add_entrypoint_object(
.expxf16
libc.hdr.errno_macros
libc.hdr.fenv_macros
+ libc.src.__support.CPP.array
+ 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.nearest_integer
libc.src.__support.FPUtil.polyeval
libc.src.__support.FPUtil.rounding_mode
- libc.src.__support.macros.attributes
libc.src.__support.macros.optimization
COMPILE_OPTIONS
-O3
@@ -1442,6 +1451,7 @@ add_entrypoint_object(
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.CPP.array
+ libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.except_value_utils
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
@@ -1545,6 +1555,7 @@ add_entrypoint_object(
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.CPP.array
+ libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.except_value_utils
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
@@ -1617,6 +1628,7 @@ add_entrypoint_object(
.expxf16
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
diff --git a/libc/src/math/generic/ceilf16.cpp b/libc/src/math/generic/ceilf16.cpp
index 8af31c6623a0..9d89efc5311d 100644
--- a/libc/src/math/generic/ceilf16.cpp
+++ b/libc/src/math/generic/ceilf16.cpp
@@ -8,6 +8,7 @@
#include "src/math/ceilf16.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/cpu_features.h"
@@ -17,7 +18,7 @@ namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(float16, ceilf16, (float16 x)) {
#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
defined(LIBC_TARGET_CPU_HAS_FAST_FLOAT16_OPS)
- return static_cast<float16>(__builtin_ceilf(x));
+ return fputil::cast<float16>(__builtin_ceilf(x));
#else
return fputil::ceil(x);
#endif
diff --git a/libc/src/math/generic/exp10f16.cpp b/libc/src/math/generic/exp10f16.cpp
index 9959f7450b59..1c5966c1f1c1 100644
--- a/libc/src/math/generic/exp10f16.cpp
+++ b/libc/src/math/generic/exp10f16.cpp
@@ -14,6 +14,7 @@
#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/nearest_integer.h"
@@ -118,13 +119,13 @@ LLVM_LIBC_FUNCTION(float16, exp10f16, (float16 x)) {
if (LIBC_UNLIKELY((x_u & ~(0x3c00U | 0x4000U | 0x4200U | 0x4400U)) == 0)) {
switch (x_u) {
case 0x3c00U: // x = 1.0f16
- return static_cast<float16>(10.0);
+ return fputil::cast<float16>(10.0);
case 0x4000U: // x = 2.0f16
- return static_cast<float16>(100.0);
+ return fputil::cast<float16>(100.0);
case 0x4200U: // x = 3.0f16
- return static_cast<float16>(1'000.0);
+ return fputil::cast<float16>(1'000.0);
case 0x4400U: // x = 4.0f16
- return static_cast<float16>(10'000.0);
+ return fputil::cast<float16>(10'000.0);
}
}
@@ -164,7 +165,7 @@ LLVM_LIBC_FUNCTION(float16, exp10f16, (float16 x)) {
// > 1 + x * P;
float exp10_lo = fputil::polyeval(lo, 0x1p+0f, 0x1.26bb14p+1f, 0x1.53526p+1f,
0x1.04b434p+1f, 0x1.2bcf9ep+0f);
- return static_cast<float16>(exp2_hi_mid * exp10_lo);
+ return fputil::cast<float16>(exp2_hi_mid * exp10_lo);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/exp2f16.cpp b/libc/src/math/generic/exp2f16.cpp
index 66b795670400..3c4310259b1d 100644
--- a/libc/src/math/generic/exp2f16.cpp
+++ b/libc/src/math/generic/exp2f16.cpp
@@ -14,6 +14,7 @@
#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/nearest_integer.h"
@@ -121,7 +122,7 @@ LLVM_LIBC_FUNCTION(float16, exp2f16, (float16 x)) {
// > 1 + x * P;
float exp2_lo = fputil::polyeval(lo, 0x1p+0f, 0x1.62e43p-1f, 0x1.ec0aa6p-3f,
0x1.c6b4a6p-5f);
- return static_cast<float16>(exp2_hi_mid * exp2_lo);
+ return fputil::cast<float16>(exp2_hi_mid * exp2_lo);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/expf16.cpp b/libc/src/math/generic/expf16.cpp
index 7ffdbd519100..0548ef3932ae 100644
--- a/libc/src/math/generic/expf16.cpp
+++ b/libc/src/math/generic/expf16.cpp
@@ -13,6 +13,7 @@
#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/rounding_mode.h"
#include "src/__support/common.h"
@@ -103,7 +104,7 @@ LLVM_LIBC_FUNCTION(float16, expf16, (float16 x)) {
// > display = hexadecimal;
// > P = fpminimax(expm1(x)/x, 2, [|SG...|], [-2^-5, 2^-5]);
// > 1 + x * P;
- return static_cast<float16>(
+ return fputil::cast<float16>(
fputil::polyeval(xf, 0x1p+0f, 0x1p+0f, 0x1.0004p-1f, 0x1.555778p-3f));
}
}
@@ -113,7 +114,7 @@ LLVM_LIBC_FUNCTION(float16, expf16, (float16 x)) {
// exp(x) = exp(hi + mid) * exp(lo)
auto [exp_hi_mid, exp_lo] = exp_range_reduction(x);
- return static_cast<float16>(exp_hi_mid * exp_lo);
+ return fputil::cast<float16>(exp_hi_mid * exp_lo);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/expm1f16.cpp b/libc/src/math/generic/expm1f16.cpp
index 0facdc510e42..4ce0efd1f461 100644
--- a/libc/src/math/generic/expm1f16.cpp
+++ b/libc/src/math/generic/expm1f16.cpp
@@ -13,6 +13,7 @@
#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/rounding_mode.h"
@@ -99,7 +100,7 @@ LLVM_LIBC_FUNCTION(float16, expm1f16, (float16 x)) {
FPBits::one(Sign::NEG).get_val());
// When x <= -0x1.0ap+3, round(expm1(x), HP, RN) = -0x1.ffcp-1.
return fputil::round_result_slightly_down(
- static_cast<float16>(-0x1.ffcp-1));
+ fputil::cast<float16>(-0x1.ffcp-1));
}
// When 0 < |x| <= 2^(-3).
@@ -114,7 +115,7 @@ LLVM_LIBC_FUNCTION(float16, expm1f16, (float16 x)) {
// > display = hexadecimal;
// > P = fpminimax(expm1(x)/x, 4, [|SG...|], [-2^-3, 2^-3]);
// > x * P;
- return static_cast<float16>(
+ return fputil::cast<float16>(
xf * fputil::polyeval(xf, 0x1p+0f, 0x1.fffff8p-2f, 0x1.555556p-3f,
0x1.55905ep-5f, 0x1.1124c2p-7f));
}
@@ -126,7 +127,7 @@ LLVM_LIBC_FUNCTION(float16, expm1f16, (float16 x)) {
// exp(x) = exp(hi + mid) * exp(lo)
auto [exp_hi_mid, exp_lo] = exp_range_reduction(x);
// expm1(x) = exp(hi + mid) * exp(lo) - 1
- return static_cast<float16>(fputil::multiply_add(exp_hi_mid, exp_lo, -1.0f));
+ return fputil::cast<float16>(fputil::multiply_add(exp_hi_mid, exp_lo, -1.0f));
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/floorf16.cpp b/libc/src/math/generic/floorf16.cpp
index 3092048f5ab0..361b22729f64 100644
--- a/libc/src/math/generic/floorf16.cpp
+++ b/libc/src/math/generic/floorf16.cpp
@@ -8,6 +8,7 @@
#include "src/math/floorf16.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/cpu_features.h"
@@ -17,7 +18,7 @@ namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(float16, floorf16, (float16 x)) {
#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
defined(LIBC_TARGET_CPU_HAS_FAST_FLOAT16_OPS)
- return static_cast<float16>(__builtin_floorf(x));
+ return fputil::cast<float16>(__builtin_floorf(x));
#else
return fputil::floor(x);
#endif
diff --git a/libc/src/math/generic/rintf16.cpp b/libc/src/math/generic/rintf16.cpp
index 3a53dd28e3d1..aefdcbea7706 100644
--- a/libc/src/math/generic/rintf16.cpp
+++ b/libc/src/math/generic/rintf16.cpp
@@ -8,6 +8,7 @@
#include "src/math/rintf16.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/cpu_features.h"
@@ -17,7 +18,7 @@ namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(float16, rintf16, (float16 x)) {
#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
defined(LIBC_TARGET_CPU_HAS_FAST_FLOAT16_OPS)
- return static_cast<float16>(__builtin_rintf(x));
+ return fputil::cast<float16>(__builtin_rintf(x));
#else
return fputil::round_using_current_rounding_mode(x);
#endif
diff --git a/libc/src/math/generic/roundevenf16.cpp b/libc/src/math/generic/roundevenf16.cpp
index c3dbd779b973..fdcd968bc9b8 100644
--- a/libc/src/math/generic/roundevenf16.cpp
+++ b/libc/src/math/generic/roundevenf16.cpp
@@ -8,6 +8,7 @@
#include "src/math/roundevenf16.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/cpu_features.h"
@@ -17,7 +18,7 @@ namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(float16, roundevenf16, (float16 x)) {
#if defined(__LIBC_USE_BUILTIN_ROUNDEVEN) && \
defined(LIBC_TARGET_CPU_HAS_FAST_FLOAT16_OPS)
- return static_cast<float16>(__builtin_roundevenf(x));
+ return fputil::cast<float16>(__builtin_roundevenf(x));
#else
return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
#endif
diff --git a/libc/src/math/generic/roundf16.cpp b/libc/src/math/generic/roundf16.cpp
index a5e2b44fbd54..9adfb52ed27c 100644
--- a/libc/src/math/generic/roundf16.cpp
+++ b/libc/src/math/generic/roundf16.cpp
@@ -8,6 +8,7 @@
#include "src/math/roundf16.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/cpu_features.h"
@@ -17,7 +18,7 @@ namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(float16, roundf16, (float16 x)) {
#if defined(__LIBC_USE_BUILTIN_ROUND) && \
defined(LIBC_TARGET_CPU_HAS_FAST_FLOAT16_OPS)
- return static_cast<float16>(__builtin_roundf(x));
+ return fputil::cast<float16>(__builtin_roundf(x));
#else
return fputil::round(x);
#endif
diff --git a/libc/src/math/generic/truncf16.cpp b/libc/src/math/generic/truncf16.cpp
index 31b1214a9a0e..4d37e6560a96 100644
--- a/libc/src/math/generic/truncf16.cpp
+++ b/libc/src/math/generic/truncf16.cpp
@@ -8,6 +8,7 @@
#include "src/math/truncf16.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/cpu_features.h"
@@ -17,7 +18,7 @@ namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(float16, truncf16, (float16 x)) {
#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
defined(LIBC_TARGET_CPU_HAS_FAST_FLOAT16_OPS)
- return static_cast<float16>(__builtin_truncf(x));
+ return fputil::cast<float16>(__builtin_truncf(x));
#else
return fputil::trunc(x);
#endif
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index 7fc68cb35e84..1b5b2cb15526 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -621,3 +621,10 @@ add_entrypoint_object(
DEPENDS
.${LIBC_TARGET_OS}.abort
)
+
+add_entrypoint_object(
+ system
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.system
+)
diff --git a/libc/src/stdlib/gpu/CMakeLists.txt b/libc/src/stdlib/gpu/CMakeLists.txt
index 073f81515870..3c0588a27e7e 100644
--- a/libc/src/stdlib/gpu/CMakeLists.txt
+++ b/libc/src/stdlib/gpu/CMakeLists.txt
@@ -61,5 +61,16 @@ add_entrypoint_object(
../abort.h
DEPENDS
libc.include.stdlib
- libc.src.__support.GPU.allocator
+ libc.src.__support.RPC.rpc_client
+)
+
+add_entrypoint_object(
+ system
+ SRCS
+ system.cpp
+ HDRS
+ ../system.h
+ DEPENDS
+ libc.include.stdlib
+ libc.src.__support.RPC.rpc_client
)
diff --git a/libc/src/stdlib/gpu/system.cpp b/libc/src/stdlib/gpu/system.cpp
new file mode 100644
index 000000000000..acf3a8c941ff
--- /dev/null
+++ b/libc/src/stdlib/gpu/system.cpp
@@ -0,0 +1,29 @@
+//===-- GPU implementation of system --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache 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/RPC/rpc_client.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/string/string_utils.h"
+
+#include "src/stdlib/system.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, system, (const char *command)) {
+ int ret;
+ rpc::Client::Port port = rpc::client.open<RPC_SYSTEM>();
+ port.send_n(command, internal::string_length(command) + 1);
+ port.recv(
+ [&](rpc::Buffer *buffer) { ret = static_cast<int>(buffer->data[0]); });
+ port.close();
+
+ return ret;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/system.h b/libc/src/stdlib/system.h
new file mode 100644
index 000000000000..3358ca7bb7a6
--- /dev/null
+++ b/libc/src/stdlib/system.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for system ------------------------*- 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_STDLIB_SYSTEM_H
+#define LLVM_LIBC_SRC_STDLIB_SYSTEM_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int system(const char *command);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDLIB_SYSTEM_H