37 changes: 29 additions & 8 deletions compiler-rt/lib/profile/InstrProfilingWriter.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,14 @@ COMPILER_RT_VISIBILITY int lprofWriteData(ProfDataWriter *Writer,
const char *BitmapEnd = __llvm_profile_end_bitmap();
const char *NamesBegin = __llvm_profile_begin_names();
const char *NamesEnd = __llvm_profile_end_names();
const VTableProfData *VTableBegin = __llvm_profile_begin_vtables();
const VTableProfData *VTableEnd = __llvm_profile_end_vtables();
const char *VNamesBegin = __llvm_profile_begin_vtabnames();
const char *VNamesEnd = __llvm_profile_end_vtabnames();
return lprofWriteDataImpl(Writer, DataBegin, DataEnd, CountersBegin,
CountersEnd, BitmapBegin, BitmapEnd, VPDataReader,
NamesBegin, NamesEnd, SkipNameDataWrite);
NamesBegin, NamesEnd, VTableBegin, VTableEnd,
VNamesBegin, VNamesEnd, SkipNameDataWrite);
}

COMPILER_RT_VISIBILITY int
Expand All @@ -261,7 +266,9 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
const char *CountersBegin, const char *CountersEnd,
const char *BitmapBegin, const char *BitmapEnd,
VPDataReaderType *VPDataReader, const char *NamesBegin,
const char *NamesEnd, int SkipNameDataWrite) {
const char *NamesEnd, const VTableProfData *VTableBegin,
const VTableProfData *VTableEnd, const char *VNamesBegin,
const char *VNamesEnd, int SkipNameDataWrite) {
/* Calculate size of sections. */
const uint64_t DataSectionSize =
__llvm_profile_get_data_size(DataBegin, DataEnd);
Expand All @@ -273,18 +280,28 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
const uint64_t NumBitmapBytes =
__llvm_profile_get_num_bitmap_bytes(BitmapBegin, BitmapEnd);
const uint64_t NamesSize = __llvm_profile_get_name_size(NamesBegin, NamesEnd);
const uint64_t NumVTables =
__llvm_profile_get_num_vtable(VTableBegin, VTableEnd);
const uint64_t VTableSectionSize =
__llvm_profile_get_vtable_section_size(VTableBegin, VTableEnd);
const uint64_t VNamesSize =
__llvm_profile_get_name_size(VNamesBegin, VNamesEnd);

/* Create the header. */
__llvm_profile_header Header;

/* Determine how much padding is needed before/after the counters and after
* the names. */
uint64_t PaddingBytesBeforeCounters, PaddingBytesAfterCounters,
PaddingBytesAfterNames, PaddingBytesAfterBitmapBytes;
__llvm_profile_get_padding_sizes_for_counters(
DataSectionSize, CountersSectionSize, NumBitmapBytes, NamesSize,
&PaddingBytesBeforeCounters, &PaddingBytesAfterCounters,
&PaddingBytesAfterBitmapBytes, &PaddingBytesAfterNames);
PaddingBytesAfterBitmapBytes, PaddingBytesAfterNames,
PaddingBytesAfterVTable, PaddingBytesAfterVNames;
if (__llvm_profile_get_padding_sizes_for_counters(
DataSectionSize, CountersSectionSize, NumBitmapBytes, NamesSize,
VTableSectionSize, VNamesSize, &PaddingBytesBeforeCounters,
&PaddingBytesAfterCounters, &PaddingBytesAfterBitmapBytes,
&PaddingBytesAfterNames, &PaddingBytesAfterVTable,
&PaddingBytesAfterVNames) == -1)
return -1;

{
/* Initialize header structure. */
Expand Down Expand Up @@ -323,7 +340,11 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
{BitmapBegin, sizeof(uint8_t), NumBitmapBytes, 0},
{NULL, sizeof(uint8_t), PaddingBytesAfterBitmapBytes, 1},
{SkipNameDataWrite ? NULL : NamesBegin, sizeof(uint8_t), NamesSize, 0},
{NULL, sizeof(uint8_t), PaddingBytesAfterNames, 1}};
{NULL, sizeof(uint8_t), PaddingBytesAfterNames, 1},
{VTableBegin, sizeof(uint8_t), VTableSectionSize, 0},
{NULL, sizeof(uint8_t), PaddingBytesAfterVTable, 1},
{SkipNameDataWrite ? NULL : VNamesBegin, sizeof(uint8_t), VNamesSize, 0},
{NULL, sizeof(uint8_t), PaddingBytesAfterVNames, 1}};
if (Writer->Write(Writer, IOVecData, sizeof(IOVecData) / sizeof(*IOVecData)))
return -1;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_stackdepot.h"

#include <algorithm>
#include <atomic>
#include <numeric>
#include <regex>
Expand Down
49 changes: 34 additions & 15 deletions compiler-rt/test/lit.common.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,24 +168,43 @@ def push_dynamic_library_lookup_path(config, new_path):
r"/i386(?=-[^/]+$)", "/x86_64", config.compiler_rt_libdir
)


# Check if the test compiler resource dir matches the local build directory
# (which happens with -DLLVM_ENABLE_PROJECTS=clang;compiler-rt) or if we are
# using an installed clang to test compiler-rt standalone. In the latter case
# we may need to override the resource dir to match the path of the just-built
# compiler-rt libraries.
test_cc_resource_dir, _ = get_path_from_clang(
shlex.split(config.target_cflags) + ["-print-resource-dir"], allow_failure=True
)
# Normalize the path for comparison
if test_cc_resource_dir is not None:
test_cc_resource_dir = os.path.realpath(test_cc_resource_dir)
if lit_config.debug:
lit_config.note(f"Resource dir for {config.clang} is {test_cc_resource_dir}")
local_build_resource_dir = os.path.realpath(config.compiler_rt_output_dir)
if test_cc_resource_dir != local_build_resource_dir:
if config.test_standalone_build_libs and config.compiler_id == "Clang":
if lit_config.debug:
lit_config.note(f'Overriding test compiler resource dir to use '
f'libraries in "{config.compiler_rt_libdir}"')
# Ensure that we use the just-built static libraries when linking by
# overriding the Clang resource directory. Additionally, we want to use
# the builtin headers shipped with clang (e.g. stdint.h), so we
# explicitly add this as an include path (since the headers are not
# going to be in the current compiler-rt build directory).
# We also tell the linker to add an RPATH entry for the local library
# directory so that the just-built shared libraries are used.
config.target_cflags += f" -nobuiltininc"
config.target_cflags += f" -I{config.compiler_rt_src_root}/include"
config.target_cflags += f" -idirafter {test_cc_resource_dir}/include"
config.target_cflags += f" -resource-dir={config.compiler_rt_output_dir}"
config.target_cflags += f" -Wl,-rpath,{config.compiler_rt_libdir}"

# Ask the compiler for the path to libraries it is going to use. If this
# doesn't match config.compiler_rt_libdir then it means we might be testing the
# compiler's own runtime libraries rather than the ones we just built.
# Warn about about this and handle appropriately.
if config.test_standalone_build_libs:
if config.compiler_id == "Clang":
# Ensure that we use the just-built libraries when linking by overriding
# the Clang resource directory. However, this also means that we can no
# longer find the builtin headers from that path, so we explicitly add
# the builtin headers as an include path.
resource_dir, _ = get_path_from_clang(
shlex.split(config.target_cflags) + ["-print-resource-dir"], allow_failure=False
)
config.target_cflags += f" -nobuiltininc"
config.target_cflags += f" -I{config.compiler_rt_src_root}/include"
config.target_cflags += f" -idirafter {resource_dir}/include"
config.target_cflags += f" -resource-dir={config.compiler_rt_obj_root}"
config.target_cflags += f" -Wl,--rpath={config.compiler_rt_libdir}"
# Warn about this and handle appropriately.
compiler_libdir = find_compiler_libdir()
if compiler_libdir:
compiler_rt_libdir_real = os.path.realpath(config.compiler_rt_libdir)
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/test/lit.common.configured.in
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ set_default("compiler_id", "@COMPILER_RT_TEST_COMPILER_ID@")
set_default("python_executable", "@Python3_EXECUTABLE@")
set_default("compiler_rt_debug", @COMPILER_RT_DEBUG_PYBOOL@)
set_default("compiler_rt_intercept_libdispatch", @COMPILER_RT_INTERCEPT_LIBDISPATCH_PYBOOL@)
set_default("compiler_rt_output_dir", "@COMPILER_RT_RESOLVED_OUTPUT_DIR@")
set_default("compiler_rt_libdir", "@COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR@")
set_default("emulator", "@COMPILER_RT_EMULATOR@")
set_default("asan_shadow_scale", "@COMPILER_RT_ASAN_SHADOW_SCALE@")
Expand Down
6 changes: 4 additions & 2 deletions compiler-rt/test/profile/instrprof-write-buffer-internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ char *__llvm_profile_end_bitmap(void);
uint64_t __llvm_profile_get_size_for_buffer_internal(
const void *DataBegin, const void *DataEnd, const char *CountersBegin,
const char *CountersEnd, const char *BitmapBegin, const char *BitmapEnd,
const char *NamesBegin, const char *NamesEnd);
const char *NamesBegin, const char *NamesEnd, const void *VTableBegin,
const void *VTableEnd, const char *VNamesBegin, const char *VNamesEnd);

