Skip to content

[libc][stdfix] Implement fixed point countlsfx functions in llvm-libc #125356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions libc/config/baremetal/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.ukbits
libc.src.stdfix.lkbits
libc.src.stdfix.ulkbits
libc.src.stdfix.countlshr
libc.src.stdfix.countlsr
libc.src.stdfix.countlslr
libc.src.stdfix.countlshk
libc.src.stdfix.countlsk
libc.src.stdfix.countlslk
libc.src.stdfix.countlsuhr
libc.src.stdfix.countlsur
libc.src.stdfix.countlsulr
libc.src.stdfix.countlsuhk
libc.src.stdfix.countlsuk
libc.src.stdfix.countlsulk
)
endif()

Expand Down
12 changes: 12 additions & 0 deletions libc/config/baremetal/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.ukbits
libc.src.stdfix.lkbits
libc.src.stdfix.ulkbits
libc.src.stdfix.countlshr
libc.src.stdfix.countlsr
libc.src.stdfix.countlslr
libc.src.stdfix.countlshk
libc.src.stdfix.countlsk
libc.src.stdfix.countlslk
libc.src.stdfix.countlsuhr
libc.src.stdfix.countlsur
libc.src.stdfix.countlsulr
libc.src.stdfix.countlsuhk
libc.src.stdfix.countlsuk
libc.src.stdfix.countlsulk
)
endif()

Expand Down
12 changes: 12 additions & 0 deletions libc/config/linux/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
# TODO: https://github.com/llvm/llvm-project/issues/115778
libc.src.stdfix.lkbits
libc.src.stdfix.ulkbits
libc.src.stdfix.countlshr
libc.src.stdfix.countlsr
libc.src.stdfix.countlslr
libc.src.stdfix.countlshk
libc.src.stdfix.countlsk
libc.src.stdfix.countlslk
libc.src.stdfix.countlsuhr
libc.src.stdfix.countlsur
libc.src.stdfix.countlsulr
libc.src.stdfix.countlsuhk
libc.src.stdfix.countlsuk
libc.src.stdfix.countlsulk
)
endif()

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 @@ -874,6 +874,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.ukbits
libc.src.stdfix.lkbits
libc.src.stdfix.ulkbits
libc.src.stdfix.countlshr
libc.src.stdfix.countlsr
libc.src.stdfix.countlslr
libc.src.stdfix.countlshk
libc.src.stdfix.countlsk
libc.src.stdfix.countlslk
libc.src.stdfix.countlsuhr
libc.src.stdfix.countlsur
libc.src.stdfix.countlsulr
libc.src.stdfix.countlsuhk
libc.src.stdfix.countlsuk
libc.src.stdfix.countlsulk
)
endif()

Expand Down
2 changes: 1 addition & 1 deletion libc/docs/headers/math/stdfix.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ The following functions are included in the ISO/IEC TR 18037:2008 standard.
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| \*bits | | | | | | | | | | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| countls | | | | | | | | | | | | |
| countls | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| divi | | | | | | | | | | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
Expand Down
84 changes: 84 additions & 0 deletions libc/include/stdfix.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,87 @@ functions:
arguments:
- type: unsigned int
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: countlshr
standards:
- stdc_ext
return_type: int
arguments:
- type: short fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: countlsr
standards:
- stdc_ext
return_type: int
arguments:
- type: fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: countlslr
standards:
- stdc_ext
return_type: int
arguments:
- type: long fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: countlshk
standards:
- stdc_ext
return_type: int
arguments:
- type: short accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: countlsk
standards:
- stdc_ext
return_type: int
arguments:
- type: accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: countlslk
standards:
- stdc_ext
return_type: int
arguments:
- type: long accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: countlsuhr
standards:
- stdc_ext
return_type: int
arguments:
- type: unsigned short fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: countlsur
standards:
- stdc_ext
return_type: int
arguments:
- type: unsigned fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: countlsulr
standards:
- stdc_ext
return_type: int
arguments:
- type: unsigned long fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: countlsuhk
standards:
- stdc_ext
return_type: int
arguments:
- type: unsigned short accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: countlsuk
standards:
- stdc_ext
return_type: int
arguments:
- type: unsigned accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: countlsulk
standards:
- stdc_ext
return_type: int
arguments:
- type: unsigned long accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
1 change: 1 addition & 0 deletions libc/src/__support/fixed_point/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ add_header_library(
libc.src.__support.macros.optimization
libc.src.__support.CPP.type_traits
libc.src.__support.CPP.bit
libc.src.__support.CPP.limits
libc.src.__support.math_extras
)

Expand Down
37 changes: 35 additions & 2 deletions libc/src/__support/fixed_point/fx_bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@

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

