Skip to content

Commit

Permalink
[libc][stdfix] Implement countlsfx functions in libc. (llvm#126597)
Browse files Browse the repository at this point in the history
fixes llvm#113357

---------

Signed-off-by: krishna2803 <[email protected]>
  • Loading branch information
krishna2803 authored and joaosaffran committed Feb 14, 2025
1 parent c3d6359 commit f897c75
Show file tree
Hide file tree
Showing 48 changed files with 919 additions and 27 deletions.
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 @@ -875,6 +875,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
35 changes: 33 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,24 @@ template <typename T> LIBC_INLINE constexpr T round(T x, int n) {
return bit_and((x + round_bit), rounding_mask);
}

// count leading sign bits
// TODO: support fixed_point_padding
template <typename T>
LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, int>
countls(T f) {
using FXRep = FXRep<T>;
using BitType = typename FXRep::StorageType;
using FXBits = FXBits<T>;

if constexpr (FXRep::SIGN_LEN > 0) {
if (f < 0)
f = bit_not(f);
}

BitType value_bits = FXBits(f).get_bits();
return cpp::countl_zero(value_bits) - FXRep::SIGN_LEN;
}

} // namespace fixed_point
} // namespace LIBC_NAMESPACE_DECL

Expand Down
48 changes: 24 additions & 24 deletions libc/src/__support/fixed_point/fx_rep.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ template <> struct FXRep<short fract> {
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SFRACT_FBIT;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;

LIBC_INLINE static constexpr Type MIN() { return SFRACT_MIN; }
LIBC_INLINE static constexpr Type MAX() { return SFRACT_MAX; }
Expand All @@ -63,8 +63,8 @@ template <> struct FXRep<unsigned short fract> {
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = USFRACT_FBIT;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;

LIBC_INLINE static constexpr Type MIN() { return USFRACT_MIN; }
LIBC_INLINE static constexpr Type MAX() { return USFRACT_MAX; }
Expand All @@ -83,8 +83,8 @@ template <> struct FXRep<fract> {
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = FRACT_FBIT;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;

LIBC_INLINE static constexpr Type MIN() { return FRACT_MIN; }
LIBC_INLINE static constexpr Type MAX() { return FRACT_MAX; }
Expand All @@ -103,8 +103,8 @@ template <> struct FXRep<unsigned fract> {
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = UFRACT_FBIT;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;

LIBC_INLINE static constexpr Type MIN() { return UFRACT_MIN; }
LIBC_INLINE static constexpr Type MAX() { return UFRACT_MAX; }
Expand All @@ -123,8 +123,8 @@ template <> struct FXRep<long fract> {
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = LFRACT_FBIT;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;

LIBC_INLINE static constexpr Type MIN() { return LFRACT_MIN; }
LIBC_INLINE static constexpr Type MAX() { return LFRACT_MAX; }
Expand All @@ -143,8 +143,8 @@ template <> struct FXRep<unsigned long fract> {
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ULFRACT_FBIT;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;

LIBC_INLINE static constexpr Type MIN() { return ULFRACT_MIN; }
LIBC_INLINE static constexpr Type MAX() { return ULFRACT_MAX; }
Expand All @@ -163,8 +163,8 @@ template <> struct FXRep<short accum> {
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = SACCUM_IBIT;
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SACCUM_FBIT;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;

LIBC_INLINE static constexpr Type MIN() { return SACCUM_MIN; }
LIBC_INLINE static constexpr Type MAX() { return SACCUM_MAX; }
Expand All @@ -183,8 +183,8 @@ template <> struct FXRep<unsigned short accum> {
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = USACCUM_IBIT;
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = USACCUM_FBIT;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;

LIBC_INLINE static constexpr Type MIN() { return USACCUM_MIN; }
LIBC_INLINE static constexpr Type MAX() { return USACCUM_MAX; }
Expand All @@ -203,8 +203,8 @@ template <> struct FXRep<accum> {
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ACCUM_IBIT;
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ACCUM_FBIT;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;

LIBC_INLINE static constexpr Type MIN() { return ACCUM_MIN; }
LIBC_INLINE static constexpr Type MAX() { return ACCUM_MAX; }
Expand All @@ -223,8 +223,8 @@ template <> struct FXRep<unsigned accum> {
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = UACCUM_IBIT;
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = UACCUM_FBIT;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;

LIBC_INLINE static constexpr Type MIN() { return UACCUM_MIN; }
LIBC_INLINE static constexpr Type MAX() { return UACCUM_MAX; }
Expand All @@ -243,8 +243,8 @@ template <> struct FXRep<long accum> {
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = LACCUM_IBIT;
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = LACCUM_FBIT;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;

LIBC_INLINE static constexpr Type MIN() { return LACCUM_MIN; }
LIBC_INLINE static constexpr Type MAX() { return LACCUM_MAX; }
Expand All @@ -263,8 +263,8 @@ template <> struct FXRep<unsigned long accum> {
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ULACCUM_IBIT;
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ULACCUM_FBIT;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;

LIBC_INLINE static constexpr Type MIN() { return ULACCUM_MIN; }
LIBC_INLINE static constexpr Type MAX() { return ULACCUM_MAX; }
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 @@ -47,6 +47,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
Loading

0 comments on commit f897c75

Please sign in to comment.