Skip to content

[libc][stdfix] Implement countlsfx functions in libc. #126597

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 21 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
cbb321f
feat: implement template meta `countls`
krishna2803 Feb 1, 2025
cddf53e
chore: add `limits.h` header to CmakeLists.txt
krishna2803 Feb 1, 2025
bcccd52
add: `countlsfx` functions
krishna2803 Feb 1, 2025
647a16c
chore: add `padding_on_unsigned_fixed_point`
krishna2803 Feb 1, 2025
ca4d532
chore: add entrypoints
krishna2803 Feb 1, 2025
5c2894f
add: unit tests for `countlsfx` functions
krishna2803 Feb 1, 2025
519ae5d
chore: documentation update
krishna2803 Feb 1, 2025
e0acc36
chore: remove -Xclang flags and tests with padding
krishna2803 Feb 4, 2025
c31e539
nit: share loop for countlsfx and roundfx
krishna2803 Feb 4, 2025
9b499bc
fix: use `FXRep:TOTAL_LEN` to incoporate for `SIGN_LEN`
krishna2803 Feb 5, 2025
632a6d8
remove: `padding_on_unsigned_fixed_point.cpp`
krishna2803 Feb 5, 2025
475945d
chore: change `count leading zeros` to `count leading sign bits`
krishna2803 Feb 5, 2025
b146648
fix: ensure newline at end
krishna2803 Feb 5, 2025
659170d
style: clang-format
krishna2803 Feb 5, 2025
780fd3a
fix: buildbot failures
krishna2803 Feb 7, 2025
88e9b63
Merge branch 'main' into implement-countlsfx
krishna2803 Feb 10, 2025
c3c1c13
style: clang-format
krishna2803 Feb 10, 2025
ac10f17
Merge branch 'main' into implement-countlsfx
krishna2803 Feb 10, 2025
8790b2c
style: llvm coding standard
krishna2803 Feb 11, 2025
7a34ec1
chore: remove optimization options from maths functions (ref #126315)
krishna2803 Feb 11, 2025
958d51b
Merge branch 'main' into implement-countlsfx
krishna2803 Feb 11, 2025
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 @@ -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);
}
Copy link
Member

Choose a reason for hiding this comment

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

ah, you had this correct before

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sorry if im missing something, but the doc says:

// Use braces on the outer `if` to avoid a potential dangling `else`
// situation.
if (isa<VarDecl>(D)) {
  if (shouldProcessAttr(A))
    handleAttr(A);
}

Copy link
Member

Choose a reason for hiding this comment

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

oh, that's news to me. I guess because of constexpr we cant make it if (FXRep::SIGN_LEN > 0 && f < 0)... or could we?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i'll just test it and see if it works!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

and it seems it doesn't..

// clang++ -std=c++20 -Wall hello.cpp -o hello
#include <iostream>

constexpr int x = 1;

int main() {
  int y;
  std::cin >> y;

  if constexpr (x > 0 && y > 4)
    std::cout << "foo bar";
}
hello.cpp:10:17: error: constexpr if condition is not a constant expression
  if constexpr (x > 0 && y > 4)
                ^~~~~~~~~~~~~~
hello.cpp:10:26: note: read of non-const variable 'y' is not allowed in a constant expression
  if constexpr (x > 0 && y > 4)
                         ^
hello.cpp:7:7: note: declared here
  int y;
      ^
1 error generated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

same here:

In file included from /home/krishna/OpenSource/llvm-project/libc/src/stdfix/countlsr.cpp:11:
/home/krishna/OpenSource/llvm-project/libc/src/__support/fixed_point/fx_bits.h:188:17: error: constexpr if condition is not a constant expression
  188 |   if constexpr (FXRep::SIGN_LEN > 0 && f < 0)
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/krishna/OpenSource/llvm-project/libc/src/stdfix/countlsr.cpp:16:68: note: in instantiation of function template specialization '__llvm_libc_21_0_0_git::fixed_point::countls<_Fract>' requested here
   16 | LLVM_LIBC_FUNCTION(int, countlsr, (fract f)) { return fixed_point::countls(f); }
      |                                                                    ^
/home/krishna/OpenSource/llvm-project/libc/src/__support/fixed_point/fx_bits.h:188:40: note: function parameter 'f' with unknown value cannot be used in a constant expression
  188 |   if constexpr (FXRep::SIGN_LEN > 0 && f < 0)
      |                                        ^
/home/krishna/OpenSource/llvm-project/libc/src/__support/fixed_point/fx_bits.h:183:11: note: declared here
  183 | countls(T f) {
      |           ^
1 error generated.


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