Expand Down Expand Up @@ -50,6 +51,12 @@ template <typename T> struct FXBits {
static constexpr StorageType SIGN_MASK =
(fx_rep::SIGN_LEN == 0 ? 0 : StorageType(1) << SIGN_OFFSET);

// mask for <integral | fraction>
static constexpr StorageType VALUE_MASK = INTEGRAL_MASK | FRACTION_MASK;

// mask for <sign | integral | fraction>
static constexpr StorageType TOTAL_MASK = SIGN_MASK | VALUE_MASK;

public:
LIBC_INLINE constexpr FXBits() = default;

Expand All @@ -74,6 +81,12 @@ template <typename T> struct FXBits {
return (value & INTEGRAL_MASK) >> INTEGRAL_OFFSET;
}

// returns complete bitstring representation the fixed point number
// the bitstring is of the form: padding | sign | integral | fraction
LIBC_INLINE constexpr StorageType get_bits() {
return (value & TOTAL_MASK) >> FRACTION_OFFSET;
}

// TODO: replace bool with Sign
LIBC_INLINE constexpr bool get_sign() {
return static_cast<bool>((value & SIGN_MASK) >> SIGN_OFFSET);
Expand Down Expand Up @@ -163,6 +176,26 @@ template <typename T> LIBC_INLINE constexpr T round(T x, int n) {
return bit_and((x + round_bit), rounding_mask);
}

// count leading sign bits
template <typename T>
LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, int>
countls(T f) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

libc/src/__support/fixed_point/fx_bits.h:182:11: error: unused parameter 'f' [-Werror,-Wunused-parameter]
  182 | countls(T f) {
      |           ^

guessing x below was supposed to be f?

using FXRep = FXRep<T>;
using BitType = typename FXRep::StorageType;
using FXBits = FXBits<T>;

constexpr int CONTAIN_LEN = cpp::numeric_limits<BitType>::digits;
constexpr int PADDING_LEN = CONTAIN_LEN - FXRep::TOTAL_LEN;

if constexpr (FXRep::SIGN_LEN != 0) {
if (x < 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the buildbot failures:

libc/src/__support/fixed_point/fx_bits.h:191:9: error: use of undeclared identifier 'x'
  191 |     if (x < 0)
      |         ^

x = bit_not(x);
}

BitType value_bits = FXBits(x)::get_bits();
return cpp::countl_zero(value_bits) - PADDING_LEN;
}

} // namespace fixed_point
} // namespace LIBC_NAMESPACE_DECL

Expand Down
12 changes: 12 additions & 0 deletions libc/src/stdfix/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,18 @@ foreach(suffix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
libc.src.__support.CPP.bit
libc.src.__support.fixed_point.fx_bits
)

add_entrypoint_object(
countls${suffix}
HDRS
countls${suffix}.h
SRCS
countls${suffix}.cpp
COMPILE_OPTIONS
${libc_opt_high_flag}
DEPENDS
libc.src.__support.fixed_point.fx_bits
)
endforeach()

add_entrypoint_object(
Expand Down
20 changes: 20 additions & 0 deletions libc/src/stdfix/countlshk.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation for countlshk 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 "countlshk.h"
#include "src/__support/common.h"
#include "src/__support/fixed_point/fx_bits.h"
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, countlshk, (short accum f)) {
return fixed_point::countls(f);
}

} // namespace LIBC_NAMESPACE_DECL
21 changes: 21 additions & 0 deletions libc/src/stdfix/countlshk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation header for countlshk function ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_STDFIX_COUNTLSHK_H
#define LLVM_LIBC_SRC_STDFIX_COUNTLSHK_H

#include "include/llvm-libc-macros/stdfix-macros.h"
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

int countlshk(short accum f);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_STDFIX_COUNTLSHK_H
20 changes: 20 additions & 0 deletions libc/src/stdfix/countlshr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation for countlshr 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 "countlshr.h"
#include "src/__support/common.h"
#include "src/__support/fixed_point/fx_bits.h"
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, countlshr, (short fract f)) {
return fixed_point::countls(f);
}

} // namespace LIBC_NAMESPACE_DECL
21 changes: 21 additions & 0 deletions libc/src/stdfix/countlshr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation header for countlshr function ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_STDFIX_COUNTLSHR_H
#define LLVM_LIBC_SRC_STDFIX_COUNTLSHR_H

#include "include/llvm-libc-macros/stdfix-macros.h"
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

int countlshr(short fract f);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_STDFIX_COUNTLSHR_H
18 changes: 18 additions & 0 deletions libc/src/stdfix/countlsk.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation for countlsk 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 "countlsk.h"
#include "src/__support/common.h"
#include "src/__support/fixed_point/fx_bits.h"
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, countlsk, (accum f)) { return fixed_point::countls(f); }

} // namespace LIBC_NAMESPACE_DECL
21 changes: 21 additions & 0 deletions libc/src/stdfix/countlsk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation header for countlsk function -------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_STDFIX_COUNTLSK_H
#define LLVM_LIBC_SRC_STDFIX_COUNTLSK_H

#include "include/llvm-libc-macros/stdfix-macros.h"
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

int countlsk(accum f);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_STDFIX_COUNTLSK_H
Loading