int __llvm_profile_write_buffer_internal(
char *Buffer, const void *DataBegin, const void *DataEnd,
Expand All @@ -45,7 +46,8 @@ int main(int argc, const char *argv[]) {
__llvm_profile_begin_data(), __llvm_profile_end_data(),
__llvm_profile_begin_counters(), __llvm_profile_end_counters(),
__llvm_profile_begin_bitmap(), __llvm_profile_end_bitmap(),
__llvm_profile_begin_names(), __llvm_profile_end_names());
__llvm_profile_begin_names(), __llvm_profile_end_names(), NULL, NULL,
NULL, NULL);

char *buf = malloc(bufsize);
int ret = __llvm_profile_write_buffer_internal(
Expand Down
18 changes: 15 additions & 3 deletions flang/runtime/Float128Math/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
# will have a dependency on the third-party library that is being
# used for building this FortranFloat128Math library.

if (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libquadmath" OR
${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "quadmath")
include(CheckLibraryExists)

if (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libquadmath")
check_include_file(quadmath.h FOUND_QUADMATH_HEADER)
if(FOUND_QUADMATH_HEADER)
add_compile_definitions(HAS_QUADMATHLIB)
Expand All @@ -25,7 +26,18 @@ if (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libquadmath" OR
"to be available: ${FLANG_RUNTIME_F128_MATH_LIB}"
)
endif()
else()
elseif (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libm")
check_library_exists(m sinl "" FOUND_LIBM)
check_library_exists(m sinf128 "" FOUND_LIBMF128)
if (FOUND_LIBM)
add_compile_definitions(HAS_LIBM)
endif()
if (FOUND_LIBMF128)
add_compile_definitions(HAS_LIBMF128)
endif()
endif()

if (NOT FOUND_QUADMATH_HEADER AND NOT FOUND_LIBM)
message(FATAL_ERROR
"Unsupported third-party library for Fortran F128 math runtime: "
"${FLANG_RUNTIME_F128_MATH_LIB}"
Expand Down
68 changes: 66 additions & 2 deletions flang/runtime/Float128Math/math-entries.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "tools.h"
#include "flang/Common/float128.h"
#include "flang/Runtime/entry-names.h"
#include <cfloat>
#include <type_traits>

namespace Fortran::runtime {
Expand Down Expand Up @@ -42,7 +43,8 @@ namespace Fortran::runtime {
#define DEFINE_SIMPLE_ALIAS(caller, callee) \
template <typename RT, typename... ATs, RT (*p)(ATs...)> struct caller<p> { \
static RT invoke(ATs... args) { \
static_assert(std::is_invocable_r_v<RT, decltype(callee), ATs...>); \
static_assert(std::is_invocable_r_v<RT, \
decltype(callee(std::declval<ATs>()...))(ATs...), ATs...>); \
if constexpr (std::is_same_v<RT, void>) { \
callee(args...); \
} else { \
Expand Down Expand Up @@ -98,7 +100,69 @@ typedef _Complex float __attribute__((mode(TC))) ComplexF128;
typedef _Complex float __attribute__((mode(KC))) ComplexF128;
#endif

#if HAS_QUADMATHLIB
#if HAS_LIBM
// Define wrapper callers for libm.
#include <ccomplex>
#include <cmath>

#if LDBL_MANT_DIG == 113
// Use STD math functions. They provide IEEE-754 128-bit float
// support either via 'long double' or __float128.
// The Bessel's functions are not present in STD namespace.
DEFINE_SIMPLE_ALIAS(Acos, std::acos)
DEFINE_SIMPLE_ALIAS(Acosh, std::acosh)
DEFINE_SIMPLE_ALIAS(Asin, std::asin)
DEFINE_SIMPLE_ALIAS(Asinh, std::asinh)
DEFINE_SIMPLE_ALIAS(Atan, std::atan)
DEFINE_SIMPLE_ALIAS(Atan2, std::atan2)
DEFINE_SIMPLE_ALIAS(Atanh, std::atanh)
// TODO: enable complex abs, when ABI adjustment for complex
// data type is resolved.
// DEFINE_SIMPLE_ALIAS(CAbs, std::abs)
DEFINE_SIMPLE_ALIAS(Ceil, std::ceil)
DEFINE_SIMPLE_ALIAS(Cos, std::cos)
DEFINE_SIMPLE_ALIAS(Cosh, std::cosh)
DEFINE_SIMPLE_ALIAS(Erf, std::erf)
DEFINE_SIMPLE_ALIAS(Erfc, std::erfc)
DEFINE_SIMPLE_ALIAS(Exp, std::exp)
DEFINE_SIMPLE_ALIAS(Floor, std::floor)
DEFINE_SIMPLE_ALIAS(Hypot, std::hypot)
DEFINE_SIMPLE_ALIAS(J0, j0l)
DEFINE_SIMPLE_ALIAS(J1, j1l)
DEFINE_SIMPLE_ALIAS(Jn, jnl)
DEFINE_SIMPLE_ALIAS(Lgamma, std::lgamma)
DEFINE_SIMPLE_ALIAS(Llround, std::llround)
DEFINE_SIMPLE_ALIAS(Lround, std::lround)
DEFINE_SIMPLE_ALIAS(Log, std::log)
DEFINE_SIMPLE_ALIAS(Log10, std::log10)
DEFINE_SIMPLE_ALIAS(Pow, std::pow)
DEFINE_SIMPLE_ALIAS(Round, std::round)
DEFINE_SIMPLE_ALIAS(Sin, std::sin)
DEFINE_SIMPLE_ALIAS(Sinh, std::sinh)
DEFINE_SIMPLE_ALIAS(Sqrt, std::sqrt)
DEFINE_SIMPLE_ALIAS(Tan, std::tan)
DEFINE_SIMPLE_ALIAS(Tanh, std::tanh)
DEFINE_SIMPLE_ALIAS(Tgamma, std::tgamma)
DEFINE_SIMPLE_ALIAS(Trunc, std::trunc)
DEFINE_SIMPLE_ALIAS(Y0, y0l)
DEFINE_SIMPLE_ALIAS(Y1, y1l)
DEFINE_SIMPLE_ALIAS(Yn, ynl)
#else // LDBL_MANT_DIG != 113
#if !HAS_LIBMF128
// glibc >=2.26 seems to have complete support for __float128
// versions of the math functions.
#error "FLANG_RUNTIME_F128_MATH_LIB=libm build requires libm >=2.26"
#endif

// We can use __float128 versions of libm functions.
// __STDC_WANT_IEC_60559_TYPES_EXT__ needs to be defined
// before including cmath to enable the *f128 prototypes.
// TODO: this needs to be enabled separately, especially
// for complex data types that require C++ complex to C complex
// adjustment to match the ABIs.
#error "Unsupported FLANG_RUNTIME_F128_MATH_LIB=libm build"
#endif // LDBL_MANT_DIG != 113
#elif HAS_QUADMATHLIB
// Define wrapper callers for libquadmath.
#include "quadmath.h"
DEFINE_SIMPLE_ALIAS(Acos, acosq)
Expand Down
6 changes: 6 additions & 0 deletions flang/test/Lower/CUDA/cuda-mod.cuf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

module cuf_mod
real, device :: md

contains
attributes(device) subroutine devsub()
end
end module

! CHECK: fir.global @_QMcuf_modEmd {cuda_attr = #fir.cuda<device>} : f32

! CHECK: func.func @_QMcuf_modPdevsub() attributes {fir.cuda_attr = #fir.cuda_proc<device>}
14 changes: 12 additions & 2 deletions flang/test/Lower/CUDA/cuda-module-use.cuf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
! RUN: bbc -emit-hlfir -fcuda %S/cuda-mod.cuf
! RUN: bbc -emit-hlfir -fcuda %s -o - | FileCheck %s

! Test importing module with variable with CUDA attributes.
! Test importing module containing variable and subroutine with CUDA attributes.

subroutine sub1()
use cuf_mod
Expand All @@ -12,4 +12,14 @@ end
! CHECK: %[[ADDR:.*]] = fir.address_of(@_QMcuf_modEmd) : !fir.ref<f32>
! CHECK: %{{.*}}:2 = hlfir.declare %[[ADDR]] {cuda_attr = #fir.cuda<device>, uniq_name = "_QMcuf_modEmd"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)

! CHECK: fir.global @_QMcuf_modEmd {cuda_attr = #fir.cuda<device>} : f32
attributes(device) subroutine sub2()
use cuf_mod
call devsub()
end

! CHECK-LABEL: func.func @_QPsub2() attributes {fir.cuda_attr = #fir.cuda_proc<device>}
! CHECK: fir.call @_QMcuf_modPdevsub()

! CHECK-LABEL: fir.global @_QMcuf_modEmd {cuda_attr = #fir.cuda<device>} : f32

! CHECK-LABEL: func.func private @_QMcuf_modPdevsub() attributes {fir.cuda_attr = #fir.cuda_proc<device>}
2 changes: 1 addition & 1 deletion libc/cmake/modules/LLVMLibCObjectRules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ function(create_entrypoint_object fq_target_name)
${fq_target_name}
PROPERTIES
ENTRYPOINT_NAME ${ADD_ENTRYPOINT_OBJ_NAME}
TARGET_TYPE ${ENTRYPOINT_OBJ_TARGET_TYPE}
TARGET_TYPE ${entrypoint_target_type}
OBJECT_FILE "$<TARGET_OBJECTS:${fq_target_name}>"
CXX_STANDARD ${ADD_ENTRYPOINT_OBJ_CXX_STANDARD}
DEPS "${fq_deps_list}"
Expand Down
4 changes: 4 additions & 0 deletions libc/config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
"LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE": {
"value": false,
"doc": "Use large table for better printf long double performance."
},
"LIBC_CONF_PRINTF_DISABLE_FIXED_POINT": {
"value": false,
"doc": "Disable printing fixed point values in printf and friends."
}
},
"string": {
Expand Down
2 changes: 2 additions & 0 deletions libc/config/gpu/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.ilogbf
libc.src.math.ldexp
libc.src.math.ldexpf
libc.src.math.llogb
libc.src.math.llogbf
libc.src.math.llrint
libc.src.math.llrintf
libc.src.math.llround
Expand Down
6 changes: 6 additions & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,9 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.ilogb
libc.src.math.ilogbf
libc.src.math.ilogbl
libc.src.math.llogb
libc.src.math.llogbf
libc.src.math.llogbl
libc.src.math.llrint
libc.src.math.llrintf
libc.src.math.llrintl
Expand Down Expand Up @@ -422,7 +425,10 @@ if(LIBC_COMPILER_HAS_FLOAT128)
libc.src.math.fmaxf128
libc.src.math.fminf128
libc.src.math.frexpf128
libc.src.math.ilogbf128
libc.src.math.ldexpf128
libc.src.math.llogbf128
libc.src.math.logbf128
libc.src.math.roundf128
libc.src.math.sqrtf128
libc.src.math.truncf128
Expand Down
3 changes: 3 additions & 0 deletions libc/config/linux/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.ldexp
libc.src.math.ldexpf
libc.src.math.ldexpl
libc.src.math.llogb
libc.src.math.llogbf
libc.src.math.llogbl
libc.src.math.llrint
libc.src.math.llrintf
libc.src.math.llrintl
Expand Down
6 changes: 6 additions & 0 deletions libc/config/linux/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,9 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.ldexp
libc.src.math.ldexpf
libc.src.math.ldexpl
libc.src.math.llogb
libc.src.math.llogbf
libc.src.math.llogbl
libc.src.math.llrint
libc.src.math.llrintf
libc.src.math.llrintl
Expand Down Expand Up @@ -431,7 +434,10 @@ if(LIBC_COMPILER_HAS_FLOAT128)
libc.src.math.fmaxf128
libc.src.math.fminf128
libc.src.math.frexpf128
libc.src.math.ilogbf128
libc.src.math.ldexpf128
libc.src.math.llogbf128
libc.src.math.logbf128
libc.src.math.roundf128
libc.src.math.sqrtf128
libc.src.math.truncf128
Expand Down
12 changes: 12 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,9 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.ldexp
libc.src.math.ldexpf
libc.src.math.ldexpl
libc.src.math.llogb
libc.src.math.llogbf
libc.src.math.llogbl
libc.src.math.llrint
libc.src.math.llrintf
libc.src.math.llrintl
Expand Down Expand Up @@ -445,7 +448,10 @@ if(LIBC_COMPILER_HAS_FLOAT128)
libc.src.math.fmaxf128
libc.src.math.fminf128
libc.src.math.frexpf128
libc.src.math.ilogbf128
libc.src.math.ldexpf128
libc.src.math.llogbf128
libc.src.math.logbf128
libc.src.math.roundf128
libc.src.math.sqrtf128
libc.src.math.truncf128
Expand Down Expand Up @@ -473,6 +479,12 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.roundur
libc.src.stdfix.roundulk
libc.src.stdfix.roundulr
libc.src.stdfix.sqrtuhk
libc.src.stdfix.sqrtuhr
libc.src.stdfix.sqrtuk
libc.src.stdfix.sqrtur
# libc.src.stdfix.sqrtulk
libc.src.stdfix.sqrtulr
)
endif()

Expand Down
1 change: 1 addition & 0 deletions libc/docs/configure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ overrides in ``config/<platform>/config.json`` and ``config/<platform>/<arch>/co
to learn about the defaults for your platform and target.

* **"printf" options**
- ``LIBC_CONF_PRINTF_DISABLE_FIXED_POINT``: Disable printing fixed point values in printf and friends.
- ``LIBC_CONF_PRINTF_DISABLE_FLOAT``: Disable printing floating point values in printf and friends.
- ``LIBC_CONF_PRINTF_DISABLE_INDEX_MODE``: Disable index mode in the printf format string.
- ``LIBC_CONF_PRINTF_DISABLE_WRITE_INT``: Disable handling of %n in printf format string.
Expand Down
12 changes: 12 additions & 0 deletions libc/docs/dev/printf_behavior.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ When set, this flag disables support for floating point numbers and all their
conversions (%a, %f, %e, %g); any floating point number conversion will be
treated as invalid. This reduces code size.

LIBC_COPT_PRINTF_DISABLE_FIXED_POINT
------------------------------------
When set, this flag disables support for fixed point numbers and all their
conversions (%r, %k); any fixed point number conversion will be treated as
invalid. This reduces code size. This has no effect if the current compiler does
not support fixed point numbers.

LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
----------------------------------
When set, this flag disables the nullptr checks in %n and %s.
Expand Down Expand Up @@ -191,3 +198,8 @@ original conversion.
The %p conversion will display a null pointer as if it was the string
"(nullptr)" passed to a "%s" conversion, with all other options remaining the
same as the original conversion.

The %r, %R, %k, and %K fixed point number format specifiers are accepted as
defined in ISO/IEC TR 18037 (the fixed point number extension). These are
available when the compiler is detected as having support for fixed point
numbers and the LIBC_COPT_PRINTF_DISABLE_FIXED_POINT flag is not set.
12 changes: 12 additions & 0 deletions libc/docs/math/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ Basic Operations
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| ilogbl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| ilogf128 | |check| | |check| | | |check| | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| ldexp | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| ldexpf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
Expand All @@ -193,6 +195,14 @@ Basic Operations
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| ldexpf128 | |check| | |check| | | |check| | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| llogb | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| llogbf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| llogbl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| llogf128 | |check| | |check| | | |check| | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| llrint | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| llrintf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
Expand All @@ -211,6 +221,8 @@ Basic Operations
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| logbl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| logf128 | |check| | |check| | | |check| | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| lrint | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| lrintf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
Expand Down
2 changes: 1 addition & 1 deletion libc/docs/math/stdfix.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Fixed-point Arithmetics
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| round | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| sqrt | | | | | | | | | | | | |
| sqrt | |check| | | |check| | | |check| | | |check| | | |check| | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+

================== =========
Expand Down
14 changes: 14 additions & 0 deletions libc/fuzzing/stdio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,17 @@ add_libc_fuzzer(
libc.src.stdio.snprintf
libc.src.__support.FPUtil.fp_bits
)

if(LIBC_COMPILER_HAS_FIXED_POINT)
add_libc_fuzzer(
printf_fixed_conv_fuzz
NEED_MPFR
SRCS
printf_fixed_conv_fuzz.cpp
DEPENDS
libc.src.stdio.snprintf
libc.src.__support.fixed_point.fx_bits
COMPILE_OPTIONS
-ffixed-point # TODO: add -ffixed-point to fuzz tests automatically
)
endif()
133 changes: 133 additions & 0 deletions libc/fuzzing/stdio/printf_fixed_conv_fuzz.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
//===-- printf_fixed_conv_fuzz.cpp ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// Fuzzing test for llvm-libc printf %f/e/g/a implementations.
///
//===----------------------------------------------------------------------===//
#include "src/stdio/snprintf.h"

#include "include/llvm-libc-macros/stdfix-macros.h"
#include "src/__support/fixed_point/fx_bits.h"
#include "src/__support/fixed_point/fx_rep.h"

#include <stddef.h>
#include <stdint.h>

#include "utils/MPFRWrapper/mpfr_inc.h"

constexpr int MAX_SIZE = 10000;

inline bool simple_streq(char *first, char *second, int length) {
for (int i = 0; i < length; ++i)
if (first[i] != second[i])
return false;

return true;
}

inline int clamp(int num, int max) {
if (num > max)
return max;
if (num < -max)
return -max;
return num;
}

enum class TestResult {
Success,
BufferSizeFailed,
LengthsDiffer,
StringsNotEqual,
};

template <typename F>
inline TestResult test_vals(const char *fmt, uint64_t num, int prec,
int width) {
typename LIBC_NAMESPACE::fixed_point::FXRep<F>::StorageType raw_num = num;

auto raw_num_bits = LIBC_NAMESPACE::fixed_point::FXBits<F>(raw_num);

// This needs to be a float with enough bits of precision to hold the fixed
// point number.
static_assert(sizeof(long double) > sizeof(long accum));

// build a long double that is equivalent to the fixed point number.
long double ld_num =
static_cast<long double>(raw_num_bits.get_integral()) +
(static_cast<long double>(raw_num_bits.get_fraction()) /
static_cast<long double>(1ll << raw_num_bits.get_exponent()));

if (raw_num_bits.get_sign())
ld_num = -ld_num;

// Call snprintf on a nullptr to get the buffer size.
int buffer_size = LIBC_NAMESPACE::snprintf(nullptr, 0, fmt, width, prec, num);

if (buffer_size < 0)
return TestResult::BufferSizeFailed;

char *test_buff = new char[buffer_size + 1];
char *reference_buff = new char[buffer_size + 1];

int test_result = 0;
int reference_result = 0;

test_result = LIBC_NAMESPACE::snprintf(test_buff, buffer_size + 1, fmt, width,
prec, num);

// The fixed point format is defined to be %f equivalent.
reference_result = mpfr_snprintf(reference_buff, buffer_size + 1, "%*.*Lf",
width, prec, ld_num);

// All of these calls should return that they wrote the same amount.
if (test_result != reference_result || test_result != buffer_size)
return TestResult::LengthsDiffer;

if (!simple_streq(test_buff, reference_buff, buffer_size))
return TestResult::StringsNotEqual;

delete[] test_buff;
delete[] reference_buff;
return TestResult::Success;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// const uint8_t raw_data[] = {0x8d,0x43,0x40,0x0,0x0,0x0,};
// data = raw_data;
// size = sizeof(raw_data);
int prec = 0;
int width = 0;

LIBC_NAMESPACE::fixed_point::FXRep<long accum>::StorageType raw_num = 0;

// Copy as many bytes of data as will fit into num, prec, and with. Any extras
// are ignored.
for (size_t cur = 0; cur < size; ++cur) {
if (cur < sizeof(raw_num)) {
raw_num = (raw_num << 8) + data[cur];
} else if (cur < sizeof(raw_num) + sizeof(prec)) {
prec = (prec << 8) + data[cur];
} else if (cur < sizeof(raw_num) + sizeof(prec) + sizeof(width)) {
width = (width << 8) + data[cur];
}
}

width = clamp(width, MAX_SIZE);
prec = clamp(prec, MAX_SIZE);

TestResult result;
result = test_vals<long accum>("%*.*lk", raw_num, prec, width);
if (result != TestResult::Success)
__builtin_trap();

result = test_vals<unsigned long accum>("%*.*lK", raw_num, prec, width);
if (result != TestResult::Success)
__builtin_trap();

return 0;
}
2 changes: 2 additions & 0 deletions libc/include/llvm-libc-macros/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ add_macro_header(
math_macros
HDR
math-macros.h
DEPENDS
.limits_macros
)

add_macro_header(
Expand Down
11 changes: 8 additions & 3 deletions libc/include/llvm-libc-macros/math-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,28 @@
#ifndef __LLVM_LIBC_MACROS_MATH_MACROS_H
#define __LLVM_LIBC_MACROS_MATH_MACROS_H

#include "limits-macros.h"

#define MATH_ERRNO 1
#define MATH_ERREXCEPT 2

#define HUGE_VAL __builtin_huge_val()
#define INFINITY __builtin_inf()
#define NAN __builtin_nanf("")

#define FP_ILOGB0 (-__INT_MAX__ - 1)
#define FP_ILOGBNAN __INT_MAX__
#define FP_ILOGB0 (-INT_MAX - 1)
#define FP_ILOGBNAN INT_MAX

#define FP_LLOGB0 (-LONG_MAX - 1)
#define FP_LLOGBNAN LONG_MAX

#define isfinite(x) __builtin_isfinite(x)
#define isinf(x) __builtin_isinf(x)
#define isnan(x) __builtin_isnan(x)

#ifdef __FAST_MATH__
#define math_errhandling 0
#elif defined __NO_MATH_ERRNO__
#elif defined(__NO_MATH_ERRNO__)
#define math_errhandling (MATH_ERREXCEPT)
#else
#define math_errhandling (MATH_ERRNO | MATH_ERREXCEPT)
Expand Down
7 changes: 7 additions & 0 deletions libc/spec/stdc.td
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,12 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"ilogb", RetValSpec<IntType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"ilogbf", RetValSpec<IntType>, [ArgSpec<FloatType>]>,
FunctionSpec<"ilogbl", RetValSpec<IntType>, [ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"ilogbf128", RetValSpec<IntType>, [ArgSpec<Float128Type>], "LIBC_COMPILER_HAS_FLOAT128">,

FunctionSpec<"llogb", RetValSpec<LongType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"llogbf", RetValSpec<LongType>, [ArgSpec<FloatType>]>,
FunctionSpec<"llogbl", RetValSpec<LongType>, [ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"llogbf128", RetValSpec<LongType>, [ArgSpec<Float128Type>], "LIBC_COMPILER_HAS_FLOAT128">,

FunctionSpec<"ldexp", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>]>,
FunctionSpec<"ldexpf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>]>,
Expand All @@ -435,6 +441,7 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"logb", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"logbf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
FunctionSpec<"logbl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"logbf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>], "LIBC_COMPILER_HAS_FLOAT128">,

FunctionSpec<"modf", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoublePtr>]>,
FunctionSpec<"modff", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatPtr>]>,
Expand Down
8 changes: 8 additions & 0 deletions libc/spec/stdc_ext.td
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ def StdcExt : StandardSpec<"stdc_ext"> {
GuardedFunctionSpec<"rounduhk", RetValSpec<UnsignedShortAccumType>, [ArgSpec<UnsignedShortAccumType>, ArgSpec<IntType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"rounduk", RetValSpec<UnsignedAccumType>, [ArgSpec<UnsignedAccumType>, ArgSpec<IntType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"roundulk", RetValSpec<UnsignedLongAccumType>, [ArgSpec<UnsignedLongAccumType>, ArgSpec<IntType>], "LIBC_COMPILER_HAS_FIXED_POINT">,

GuardedFunctionSpec<"sqrtuhr", RetValSpec<UnsignedShortFractType>, [ArgSpec<UnsignedShortFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"sqrtur", RetValSpec<UnsignedFractType>, [ArgSpec<UnsignedFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"sqrtulr", RetValSpec<UnsignedLongFractType>, [ArgSpec<UnsignedLongFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,

GuardedFunctionSpec<"sqrtuhk", RetValSpec<UnsignedShortAccumType>, [ArgSpec<UnsignedShortAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"sqrtuk", RetValSpec<UnsignedAccumType>, [ArgSpec<UnsignedAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"sqrtulk", RetValSpec<UnsignedLongAccumType>, [ArgSpec<UnsignedLongAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
]
>;

Expand Down
86 changes: 56 additions & 30 deletions libc/src/__support/FPUtil/ManipulationFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,54 +71,80 @@ LIBC_INLINE T copysign(T x, T y) {
return xbits.get_val();
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE int ilogb(T x) {
// TODO: Raise appropriate floating point exceptions and set errno to the
// an appropriate error value wherever relevant.
FPBits<T> bits(x);
if (bits.is_zero()) {
return FP_ILOGB0;
} else if (bits.is_nan()) {
return FP_ILOGBNAN;
} else if (bits.is_inf()) {
return INT_MAX;
template <typename T> struct IntLogbConstants;

template <> struct IntLogbConstants<int> {
LIBC_INLINE_VAR static constexpr int FP_LOGB0 = FP_ILOGB0;
LIBC_INLINE_VAR static constexpr int FP_LOGBNAN = FP_ILOGBNAN;
LIBC_INLINE_VAR static constexpr int T_MAX = INT_MAX;
LIBC_INLINE_VAR static constexpr int T_MIN = INT_MIN;
};

template <> struct IntLogbConstants<long> {
LIBC_INLINE_VAR static constexpr long FP_LOGB0 = FP_ILOGB0;
LIBC_INLINE_VAR static constexpr long FP_LOGBNAN = FP_ILOGBNAN;
LIBC_INLINE_VAR static constexpr long T_MAX = LONG_MAX;
LIBC_INLINE_VAR static constexpr long T_MIN = LONG_MIN;
};

template <typename T, typename U>
LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<U>, T>
intlogb(U x) {
FPBits<U> bits(x);
if (LIBC_UNLIKELY(bits.is_zero() || bits.is_inf_or_nan())) {
set_errno_if_required(EDOM);
raise_except_if_required(FE_INVALID);

if (bits.is_zero())
return IntLogbConstants<T>::FP_LOGB0;
if (bits.is_nan())
return IntLogbConstants<T>::FP_LOGBNAN;
// bits is inf.
return IntLogbConstants<T>::T_MAX;
}

NormalFloat<T> normal(bits);
DyadicFloat<FPBits<U>::STORAGE_LEN> normal(bits.get_val());
int exponent = normal.get_unbiased_exponent();
// The C standard does not specify the return value when an exponent is
// out of int range. However, XSI conformance required that INT_MAX or
// INT_MIN are returned.
// NOTE: It is highly unlikely that exponent will be out of int range as
// the exponent is only 15 bits wide even for the 128-bit floating point
// format.
if (normal.exponent > INT_MAX)
return INT_MAX;
else if (normal.exponent < INT_MIN)
return INT_MIN;
else
return normal.exponent;
if (LIBC_UNLIKELY(exponent > IntLogbConstants<T>::T_MAX ||
exponent < IntLogbConstants<T>::T_MIN)) {
set_errno_if_required(ERANGE);
raise_except_if_required(FE_INVALID);
return exponent > 0 ? IntLogbConstants<T>::T_MAX
: IntLogbConstants<T>::T_MIN;
}

return static_cast<T>(exponent);
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T logb(T x) {
LIBC_INLINE constexpr T logb(T x) {
FPBits<T> bits(x);
if (bits.is_zero()) {
// TODO(Floating point exception): Raise div-by-zero exception.
// TODO(errno): POSIX requires setting errno to ERANGE.
return FPBits<T>::inf(Sign::NEG).get_val();
} else if (bits.is_nan()) {
return x;
} else if (bits.is_inf()) {
// Return positive infinity.
if (LIBC_UNLIKELY(bits.is_zero() || bits.is_inf_or_nan())) {
if (bits.is_nan())
return x;

raise_except_if_required(FE_DIVBYZERO);

if (bits.is_zero()) {
set_errno_if_required(ERANGE);
return FPBits<T>::inf(Sign::NEG).get_val();
}
// bits is inf.
return FPBits<T>::inf().get_val();
}

NormalFloat<T> normal(bits);
return static_cast<T>(normal.exponent);
DyadicFloat<FPBits<T>::STORAGE_LEN> normal(bits.get_val());
return static_cast<T>(normal.get_unbiased_exponent());
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T ldexp(T x, int exp) {
LIBC_INLINE constexpr T ldexp(T x, int exp) {
FPBits<T> bits(x);
if (LIBC_UNLIKELY((exp == 0) || bits.is_zero() || bits.is_inf_or_nan()))
return x;
Expand Down
5 changes: 5 additions & 0 deletions libc/src/__support/FPUtil/dyadic_float.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ template <size_t Bits> struct DyadicFloat {
return *this;
}

// Assume that it is already normalized. Output the unbiased exponent.
LIBC_INLINE constexpr int get_unbiased_exponent() const {
return exponent + (Bits - 1);
}

// Assume that it is already normalized.
// Output is rounded correctly with respect to the current rounding mode.
template <typename T,
Expand Down
13 changes: 13 additions & 0 deletions libc/src/__support/fixed_point/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,16 @@ add_header_library(
libc.src.__support.CPP.bit
libc.src.__support.math_extras
)

add_header_library(
sqrt
HDRS
sqrt.h
DEPENDS
.fx_rep
libc.include.llvm-libc-macros.stdfix_macros
libc.src.__support.macros.attributes
libc.src.__support.macros.optimization
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
)
129 changes: 129 additions & 0 deletions libc/src/__support/fixed_point/sqrt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
//===-- Calculate square root of fixed point numbers. -----*- 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_FIXEDPOINT_SQRT_H
#define LLVM_LIBC_SRC___SUPPORT_FIXEDPOINT_SQRT_H

#include "include/llvm-libc-macros/stdfix-macros.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY

#include "fx_rep.h"

#ifdef LIBC_COMPILER_HAS_FIXED_POINT

namespace LIBC_NAMESPACE::fixed_point {

namespace internal {

template <typename T> struct SqrtConfig;

template <> struct SqrtConfig<unsigned short fract> {
using Type = unsigned short fract;
static constexpr int EXTRA_STEPS = 0;
};

template <> struct SqrtConfig<unsigned fract> {
using Type = unsigned fract;
static constexpr int EXTRA_STEPS = 1;
};

template <> struct SqrtConfig<unsigned long fract> {
using Type = unsigned long fract;
static constexpr int EXTRA_STEPS = 2;
};

template <>
struct SqrtConfig<unsigned short accum> : SqrtConfig<unsigned fract> {};

template <>
struct SqrtConfig<unsigned accum> : SqrtConfig<unsigned long fract> {};

// TODO: unsigned long accum type is 64-bit, and will need 64-bit fract type.
// Probably we will use DyadicFloat<64> for intermediate computations instead.

// Linear approximation for the initial values, with errors bounded by:
// max(1.5 * 2^-11, eps)
// Generated with Sollya:
// > for i from 4 to 15 do {
// P = fpminimax(sqrt(x), 1, [|8, 8|], [i * 2^-4, (i + 1)*2^-4],
// fixed, absolute);
// print("{", coeff(P, 1), "uhr,", coeff(P, 0), "uhr},");
// };
static constexpr unsigned short fract SQRT_FIRST_APPROX[12][2] = {
{0x1.e8p-1uhr, 0x1.0cp-2uhr}, {0x1.bap-1uhr, 0x1.28p-2uhr},
{0x1.94p-1uhr, 0x1.44p-2uhr}, {0x1.74p-1uhr, 0x1.6p-2uhr},
{0x1.6p-1uhr, 0x1.74p-2uhr}, {0x1.4ep-1uhr, 0x1.88p-2uhr},
{0x1.3ep-1uhr, 0x1.9cp-2uhr}, {0x1.32p-1uhr, 0x1.acp-2uhr},
{0x1.22p-1uhr, 0x1.c4p-2uhr}, {0x1.18p-1uhr, 0x1.d4p-2uhr},
{0x1.08p-1uhr, 0x1.fp-2uhr}, {0x1.04p-1uhr, 0x1.f8p-2uhr},
};

} // namespace internal

template <typename T>
LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, T> sqrt(T x) {
using BitType = typename FXRep<T>::StorageType;
BitType x_bit = cpp::bit_cast<BitType>(x);

if (LIBC_UNLIKELY(x_bit == 0))
return FXRep<T>::ZERO();

int leading_zeros = cpp::countl_zero(x_bit);
constexpr int STORAGE_LENGTH = sizeof(BitType) * CHAR_BIT;
constexpr int EXP_ADJUSTMENT = STORAGE_LENGTH - FXRep<T>::FRACTION_LEN - 1;
// x_exp is the real exponent of the leading bit of x.
int x_exp = EXP_ADJUSTMENT - leading_zeros;
int shift = EXP_ADJUSTMENT - 1 - (x_exp & (~1));
// Normalize.
x_bit <<= shift;
using FracType = typename internal::SqrtConfig<T>::Type;
FracType x_frac = cpp::bit_cast<FracType>(x_bit);

// Use use Newton method to approximate sqrt(a):
// x_{n + 1} = 1/2 (x_n + a / x_n)
// For the initial values, we choose x_0

// Use the leading 4 bits to do look up for sqrt(x).
// After normalization, 0.25 <= x_frac < 1, so the leading 4 bits of x_frac
// are between 0b0100 and 0b1111. Hence the lookup table only needs 12
// entries, and we can get the index by subtracting the leading 4 bits of
// x_frac by 4 = 0b0100.
int index = (x_bit >> (STORAGE_LENGTH - 4)) - 4;
FracType a = static_cast<FracType>(internal::SQRT_FIRST_APPROX[index][0]);
FracType b = static_cast<FracType>(internal::SQRT_FIRST_APPROX[index][1]);

// Initial approximation step.
// Estimated error bounds: | r - sqrt(x_frac) | < max(1.5 * 2^-11, eps).
FracType r = a * x_frac + b;

// Further Newton-method iterations for square-root:
// x_{n + 1} = 0.5 * (x_n + a / x_n)
// We distribute and do the multiplication by 0.5 first to avoid overflow.
// TODO: Investigate the performance and accuracy of using division-free
// iterations from:
// Blanchard, J. D. and Chamberland, M., "Newton's Method Without Division",
// The American Mathematical Monthly (2023).
// https://chamberland.math.grinnell.edu/papers/newton.pdf
for (int i = 0; i < internal::SqrtConfig<T>::EXTRA_STEPS; ++i)
r = (r >> 1) + (x_frac >> 1) / r;

// Re-scaling
r >>= EXP_ADJUSTMENT - (x_exp >> 1);

// Return result.
return cpp::bit_cast<T>(r);
}

} // namespace LIBC_NAMESPACE::fixed_point

#endif // LIBC_COMPILER_HAS_FIXED_POINT

#endif // LLVM_LIBC_SRC___SUPPORT_FIXEDPOINT_SQRT_H
33 changes: 7 additions & 26 deletions libc/src/math/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
add_subdirectory(generic)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
add_subdirectory(${LIBC_TARGET_ARCHITECTURE})
elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
# TODO: We should split this into 'nvptx' and 'amdgpu' for the GPU build.
add_subdirectory(${LIBC_TARGET_OS})
endif()

function(add_math_entrypoint_object name)
# We prefer machine specific implementation if available. Hence we check
# that first and return early if we are able to add an alias target for the
# machine specific implementation.
get_fq_target_name("${LIBC_TARGET_ARCHITECTURE}.${name}" fq_machine_specific_target_name)
get_fq_target_name("${LIBC_TARGET_OS}.${name}" fq_os_specific_target_name)
if(TARGET ${fq_machine_specific_target_name})
add_entrypoint_object(
${name}
Expand All @@ -20,28 +16,6 @@ function(add_math_entrypoint_object name)
.${LIBC_TARGET_ARCHITECTURE}.${name}
)
return()
elseif(TARGET ${fq_os_specific_target_name})
add_entrypoint_object(
${name}
ALIAS
DEPENDS
.${LIBC_TARGET_OS}.${name}
)
return()
endif()

# The GPU optionally depends on vendor libraries. If we emitted one of these
# entrypoints it means the user requested it and we should use it instead.
get_fq_target_name("${LIBC_TARGET_OS}.vendor.${name}" fq_vendor_specific_target_name)
if(TARGET ${fq_vendor_specific_target_name})
add_entrypoint_object(
${name}
ALIAS
DEPENDS
.${LIBC_TARGET_OS}.vendor.${name}
VENDOR
)
return()
endif()

get_fq_target_name("generic.${name}" fq_generic_target_name)
Expand Down Expand Up @@ -157,6 +131,12 @@ add_math_entrypoint_object(hypotf)
add_math_entrypoint_object(ilogb)
add_math_entrypoint_object(ilogbf)
add_math_entrypoint_object(ilogbl)
add_math_entrypoint_object(ilogbf128)

add_math_entrypoint_object(llogb)
add_math_entrypoint_object(llogbf)
add_math_entrypoint_object(llogbl)
add_math_entrypoint_object(llogbf128)

add_math_entrypoint_object(ldexp)
add_math_entrypoint_object(ldexpf)
Expand All @@ -178,6 +158,7 @@ add_math_entrypoint_object(logf)
add_math_entrypoint_object(logb)
add_math_entrypoint_object(logbf)
add_math_entrypoint_object(logbl)
add_math_entrypoint_object(logbf128)

add_math_entrypoint_object(llrint)
add_math_entrypoint_object(llrintf)
Expand Down

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/acos.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU acos 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/acos.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, acos, (double x)) { return __ocml_acos_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/acosf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the acosf function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/acosf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, acosf, (float x)) { return __ocml_acos_f32(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/acosh.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU acosh 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/acosh.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, acosh, (double x)) { return __ocml_acosh_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/acoshf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the acoshf function for GPU ---------------------===//
//
// Part of the LLVM Project, under the Apache 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/acoshf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, acoshf, (float x)) { return __ocml_acosh_f32(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/asin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU asin 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/asin.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, asin, (double x)) { return __ocml_asin_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/asinf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the asinf function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/asinf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, asinf, (float x)) { return __ocml_asin_f32(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/asinh.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU asinh 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/asinh.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, asinh, (double x)) { return __ocml_asinh_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/asinhf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the asinhf function for GPU ---------------------===//
//
// Part of the LLVM Project, under the Apache 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/asinhf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, asinhf, (float x)) { return __ocml_asinh_f32(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/atan.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU atan 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/atan.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, atan, (double x)) { return __ocml_atan_f64(x); }

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/atan2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the GPU atan2 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/atan2.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, atan2, (double x, double y)) {
return __ocml_atan2_f64(x, y);
}

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/atan2f.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the GPU atan2f 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/atan2f.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, atan2f, (float x, float y)) {
return __ocml_atan2_f32(x, y);
}

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/atanf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the atanf function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/atanf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, atanf, (float x)) { return __ocml_atan_f32(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/atanh.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU atanh 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/atanh.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, atanh, (double x)) { return __ocml_atanh_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/atanhf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the atanhf function for GPU ---------------------===//
//
// Part of the LLVM Project, under the Apache 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/atanhf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, atanhf, (float x)) { return __ocml_atanh_f32(x); }

} // namespace LIBC_NAMESPACE
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/cos.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the cos function for GPU ------------------------===//
//
// Part of the LLVM Project, under the Apache 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/cos.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, cos, (double x)) { return __ocml_cos_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/cosf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the cosf function for GPU -----------------------===//
//
// Part of the LLVM Project, under the Apache 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/cosf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, cosf, (float x)) { return __ocml_cos_f32(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/cosh.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the cosh function for GPU -----------------------===//
//
// Part of the LLVM Project, under the Apache 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/cosh.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, cosh, (double x)) { return __ocml_cosh_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/coshf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the coshf function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/coshf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, coshf, (float x)) { return __ocml_cosh_f32(x); }

} // namespace LIBC_NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#ifndef LLVM_LIBC_SRC_MATH_GPU_AMDGPU_DECLARATIONS_H
#define LLVM_LIBC_SRC_MATH_GPU_AMDGPU_DECLARATIONS_H

#include "platform.h"

#include "src/__support/GPU/utils.h"

namespace LIBC_NAMESPACE {
Expand Down
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/erf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU erf 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/erf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, erf, (double x)) { return __ocml_erf_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/erff.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU erff 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/erff.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, erff, (float x)) { return __ocml_erf_f32(x); }

} // namespace LIBC_NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
#include "src/math/exp.h"
#include "src/__support/common.h"

#include "common.h"
#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, exp, (double x)) { return internal::exp(x); }
LLVM_LIBC_FUNCTION(double, exp, (double x)) { return __builtin_exp(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/exp10.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU exp10 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/exp10.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, exp10, (double x)) { return __ocml_exp10_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/exp10f.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the exp10f function for GPU ---------------------===//
//
// Part of the LLVM Project, under the Apache 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/exp10f.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, exp10f, (float x)) { return __ocml_exp10_f32(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/exp2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU exp2 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/exp2.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, exp2, (double x)) { return __ocml_exp2_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/exp2f.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the exp2f function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/exp2f.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, exp2f, (float x)) { return __ocml_exp2_f32(x); }

} // namespace LIBC_NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
#include "src/math/expf.h"
#include "src/__support/common.h"

#include "common.h"
#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, expf, (float x)) { return internal::expf(x); }
LLVM_LIBC_FUNCTION(float, expf, (float x)) { return __builtin_expf(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/expm1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU expm1 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/expm1.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, expm1, (double x)) { return __ocml_expm1_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/expm1f.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the expm1f function for GPU ---------------------===//
//
// Part of the LLVM Project, under the Apache 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/expm1f.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, expm1f, (float x)) { return __ocml_expm1_f32(x); }

} // namespace LIBC_NAMESPACE
File renamed without changes.
File renamed without changes.
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/fdim.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the fdim function for GPU -----------------------===//
//
// Part of the LLVM Project, under the Apache 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/fdim.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, fdim, (double x, double y)) {
return __ocml_fdim_f64(x, y);
}

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/fdimf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the fdimf function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/fdimf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, fdimf, (float x, float y)) {
return __ocml_fdim_f32(x, y);
}

} // namespace LIBC_NAMESPACE
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
25 changes: 25 additions & 0 deletions libc/src/math/amdgpu/fmax.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===-- Implementation of the fmax function for GPU -----------------------===//
//
// Part of the LLVM Project, under the Apache 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/fmax.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/macros/optimization.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, fmax, (double x, double y)) {
// FIXME: The builtin function does not correctly handle the +/-0.0 case.
if (LIBC_UNLIKELY(x == y))
return cpp::bit_cast<double>(cpp::bit_cast<uint64_t>(x) &
cpp::bit_cast<uint64_t>(y));
return __builtin_fmax(x, y);
}

} // namespace LIBC_NAMESPACE
25 changes: 25 additions & 0 deletions libc/src/math/amdgpu/fmaxf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===-- Implementation of the fmaxf function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/fmaxf.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/macros/optimization.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, fmaxf, (float x, float y)) {
// FIXME: The builtin function does not correctly handle the +/-0.0 case.
if (LIBC_UNLIKELY(x == y))
return cpp::bit_cast<float>(cpp::bit_cast<uint32_t>(x) &
cpp::bit_cast<uint32_t>(y));
return __builtin_fmaxf(x, y);
}

} // namespace LIBC_NAMESPACE
25 changes: 25 additions & 0 deletions libc/src/math/amdgpu/fmin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===-- Implementation of the fmin function for GPU -----------------------===//
//
// Part of the LLVM Project, under the Apache 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/fmin.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/macros/optimization.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, fmin, (double x, double y)) {
// FIXME: The builtin function does not correctly handle the +/-0.0 case.
if (LIBC_UNLIKELY(x == y))
return cpp::bit_cast<double>(cpp::bit_cast<uint64_t>(x) |
cpp::bit_cast<uint64_t>(y));
return __builtin_fmin(x, y);
}

} // namespace LIBC_NAMESPACE
25 changes: 25 additions & 0 deletions libc/src/math/amdgpu/fminf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===-- Implementation of the fminf function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/fminf.h"

#include "src/__support/CPP/bit.h"
#include "src/__support/common.h"
#include "src/__support/macros/optimization.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, fminf, (float x, float y)) {
// FIXME: The builtin function does not correctly handle the +/-0.0 case.
if (LIBC_UNLIKELY(x == y))
return cpp::bit_cast<float>(cpp::bit_cast<uint32_t>(x) |
cpp::bit_cast<uint32_t>(y));
return __builtin_fminf(x, y);
}

} // namespace LIBC_NAMESPACE
File renamed without changes.
File renamed without changes.
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/frexp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the frexp function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/frexp.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, frexp, (double x, int *p)) {
return __builtin_frexp(x, p);
}

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/frexpf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the frexpf function for GPU ---------------------===//
//
// Part of the LLVM Project, under the Apache 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/frexpf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, frexpf, (float x, int *p)) {
return __builtin_frexpf(x, p);
}

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/hypot.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the hypot function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/hypot.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, hypot, (double x, double y)) {
return __ocml_hypot_f64(x, y);
}

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/hypotf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the hypotf function for GPU ---------------------===//
//
// Part of the LLVM Project, under the Apache 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/hypotf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, hypotf, (float x, float y)) {
return __ocml_hypot_f32(x, y);
}

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/ilogb.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the ilogb function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/ilogb.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(int, ilogb, (double x)) { return __ocml_ilogb_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/ilogbf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the ilogbf function for GPU ---------------------===//
//
// Part of the LLVM Project, under the Apache 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/ilogbf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(int, ilogbf, (float x)) { return __ocml_ilogb_f32(x); }

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/ldexp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the ldexp function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/ldexp.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, ldexp, (double x, int y)) {
return __builtin_ldexp(x, y);
}

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/ldexpf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the ldexpf function for GPU ---------------------===//
//
// Part of the LLVM Project, under the Apache 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/ldexpf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, ldexpf, (float x, int y)) {
return __builtin_ldexpf(x, y);
}

} // namespace LIBC_NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
#include "src/math/llrint.h"
#include "src/__support/common.h"

#include "common.h"
#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(long long, llrint, (double x)) {
return internal::llrint(x);
return static_cast<long long>(__builtin_rint(x));
}

} // namespace LIBC_NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
#include "src/math/llrintf.h"
#include "src/__support/common.h"

#include "common.h"
#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(long long, llrintf, (float x)) {
return internal::llrintf(x);
return static_cast<long long>(__builtin_rintf(x));
}

} // namespace LIBC_NAMESPACE
File renamed without changes.
File renamed without changes.
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/log.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU log 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/log.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, log, (double x)) { return __ocml_log_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/log10.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU log10 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/log10.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, log10, (double x)) { return __ocml_log10_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/log10f.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU log10f 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/log10f.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, log10f, (float x)) { return __ocml_log10_f32(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/log1p.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU log1p 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/log1p.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, log1p, (double x)) { return __ocml_log1p_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/log1pf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU log1pf 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/log1pf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, log1pf, (float x)) { return __ocml_log1p_f32(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/log2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU log2 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/log2.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, log2, (double x)) { return __ocml_log2_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/log2f.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU log2f 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/log2f.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, log2f, (float x)) { return __ocml_log2_f32(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/logb.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU logb 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/logb.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, logb, (double x)) { return __ocml_logb_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/logbf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU logbf 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/logbf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, logbf, (float x)) { return __ocml_logb_f32(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/logf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU logf 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/logf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, logf, (float x)) { return __ocml_log_f32(x); }

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/lrint.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the lrint function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/lrint.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(long, lrint, (double x)) {
return static_cast<long>(__builtin_rint(x));
}

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/lrintf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the lrintf function for GPU ---------------------===//
//
// Part of the LLVM Project, under the Apache 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/lrintf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(long, lrintf, (float x)) {
return static_cast<long>(__builtin_rintf(x));
}

} // namespace LIBC_NAMESPACE
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/nextafter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the nextafter function for GPU ------------------===//
//
// Part of the LLVM Project, under the Apache 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/nextafter.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, nextafter, (double x, double y)) {
return __ocml_nextafter_f64(x, y);
}

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/nextafterf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the nextafterf function for GPU -----------------===//
//
// Part of the LLVM Project, under the Apache 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/nextafterf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, nextafterf, (float x, float y)) {
return __ocml_nextafter_f32(x, y);
}

} // namespace LIBC_NAMESPACE
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
#include "src/math/pow.h"
#include "src/__support/common.h"

#include "common.h"
#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, pow, (double x, double y)) {
return internal::pow(x, y);
return __ocml_pow_f64(x, y);
}

} // namespace LIBC_NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
#include "src/math/powf.h"
#include "src/__support/common.h"

#include "common.h"
#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) {
return internal::powf(x, y);
return __ocml_pow_f32(x, y);
}

} // namespace LIBC_NAMESPACE
File renamed without changes.
File renamed without changes.
23 changes: 23 additions & 0 deletions libc/src/math/amdgpu/remquo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===-- Implementation of the GPU remquo 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/remquo.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, remquo, (double x, double y, int *quo)) {
int tmp;
double r = __ocml_remquo_f64(x, y, (gpu::Private<int> *)&tmp);
*quo = tmp;
return r;
}

} // namespace LIBC_NAMESPACE
23 changes: 23 additions & 0 deletions libc/src/math/amdgpu/remquof.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===-- Implementation of the GPU remquof 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/remquof.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, remquof, (float x, float y, int *quo)) {
int tmp;
float r = __ocml_remquo_f32(x, y, (gpu::Private<int> *)&tmp);
*quo = tmp;
return r;
}

} // namespace LIBC_NAMESPACE
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/scalbn.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the GPU scalbn 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/scalbn.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, scalbn, (double x, int y)) {
return __builtin_amdgcn_ldexp(x, y);
}

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/scalbnf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the GPU scalbnf 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/scalbnf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, scalbnf, (float x, int y)) {
return __builtin_amdgcn_ldexpf(x, y);
}

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/sin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the sin function for GPU ------------------------===//
//
// Part of the LLVM Project, under the Apache 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/sin.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, sin, (double x)) { return __ocml_sin_f64(x); }

} // namespace LIBC_NAMESPACE
20 changes: 20 additions & 0 deletions libc/src/math/amdgpu/sincos.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of the sincos function for GPU ---------------------===//
//
// Part of the LLVM Project, under the Apache 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/sincos.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(void, sincos, (double x, double *sinptr, double *cosptr)) {
*sinptr = __ocml_sincos_f64(x, cosptr);
}

} // namespace LIBC_NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
#include "src/math/sincosf.h"
#include "src/__support/common.h"

