77 changes: 77 additions & 0 deletions libc/src/__support/bit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//===-- Mimics llvm/ADT/Bit.h -----------------------------------*- C++ -*-===//
// Provides useful bit functions.
//
// Part of the LLVM Project, under the Apache 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_BIT_H
#define LLVM_LIBC_SRC___SUPPORT_BIT_H

#include "src/__support/macros/attributes.h" // LIBC_INLINE

namespace LIBC_NAMESPACE {

// The following overloads are matched based on what is accepted by
// __builtin_clz/ctz* rather than using the exactly-sized aliases from stdint.h.
// This way, we can avoid making any assumptions about integer sizes and let the
// compiler match for us.
namespace __internal {

template <typename T> LIBC_INLINE int constexpr correct_zero(T val, int bits) {
if (val == T(0))
return sizeof(T(0)) * 8;
else
return bits;
}

template <typename T> LIBC_INLINE constexpr int clz(T val);
template <> LIBC_INLINE int clz<unsigned int>(unsigned int val) {
return __builtin_clz(val);
}
template <>
LIBC_INLINE constexpr int clz<unsigned long int>(unsigned long int val) {
return __builtin_clzl(val);
}
template <>
LIBC_INLINE constexpr int
clz<unsigned long long int>(unsigned long long int val) {
return __builtin_clzll(val);
}

template <typename T> LIBC_INLINE constexpr int ctz(T val);
template <> LIBC_INLINE int ctz<unsigned int>(unsigned int val) {
return __builtin_ctz(val);
}
template <>
LIBC_INLINE constexpr int ctz<unsigned long int>(unsigned long int val) {
return __builtin_ctzl(val);
}
template <>
LIBC_INLINE constexpr int
ctz<unsigned long long int>(unsigned long long int val) {
return __builtin_ctzll(val);
}
} // namespace __internal

template <typename T> LIBC_INLINE constexpr int safe_ctz(T val) {
return __internal::correct_zero(val, __internal::ctz(val));
}

template <typename T> LIBC_INLINE constexpr int unsafe_ctz(T val) {
return __internal::ctz(val);
}

template <typename T> LIBC_INLINE constexpr int safe_clz(T val) {
return __internal::correct_zero(val, __internal::clz(val));
}

template <typename T> LIBC_INLINE constexpr int unsafe_clz(T val) {
return __internal::clz(val);
}

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC___SUPPORT_BIT_H
2 changes: 1 addition & 1 deletion libc/src/__support/integer_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/common.h"

#include "builtin_wrappers.h"
#include "bit.h"
#include "number_pair.h"

#include <stdint.h>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
//===--Convenient template for builtins -------------------------*- C++ -*-===//
// (Count Lead Zeroes) and (Count Trailing Zeros)
//===-- Mimics llvm/Support/MathExtras.h ------------------------*- C++ -*-===//
// Provides useful math functions.
//
// Part of the LLVM Project, under the Apache 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_BUILTIN_WRAPPERS_H
#define LLVM_LIBC_SRC___SUPPORT_BUILTIN_WRAPPERS_H
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXTRAS_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_EXTRAS_H

#include "named_pair.h"
#include "src/__support/CPP/type_traits.h"
Expand All @@ -17,64 +17,6 @@

namespace LIBC_NAMESPACE {

// The following overloads are matched based on what is accepted by
// __builtin_clz/ctz* rather than using the exactly-sized aliases from stdint.h.
// This way, we can avoid making any assumptions about integer sizes and let the
// compiler match for us.
namespace __internal {

template <typename T> LIBC_INLINE int constexpr correct_zero(T val, int bits) {
if (val == T(0))
return sizeof(T(0)) * 8;
else
return bits;
}

template <typename T> LIBC_INLINE constexpr int clz(T val);
template <> LIBC_INLINE int clz<unsigned int>(unsigned int val) {
return __builtin_clz(val);
}
template <>
LIBC_INLINE constexpr int clz<unsigned long int>(unsigned long int val) {
return __builtin_clzl(val);
}
template <>
LIBC_INLINE constexpr int
clz<unsigned long long int>(unsigned long long int val) {
return __builtin_clzll(val);
}

template <typename T> LIBC_INLINE constexpr int ctz(T val);
template <> LIBC_INLINE int ctz<unsigned int>(unsigned int val) {
return __builtin_ctz(val);
}
template <>
LIBC_INLINE constexpr int ctz<unsigned long int>(unsigned long int val) {
return __builtin_ctzl(val);
}
template <>
LIBC_INLINE constexpr int
ctz<unsigned long long int>(unsigned long long int val) {
return __builtin_ctzll(val);
}
} // namespace __internal

template <typename T> LIBC_INLINE constexpr int safe_ctz(T val) {
return __internal::correct_zero(val, __internal::ctz(val));
}

template <typename T> LIBC_INLINE constexpr int unsafe_ctz(T val) {
return __internal::ctz(val);
}

template <typename T> LIBC_INLINE constexpr int safe_clz(T val) {
return __internal::correct_zero(val, __internal::clz(val));
}

template <typename T> LIBC_INLINE constexpr int unsafe_clz(T val) {
return __internal::clz(val);
}

// Add with carry
DEFINE_NAMED_PAIR_TEMPLATE(SumCarry, sum, carry);

Expand Down Expand Up @@ -223,4 +165,4 @@ sub_with_borrow<unsigned long long>(unsigned long long a, unsigned long long b,

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC___SUPPORT_BUILTIN_WRAPPERS_H
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXTRAS_H
2 changes: 1 addition & 1 deletion libc/src/__support/str_to_float.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/UInt128.h"
#include "src/__support/builtin_wrappers.h"
#include "src/__support/bit.h"
#include "src/__support/common.h"
#include "src/__support/ctype_utils.h"
#include "src/__support/detailed_powers_of_ten.h"
Expand Down
10 changes: 5 additions & 5 deletions libc/src/math/generic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -775,10 +775,12 @@ add_entrypoint_object(
../powf.h
DEPENDS
.common_constants
.explogxf
.exp2f_impl
.exp10f_impl
libc.src.__support.builtin_wrappers
.exp2f_impl
.explogxf
libc.include.errno
libc.include.math
libc.src.__support.bit
libc.src.__support.CPP.bit
libc.src.__support.CPP.optional
libc.src.__support.FPUtil.fenv_impl
Expand All @@ -790,9 +792,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.sqrt
libc.src.__support.FPUtil.triple_double
libc.src.__support.macros.optimization
libc.include.errno
libc.src.errno.errno
libc.include.math
COMPILE_OPTIONS
-O3
)
Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/powf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include "src/__support/FPUtil/nearest_integer.h"
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/FPUtil/sqrt.h" // Speedup for powf(x, 1/2) = sqrtf(x)
#include "src/__support/builtin_wrappers.h"
#include "src/__support/bit.h"
#include "src/__support/common.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY

Expand Down
23 changes: 23 additions & 0 deletions libc/test/src/__support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,29 @@ add_libc_test(
libc.src.__support.common
)


add_libc_test(
bit_test
SUITE
libc-support-tests
SRCS
bit_test.cpp
DEPENDS
libc.src.__support.bit
)


add_libc_test(
math_extras_test
SUITE
libc-support-tests
SRCS
math_extras_test.cpp
DEPENDS
libc.src.__support.math_extras
)


add_libc_test(
high_precision_decimal_test
SUITE
Expand Down
18 changes: 18 additions & 0 deletions libc/test/src/__support/bit_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Unittests for BlockStore ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/__support/bit.h"
#include "test/UnitTest/Test.h"

namespace LIBC_NAMESPACE {

TEST(LlvmLibcBlockBitTest, TODO) {
// TODO Implement me.
}

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/test/src/__support/math_extras_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Unittests for math_extras -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/__support/math_extras.h"
#include "test/UnitTest/Test.h"

namespace LIBC_NAMESPACE {

TEST(LlvmLibcBlockMathExtrasTest, TODO) {
// TODO Implement me.
}

} // namespace LIBC_NAMESPACE
29 changes: 19 additions & 10 deletions utils/bazel/llvm-project-overlay/libc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ libc_support_library(
name = "__support_integer_utils",
hdrs = ["src/__support/integer_utils.h"],
deps = [
":__support_builtin_wrappers",
":__support_bit",
":__support_common",
":__support_cpp_type_traits",
":__support_number_pair",
Expand All @@ -430,14 +430,15 @@ libc_support_library(
name = "__support_uint",
hdrs = ["src/__support/UInt.h"],
deps = [
":__support_builtin_wrappers",
":__support_bit",
":__support_cpp_array",
":__support_cpp_limits",
":__support_cpp_optional",
":__support_cpp_type_traits",
":__support_integer_utils",
":__support_macros_attributes",
":__support_macros_optimization",
":__support_math_extras",
":__support_number_pair",
],
)
Expand Down Expand Up @@ -516,7 +517,7 @@ libc_support_library(
"src/__support/str_to_float.h",
],
deps = [
":__support_builtin_wrappers",
":__support_bit",
":__support_common",
":__support_cpp_limits",
":__support_cpp_optional",
Expand Down Expand Up @@ -572,8 +573,16 @@ libc_support_library(
)

libc_support_library(
name = "__support_builtin_wrappers",
hdrs = ["src/__support/builtin_wrappers.h"],
name = "__support_bit",
hdrs = ["src/__support/bit.h"],
deps = [
":__support_macros_attributes",
],
)

libc_support_library(
name = "__support_math_extras",
hdrs = ["src/__support/math_extras.h"],
deps = [
":__support_cpp_type_traits",
":__support_macros_attributes",
Expand All @@ -586,7 +595,7 @@ libc_support_library(
name = "__support_fputil_generic_fmod",
hdrs = ["src/__support/FPUtil/generic/FMod.h"],
deps = [
":__support_builtin_wrappers",
":__support_bit",
":__support_common",
":__support_cpp_limits",
":__support_cpp_type_traits",
Expand Down Expand Up @@ -658,7 +667,7 @@ libc_support_library(
hdrs = ["src/__support/FPUtil/FPBits.h"],
textual_hdrs = ["src/__support/FPUtil/x86_64/LongDoubleBits.h"],
deps = [
":__support_builtin_wrappers",
":__support_bit",
":__support_common",
":__support_cpp_bit",
":__support_cpp_type_traits",
Expand Down Expand Up @@ -687,7 +696,7 @@ libc_support_library(
name = "__support_fputil_hypot",
hdrs = ["src/__support/FPUtil/Hypot.h"],
deps = [
":__support_builtin_wrappers",
":__support_bit",
":__support_common",
":__support_cpp_bit",
":__support_cpp_type_traits",
Expand Down Expand Up @@ -766,7 +775,7 @@ libc_support_library(
name = "__support_fputil_sqrt",
hdrs = sqrt_hdrs,
deps = [
":__support_builtin_wrappers",
":__support_bit",
":__support_common",
":__support_cpp_bit",
":__support_cpp_type_traits",
Expand Down Expand Up @@ -795,7 +804,7 @@ libc_support_library(
# doesn't support FMA, so they can't be compiled on their own.
textual_hdrs = fma_platform_hdrs,
deps = [
":__support_builtin_wrappers",
":__support_bit",
":__support_cpp_bit",
":__support_cpp_type_traits",
":__support_fputil_fenv_impl",
Expand Down
2 changes: 1 addition & 1 deletion utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def libc_math_function(
":__support_fputil_nearest_integer_operations",
":__support_fputil_normal_float",
":__support_fputil_platform_defs",
":__support_builtin_wrappers",
":__support_math_extras",
":__support_fputil_except_value_utils",
]
libc_function(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ package(default_visibility = ["//visibility:public"])

licenses(["notice"])

libc_test(
name = "bit_test",
srcs = ["bit_test.cpp"],
deps = ["//libc:__support_bit"],
)

libc_test(
name = "math_extras_test",
srcs = ["math_extras_test.cpp"],
deps = ["//libc:__support_math_extras"],
)

# This test is currently disabled because of an issue in
# `libc/src/__support/CPP/new.h` which currently fails with
# "error: cannot apply asm label to function after its first use"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ def math_test(name, hdrs = [], deps = [], **kwargs):
srcs = [test_name + ".cpp"] + hdrs,
libc_function_deps = ["//libc:func_name".replace("func_name", name)],
deps = [
"//libc:__support_builtin_wrappers",
"//libc:__support_bit",
"//libc:__support_fputil_basic_operations",
"//libc:__support_fputil_fenv_impl",
"//libc:__support_fputil_float_properties",
"//libc:__support_fputil_fp_bits",
"//libc:__support_fputil_manipulation_functions",
"//libc:__support_fputil_nearest_integer_operations",
"//libc:__support_fputil_normal_float",
"//libc:__support_math_extras",
"//libc:__support_uint128",
"//libc/test/UnitTest:fp_test_helpers",
] + deps,
Expand Down