#include "common.h"
#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(void, sincosf, (float x, float *sinptr, float *cosptr)) {
return internal::sincosf(x, sinptr, cosptr);
*sinptr = __ocml_sincos_f32(x, cosptr);
}

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/sinf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the sinf function for GPU -----------------------===//
//
// Part of the LLVM Project, under the Apache 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/sinf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, sinf, (float x)) { return __ocml_sin_f32(x); }

} // namespace LIBC_NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//===-- Implementation of the GPU sinh function ---------------------------===//
//===-- Implementation of the sinh function for GPU -----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
Expand All @@ -9,8 +9,10 @@
#include "src/math/sinh.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, sinh, (double x)) { return __builtin_sinh(x); }
LLVM_LIBC_FUNCTION(double, sinh, (double x)) { return __ocml_sinh_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/sinhf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the sinhf function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/sinhf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, sinhf, (float x)) { return __ocml_sinh_f32(x); }

} // namespace LIBC_NAMESPACE
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//===-- Implementation of the GPU tan function ----------------------------===//
//===-- Implementation of the tan function for GPU ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
Expand All @@ -9,8 +9,10 @@
#include "src/math/tan.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, tan, (double x)) { return __builtin_tan(x); }
LLVM_LIBC_FUNCTION(double, tan, (double x)) { return __ocml_tan_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/tanf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the tanf function for GPU -----------------------===//
//
// Part of the LLVM Project, under the Apache 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/tanf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, tanf, (float x)) { return __ocml_tan_f32(x); }

} // namespace LIBC_NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//===-- Implementation of the GPU tanh function ---------------------------===//
//===-- Implementation of the tanh function for GPU -----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
Expand All @@ -9,8 +9,10 @@
#include "src/math/tanh.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, tanh, (double x)) { return __builtin_tanh(x); }
LLVM_LIBC_FUNCTION(double, tanh, (double x)) { return __ocml_tanh_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/tanhf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the tanhf function for GPU ----------------------===//
//
// Part of the LLVM Project, under the Apache 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/tanhf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, tanhf, (float x)) { return __ocml_tanh_f32(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/tgamma.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU tgamma 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/tgamma.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(double, tgamma, (double x)) { return __ocml_tgamma_f64(x); }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/amdgpu/tgammaf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of the GPU tgammaf 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/tgammaf.h"
#include "src/__support/common.h"

#include "declarations.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, tgammaf, (float x)) { return __ocml_tgamma_f32(x); }

} // namespace LIBC_NAMESPACE
File renamed without changes.
File renamed without changes.
98 changes: 86 additions & 12 deletions libc/src/math/generic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -969,10 +969,10 @@ add_entrypoint_object(
ilogb.cpp
HDRS
../ilogb.h
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
COMPILE_OPTIONS
-O2
)

add_entrypoint_object(
Expand All @@ -981,10 +981,10 @@ add_entrypoint_object(
ilogbf.cpp
HDRS
../ilogbf.h
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
COMPILE_OPTIONS
-O2
)

add_entrypoint_object(
Expand All @@ -993,10 +993,72 @@ add_entrypoint_object(
ilogbl.cpp
HDRS
../ilogbl.h
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
ilogbf128
SRCS
ilogbf128.cpp
HDRS
../ilogbf128.h
COMPILE_OPTIONS
-O2
-O3
DEPENDS
libc.src.__support.macros.properties.float
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
llogb
SRCS
llogb.cpp
HDRS
../llogb.h
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
llogbf
SRCS
llogbf.cpp
HDRS
../llogbf.h
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
llogbl
SRCS
llogbl.cpp
HDRS
../llogbl.h
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
llogbf128
SRCS
llogbf128.cpp
HDRS
../llogbf128.h
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.macros.properties.float
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
Expand Down Expand Up @@ -1044,8 +1106,8 @@ add_entrypoint_object(
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.macros.properties.float
libc.src.__support.FPUtil.manipulation_functions
libc.src.__support.macros.properties.float
libc.src.__support.FPUtil.manipulation_functions
)

add_object_library(
Expand Down Expand Up @@ -1229,10 +1291,10 @@ add_entrypoint_object(
logb.cpp
HDRS
../logb.h
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
COMPILE_OPTIONS
-O2
)

add_entrypoint_object(
Expand All @@ -1241,10 +1303,10 @@ add_entrypoint_object(
logbf.cpp
HDRS
../logbf.h
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
COMPILE_OPTIONS
-O2
)

add_entrypoint_object(
Expand All @@ -1253,10 +1315,22 @@ add_entrypoint_object(
logbl.cpp
HDRS
../logbl.h
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
logbf128
SRCS
logbf128.cpp
HDRS
../logbf128.h
COMPILE_OPTIONS
-O2
-O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/ilogb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(int, ilogb, (double x)) { return fputil::ilogb(x); }
LLVM_LIBC_FUNCTION(int, ilogb, (double x)) { return fputil::intlogb<int>(x); }

} // namespace LIBC_NAMESPACE
2 changes: 1 addition & 1 deletion libc/src/math/generic/ilogbf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(int, ilogbf, (float x)) { return fputil::ilogb(x); }
LLVM_LIBC_FUNCTION(int, ilogbf, (float x)) { return fputil::intlogb<int>(x); }

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/ilogbf128.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of ilogbf128 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/ilogbf128.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(int, ilogbf128, (float128 x)) {
return fputil::intlogb<int>(x);
}

} // namespace LIBC_NAMESPACE
4 changes: 3 additions & 1 deletion libc/src/math/generic/ilogbl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(int, ilogbl, (long double x)) { return fputil::ilogb(x); }
LLVM_LIBC_FUNCTION(int, ilogbl, (long double x)) {
return fputil::intlogb<int>(x);
}

} // namespace LIBC_NAMESPACE
17 changes: 17 additions & 0 deletions libc/src/math/generic/llogb.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//===-- Implementation of llogb 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/llogb.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(long, llogb, (double x)) { return fputil::intlogb<long>(x); }

} // namespace LIBC_NAMESPACE
17 changes: 17 additions & 0 deletions libc/src/math/generic/llogbf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//===-- Implementation of llogbf 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/llogbf.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(long, llogbf, (float x)) { return fputil::intlogb<long>(x); }

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/llogbf128.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of llogbf128 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/llogbf128.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(long, llogbf128, (float128 x)) {
return fputil::intlogb<long>(x);
}

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/llogbl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of llogbl 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/llogbl.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(long, llogbl, (long double x)) {
return fputil::intlogb<long>(x);
}

} // namespace LIBC_NAMESPACE
2 changes: 1 addition & 1 deletion libc/src/math/generic/logbf.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//===-- Implementation of logbf function ---------------------------------===//
//===-- Implementation of logbf function ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
Expand Down
Loading