[libc-commits] [libc] f6bfa33 - [libc][stdfix] Implement fixed point bitsfx functions in llvm libc (#128413)

via libc-commits libc-commits at lists.llvm.org
Thu Feb 27 10:05:31 PST 2025


Author: Krishna Pandey
Date: 2025-02-27T13:05:27-05:00
New Revision: f6bfa33cdb1482df0e2f23413fbe809afbc28830

URL: https://github.com/llvm/llvm-project/commit/f6bfa33cdb1482df0e2f23413fbe809afbc28830
DIFF: https://github.com/llvm/llvm-project/commit/f6bfa33cdb1482df0e2f23413fbe809afbc28830.diff

LOG: [libc][stdfix] Implement fixed point bitsfx functions in llvm libc (#128413)

Fixes #113359

---------

Signed-off-by: krishna2803 <kpandey81930 at gmail.com>

Added: 
    libc/src/stdfix/bitshk.cpp
    libc/src/stdfix/bitshk.h
    libc/src/stdfix/bitshr.cpp
    libc/src/stdfix/bitshr.h
    libc/src/stdfix/bitsk.cpp
    libc/src/stdfix/bitsk.h
    libc/src/stdfix/bitslk.cpp
    libc/src/stdfix/bitslk.h
    libc/src/stdfix/bitslr.cpp
    libc/src/stdfix/bitslr.h
    libc/src/stdfix/bitsr.cpp
    libc/src/stdfix/bitsr.h
    libc/src/stdfix/bitsuhk.cpp
    libc/src/stdfix/bitsuhk.h
    libc/src/stdfix/bitsuhr.cpp
    libc/src/stdfix/bitsuhr.h
    libc/src/stdfix/bitsuk.cpp
    libc/src/stdfix/bitsuk.h
    libc/src/stdfix/bitsulk.cpp
    libc/src/stdfix/bitsulk.h
    libc/src/stdfix/bitsulr.cpp
    libc/src/stdfix/bitsulr.h
    libc/src/stdfix/bitsur.cpp
    libc/src/stdfix/bitsur.h
    libc/src/stdfix/bitusk.cpp
    libc/test/src/stdfix/BitsFxTest.h
    libc/test/src/stdfix/bitshk_test.cpp
    libc/test/src/stdfix/bitshr_test.cpp
    libc/test/src/stdfix/bitsk_test.cpp
    libc/test/src/stdfix/bitslk_test.cpp
    libc/test/src/stdfix/bitslr_test.cpp
    libc/test/src/stdfix/bitsr_test.cpp
    libc/test/src/stdfix/bitsuhk_test.cpp
    libc/test/src/stdfix/bitsuhr_test.cpp
    libc/test/src/stdfix/bitsuk_test.cpp
    libc/test/src/stdfix/bitsulk_test.cpp
    libc/test/src/stdfix/bitsulr_test.cpp
    libc/test/src/stdfix/bitsur_test.cpp

Modified: 
    libc/config/baremetal/arm/entrypoints.txt
    libc/config/baremetal/riscv/entrypoints.txt
    libc/config/linux/riscv/entrypoints.txt
    libc/config/linux/x86_64/entrypoints.txt
    libc/docs/headers/math/stdfix.rst
    libc/include/stdfix.yaml
    libc/src/__support/fixed_point/fx_bits.h
    libc/src/stdfix/CMakeLists.txt
    libc/test/UnitTest/LibcTest.cpp
    libc/test/src/stdfix/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 6fd1fce3ab245..d7a01bdf90b3f 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -509,6 +509,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.ukbits
     libc.src.stdfix.lkbits
     libc.src.stdfix.ulkbits
+    libc.src.stdfix.bitshr
+    libc.src.stdfix.bitsr
+    libc.src.stdfix.bitslr
+    libc.src.stdfix.bitshk
+    libc.src.stdfix.bitsk
+    libc.src.stdfix.bitslk
+    libc.src.stdfix.bitsuhr
+    libc.src.stdfix.bitsur
+    libc.src.stdfix.bitsulr
+    libc.src.stdfix.bitsuhk
+    libc.src.stdfix.bitsuk
+    libc.src.stdfix.bitsulk
     libc.src.stdfix.countlshr
     libc.src.stdfix.countlsr
     libc.src.stdfix.countlslr

diff  --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 5985c495bdaf2..ae00803dd0def 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -504,6 +504,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.ukbits
     libc.src.stdfix.lkbits
     libc.src.stdfix.ulkbits
+    libc.src.stdfix.bitshr
+    libc.src.stdfix.bitsr
+    libc.src.stdfix.bitslr
+    libc.src.stdfix.bitshk
+    libc.src.stdfix.bitsk
+    libc.src.stdfix.bitslk
+    libc.src.stdfix.bitshr
+    libc.src.stdfix.bitsur
+    libc.src.stdfix.bitsulr
+    libc.src.stdfix.bitsuhk
+    libc.src.stdfix.bitsuk
+    libc.src.stdfix.bitsulk
     libc.src.stdfix.countlshr
     libc.src.stdfix.countlsr
     libc.src.stdfix.countlslr

diff  --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index fa1e48f901a90..4b69e43bce37d 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -748,6 +748,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.bitshr
+    libc.src.stdfix.bitsr
+    libc.src.stdfix.bitslr
+    libc.src.stdfix.bitshk
+    libc.src.stdfix.bitsk
+    libc.src.stdfix.bitslk
+    libc.src.stdfix.bitsuhr
+    libc.src.stdfix.bitsur
+    libc.src.stdfix.bitsulr
+    libc.src.stdfix.bitsuhk
+    libc.src.stdfix.bitsuk
+    libc.src.stdfix.bitsulk
     libc.src.stdfix.countlshr
     libc.src.stdfix.countlsr
     libc.src.stdfix.countlslr

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index a07393a49e0ad..293f6edd1ed27 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -876,6 +876,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.ukbits
     libc.src.stdfix.lkbits
     libc.src.stdfix.ulkbits
+    libc.src.stdfix.bitshr
+    libc.src.stdfix.bitsr
+    libc.src.stdfix.bitslr
+    libc.src.stdfix.bitshk
+    libc.src.stdfix.bitsk
+    libc.src.stdfix.bitslk
+    libc.src.stdfix.bitsuhr
+    libc.src.stdfix.bitsur
+    libc.src.stdfix.bitsulr
+    libc.src.stdfix.bitsuhk
+    libc.src.stdfix.bitsuk
+    libc.src.stdfix.bitsulk
     libc.src.stdfix.countlshr
     libc.src.stdfix.countlsr
     libc.src.stdfix.countlslr

diff  --git a/libc/docs/headers/math/stdfix.rst b/libc/docs/headers/math/stdfix.rst
index 4507f2b608bf1..73a0a596df331 100644
--- a/libc/docs/headers/math/stdfix.rst
+++ b/libc/docs/headers/math/stdfix.rst
@@ -69,7 +69,7 @@ The following functions are included in the ISO/IEC TR 18037:2008 standard.
 +===============+================+=============+===============+============+================+=============+================+=============+===============+============+================+=============+
 | abs           |                | |check|     |               | |check|    |                | |check|     |                | |check|     |               | |check|    |                | |check|     |
 +---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
-| bits\*        |                |             |               |            |                |             |                |             |               |            |                |             |
+| bits\*        | |check|        | |check|     | |check|       | |check|    | |check|        | |check|     | |check|        | |check|     | |check|       | |check|    | |check|        | |check|     |
 +---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
 | \*bits        |                |             |               |            |                |             |                |             |               |            |                |             |
 +---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+

diff  --git a/libc/include/stdfix.yaml b/libc/include/stdfix.yaml
index 0abf2f3a9b3b6..707e5a2b09819 100644
--- a/libc/include/stdfix.yaml
+++ b/libc/include/stdfix.yaml
@@ -148,6 +148,90 @@ functions:
     arguments:
       - type: uint_ulk_t
     guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: bitshr
+    standards:
+      - stdc_ext
+    return_type: int_hr_t
+    arguments:
+      - type: short fract
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: bitsuhr
+    standards:
+      - stdc_ext
+    return_type: uint_uhr_t
+    arguments:
+      - type: unsigned short fract
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: bitsr
+    standards:
+      - stdc_ext
+    return_type: int_r_t
+    arguments:
+      - type: fract
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: bitsur
+    standards:
+      - stdc_ext
+    return_type: uint_ur_t
+    arguments:
+      - type: unsigned fract
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: bitslr
+    standards:
+      - stdc_ext
+    return_type: int_lr_t
+    arguments:
+      - type: long fract
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: bitsulr
+    standards:
+      - stdc_ext
+    return_type: uint_ulr_t
+    arguments:
+      - type: unsigned long fract
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: bitshk
+    standards:
+      - stdc_ext
+    return_type: int_hk_t
+    arguments:
+      - type: short accum
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: bitsuhk
+    standards:
+      - stdc_ext
+    return_type: uint_uhk_t
+    arguments:
+      - type: unsigned short accum
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: bitsk
+    standards:
+      - stdc_ext
+    return_type: int_k_t
+    arguments:
+      - type: accum
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: bitsuk
+    standards:
+      - stdc_ext
+    return_type: uint_uk_t
+    arguments:
+      - type: unsigned accum
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: bitslk
+    standards:
+      - stdc_ext
+    return_type: int_lk_t
+    arguments:
+      - type: long accum
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: bitsulk
+    standards:
+      - stdc_ext
+    return_type: uint_ulk_t
+    arguments:
+      - type: unsigned long accum
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
   - name: roundhk
     standards:
       - stdc_ext

diff  --git a/libc/src/__support/fixed_point/fx_bits.h b/libc/src/__support/fixed_point/fx_bits.h
index 7509419da0c43..b05f46bd34660 100644
--- a/libc/src/__support/fixed_point/fx_bits.h
+++ b/libc/src/__support/fixed_point/fx_bits.h
@@ -194,6 +194,13 @@ countls(T f) {
   return cpp::countl_zero(value_bits) - FXRep::SIGN_LEN;
 }
 
+// fixed-point to integer conversion
+template <typename T, typename XType>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, XType>
+bitsfx(T f) {
+  return cpp::bit_cast<XType, T>(f);
+}
+
 } // namespace fixed_point
 } // namespace LIBC_NAMESPACE_DECL
 

diff  --git a/libc/src/stdfix/CMakeLists.txt b/libc/src/stdfix/CMakeLists.txt
index 6fb06b8d7e9ae..362af0bf0d55c 100644
--- a/libc/src/stdfix/CMakeLists.txt
+++ b/libc/src/stdfix/CMakeLists.txt
@@ -48,6 +48,20 @@ foreach(suffix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
       libc.src.__support.fixed_point.fx_bits
   )
 
+  add_entrypoint_object(
+    bits${suffix}
+    HDRS
+      bits${suffix}.h
+    SRCS
+      bits${suffix}.cpp
+    COMPILE_OPTIONS
+      ${libc_opt_high_flag}
+    DEPENDS
+      libc.src.__support.fixed_point.fx_bits
+      libc.include.llvm-libc-types.stdfix-types
+      libc.include.llvm-libc-macros.stdfix_macros
+  )
+
   add_entrypoint_object(
     countls${suffix}
     HDRS

diff  --git a/libc/src/stdfix/bitshk.cpp b/libc/src/stdfix/bitshk.cpp
new file mode 100644
index 0000000000000..d0a3e128bdd65
--- /dev/null
+++ b/libc/src/stdfix/bitshk.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of bitshk 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 "bitshk.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // short accum
+#include "include/llvm-libc-types/stdfix-types.h"   // int_hk_t
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int_hk_t, bitshk, (short accum f)) {
+  return fixed_point::bitsfx<short accum, int_hk_t>(f);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/bitshk.h b/libc/src/stdfix/bitshk.h
new file mode 100644
index 0000000000000..a1505e2e56d85
--- /dev/null
+++ b/libc/src/stdfix/bitshk.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for bitshk 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_BITSHK_H
+#define LLVM_LIBC_SRC_STDFIX_BITSHK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // short accum
+#include "include/llvm-libc-types/stdfix-types.h"   // int_hk_t
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+int_hk_t bitshk(short accum f);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_BITSHK_H

diff  --git a/libc/src/stdfix/bitshr.cpp b/libc/src/stdfix/bitshr.cpp
new file mode 100644
index 0000000000000..394d1f08f6ae5
--- /dev/null
+++ b/libc/src/stdfix/bitshr.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of bitshr 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 "bitshr.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // short fract
+#include "include/llvm-libc-types/stdfix-types.h"   // int_hr_t
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int_hr_t, bitshr, (short fract f)) {
+  return fixed_point::bitsfx<short fract, int_hr_t>(f);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/bitshr.h b/libc/src/stdfix/bitshr.h
new file mode 100644
index 0000000000000..d5b4b8f56a7e9
--- /dev/null
+++ b/libc/src/stdfix/bitshr.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for bitshr 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_BITSHR_H
+#define LLVM_LIBC_SRC_STDFIX_BITSHR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // short fract
+#include "include/llvm-libc-types/stdfix-types.h"   // int_hr_t
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+int_hr_t bitshr(short fract f);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_BITSHR_H

diff  --git a/libc/src/stdfix/bitsk.cpp b/libc/src/stdfix/bitsk.cpp
new file mode 100644
index 0000000000000..f8c9d77d56e9c
--- /dev/null
+++ b/libc/src/stdfix/bitsk.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation for bitsk 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 "bitsk.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // accum
+#include "include/llvm-libc-types/stdfix-types.h"   // int_k_t
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int_k_t, bitsk, (accum f)) {
+  return fixed_point::bitsfx<accum, int_k_t>(f);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/bitsk.h b/libc/src/stdfix/bitsk.h
new file mode 100644
index 0000000000000..32d5a724dfb0b
--- /dev/null
+++ b/libc/src/stdfix/bitsk.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for bitsk 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_BITSK_H
+#define LLVM_LIBC_SRC_STDFIX_BITSK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // accum
+#include "include/llvm-libc-types/stdfix-types.h"   // int_k_t
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+int_k_t bitsk(accum f);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_BITSK_H

diff  --git a/libc/src/stdfix/bitslk.cpp b/libc/src/stdfix/bitslk.cpp
new file mode 100644
index 0000000000000..f4af2a8cd8b99
--- /dev/null
+++ b/libc/src/stdfix/bitslk.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation for bitslk 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 "bitslk.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // long accum
+#include "include/llvm-libc-types/stdfix-types.h"   // int_lk_t
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int_lk_t, bitslk, (long accum f)) {
+  return fixed_point::bitsfx<long accum, int_lk_t>(f);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/bitslk.h b/libc/src/stdfix/bitslk.h
new file mode 100644
index 0000000000000..821116b9a7c1b
--- /dev/null
+++ b/libc/src/stdfix/bitslk.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for bitslk 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_BITSLK_H
+#define LLVM_LIBC_SRC_STDFIX_BITSLK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // long accum
+#include "include/llvm-libc-types/stdfix-types.h"   // int_lk_t
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+int_lk_t bitslk(long accum f);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_BITSLK_H

diff  --git a/libc/src/stdfix/bitslr.cpp b/libc/src/stdfix/bitslr.cpp
new file mode 100644
index 0000000000000..3b38aa21a6338
--- /dev/null
+++ b/libc/src/stdfix/bitslr.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of bitslr 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 "bitslr.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // long fract
+#include "include/llvm-libc-types/stdfix-types.h"   // int_lr_t
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int_lr_t, bitslr, (long fract f)) {
+  return fixed_point::bitsfx<long fract, int_lr_t>(f);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/bitslr.h b/libc/src/stdfix/bitslr.h
new file mode 100644
index 0000000000000..0cb597214f550
--- /dev/null
+++ b/libc/src/stdfix/bitslr.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for bitslr 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_BITSLR_H
+#define LLVM_LIBC_SRC_STDFIX_BITSLR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // long fract
+#include "include/llvm-libc-types/stdfix-types.h"   // int_lr_t
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+int_lr_t bitslr(long fract f);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_BITSLR_H

diff  --git a/libc/src/stdfix/bitsr.cpp b/libc/src/stdfix/bitsr.cpp
new file mode 100644
index 0000000000000..2b6ad2cfe189a
--- /dev/null
+++ b/libc/src/stdfix/bitsr.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of bitsr 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 "bitsr.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // fract
+#include "include/llvm-libc-types/stdfix-types.h"   // int_r_t
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int_r_t, bitsr, (fract f)) {
+  return fixed_point::bitsfx<fract, int_r_t>(f);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/bitsr.h b/libc/src/stdfix/bitsr.h
new file mode 100644
index 0000000000000..e071f034cd107
--- /dev/null
+++ b/libc/src/stdfix/bitsr.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for bitsr 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_BITSR_H
+#define LLVM_LIBC_SRC_STDFIX_BITSR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // fract
+#include "include/llvm-libc-types/stdfix-types.h"   // int_r_t
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+int_r_t bitsr(fract f);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_BITSR_H

diff  --git a/libc/src/stdfix/bitsuhk.cpp b/libc/src/stdfix/bitsuhk.cpp
new file mode 100755
index 0000000000000..1b0bf59a550f1
--- /dev/null
+++ b/libc/src/stdfix/bitsuhk.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of bitsuhk 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 "bitsuhk.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned short accum
+#include "include/llvm-libc-types/stdfix-types.h"   // uint_uhk_t
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(uint_uhk_t, bitsuhk, (unsigned short accum f)) {
+  return fixed_point::bitsfx<unsigned short accum, uint_uhk_t>(f);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/bitsuhk.h b/libc/src/stdfix/bitsuhk.h
new file mode 100755
index 0000000000000..1e80286d77099
--- /dev/null
+++ b/libc/src/stdfix/bitsuhk.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for bitsuhk 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_BITSUHK_H
+#define LLVM_LIBC_SRC_STDFIX_BITSUHK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned short accum
+#include "include/llvm-libc-types/stdfix-types.h"   // uint_uhk_t
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+uint_uhk_t bitsuhk(unsigned short accum f);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_BITSUHK_H

diff  --git a/libc/src/stdfix/bitsuhr.cpp b/libc/src/stdfix/bitsuhr.cpp
new file mode 100755
index 0000000000000..66152e14bb209
--- /dev/null
+++ b/libc/src/stdfix/bitsuhr.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of bitsuhr 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 "bitsuhr.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned short fract
+#include "include/llvm-libc-types/stdfix-types.h"   // uint_uhr_t
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(uint_uhr_t, bitsuhr, (unsigned short fract f)) {
+  return fixed_point::bitsfx<unsigned short fract, uint_uhr_t>(f);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/bitsuhr.h b/libc/src/stdfix/bitsuhr.h
new file mode 100755
index 0000000000000..0311665bc17f3
--- /dev/null
+++ b/libc/src/stdfix/bitsuhr.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for bitsuhr 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_BITSUHR_H
+#define LLVM_LIBC_SRC_STDFIX_BITSUHR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned short fract
+#include "include/llvm-libc-types/stdfix-types.h"   // uint_uhr_t
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+uint_uhr_t bitsuhr(unsigned short fract f);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_BITSUHR_H

diff  --git a/libc/src/stdfix/bitsuk.cpp b/libc/src/stdfix/bitsuk.cpp
new file mode 100755
index 0000000000000..b0a92bd92d4ea
--- /dev/null
+++ b/libc/src/stdfix/bitsuk.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation for bitsuk 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 "bitsuk.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned accum
+#include "include/llvm-libc-types/stdfix-types.h"   // uint_uk_t
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(uint_uk_t, bitsuk, (unsigned accum f)) {
+  return fixed_point::bitsfx<unsigned accum, uint_uk_t>(f);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/bitsuk.h b/libc/src/stdfix/bitsuk.h
new file mode 100755
index 0000000000000..fce37e82d44c1
--- /dev/null
+++ b/libc/src/stdfix/bitsuk.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for bitsuk 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_BITSUK_H
+#define LLVM_LIBC_SRC_STDFIX_BITSUK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned accum
+#include "include/llvm-libc-types/stdfix-types.h"   // uint_uk_t
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+uint_uk_t bitsuk(unsigned accum f);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_BITSUK_H

diff  --git a/libc/src/stdfix/bitsulk.cpp b/libc/src/stdfix/bitsulk.cpp
new file mode 100755
index 0000000000000..b8f61a16eb61e
--- /dev/null
+++ b/libc/src/stdfix/bitsulk.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation for bitsulk 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 "bitsulk.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned long accum
+#include "include/llvm-libc-types/stdfix-types.h"   // uint_ulk_t
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(uint_ulk_t, bitsulk, (unsigned long accum f)) {
+  return fixed_point::bitsfx<unsigned long accum, uint_ulk_t>(f);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/bitsulk.h b/libc/src/stdfix/bitsulk.h
new file mode 100755
index 0000000000000..1bf681ee751c6
--- /dev/null
+++ b/libc/src/stdfix/bitsulk.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for bitsulk 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_BITSLK_H
+#define LLVM_LIBC_SRC_STDFIX_BITSLK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned long accum
+#include "include/llvm-libc-types/stdfix-types.h"   // uint_ulk_t
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+uint_ulk_t bitsulk(unsigned long accum f);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_BITSLK_H

diff  --git a/libc/src/stdfix/bitsulr.cpp b/libc/src/stdfix/bitsulr.cpp
new file mode 100755
index 0000000000000..9fd1b15bedad9
--- /dev/null
+++ b/libc/src/stdfix/bitsulr.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of bitsulr 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 "bitsulr.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned long fract
+#include "include/llvm-libc-types/stdfix-types.h"   // uint_ulr_t
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(uint_ulr_t, bitsulr, (unsigned long fract f)) {
+  return fixed_point::bitsfx<unsigned long fract, uint_ulr_t>(f);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/bitsulr.h b/libc/src/stdfix/bitsulr.h
new file mode 100755
index 0000000000000..cf0f6fbe6698d
--- /dev/null
+++ b/libc/src/stdfix/bitsulr.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for bitsulr 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_BITSULR_H
+#define LLVM_LIBC_SRC_STDFIX_BITSULR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned long fract
+#include "include/llvm-libc-types/stdfix-types.h"   // uint_ulr_t
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+uint_ulr_t bitsulr(unsigned long fract f);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_BITSULR_H

diff  --git a/libc/src/stdfix/bitsur.cpp b/libc/src/stdfix/bitsur.cpp
new file mode 100755
index 0000000000000..ffb52de9257bf
--- /dev/null
+++ b/libc/src/stdfix/bitsur.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of bitsur 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 "bitsur.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned fract
+#include "include/llvm-libc-types/stdfix-types.h"   // uint_ur_t
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(uint_ur_t, bitsur, (unsigned fract f)) {
+  return fixed_point::bitsfx<unsigned fract, uint_ur_t>(f);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/bitsur.h b/libc/src/stdfix/bitsur.h
new file mode 100755
index 0000000000000..4c938bb65ec8d
--- /dev/null
+++ b/libc/src/stdfix/bitsur.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for bitsur 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_BITSUR_H
+#define LLVM_LIBC_SRC_STDFIX_BITSUR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned fract
+#include "include/llvm-libc-types/stdfix-types.h"   // uint_ur_t
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+uint_ur_t bitsur(unsigned fract f);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_BITSUR_H

diff  --git a/libc/src/stdfix/bitusk.cpp b/libc/src/stdfix/bitusk.cpp
new file mode 100755
index 0000000000000..ac0852e078c60
--- /dev/null
+++ b/libc/src/stdfix/bitusk.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation for bitsuk 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 "bitsuk.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned accum
+#include "include/llvm-libc-types/stdfix-types.h"   // uint_uk_t
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(uint_uk_t, bitsuk, (unsigned accum f)) {
+  return fixed_point::bitsfx<unsigned accum, uint_uk_t>(f);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/test/UnitTest/LibcTest.cpp b/libc/test/UnitTest/LibcTest.cpp
index afb1368f00905..4395c7cf6e201 100644
--- a/libc/test/UnitTest/LibcTest.cpp
+++ b/libc/test/UnitTest/LibcTest.cpp
@@ -223,6 +223,7 @@ TEST_SPECIALIZATION(int);
 TEST_SPECIALIZATION(long);
 TEST_SPECIALIZATION(long long);
 
+TEST_SPECIALIZATION(signed char);
 TEST_SPECIALIZATION(unsigned char);
 TEST_SPECIALIZATION(unsigned short);
 TEST_SPECIALIZATION(unsigned int);

diff  --git a/libc/test/src/stdfix/BitsFxTest.h b/libc/test/src/stdfix/BitsFxTest.h
new file mode 100644
index 0000000000000..eca6ab1bb28ab
--- /dev/null
+++ b/libc/test/src/stdfix/BitsFxTest.h
@@ -0,0 +1,81 @@
+//===-- Utility class to test bitsfx functions ------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "test/UnitTest/Test.h"
+
+#include "src/__support/fixed_point/fx_rep.h"
+
+template <typename T, typename XType>
+class BitsFxTest : public LIBC_NAMESPACE::testing::Test {
+
+  using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<T>;
+  static constexpr T zero = FXRep::ZERO();
+  static constexpr T max = FXRep::MAX();
+  static constexpr T min = FXRep::MIN();
+  static constexpr T one_half = FXRep::ONE_HALF();
+  static constexpr T one_fourth = FXRep::ONE_FOURTH();
+  static constexpr T eps = FXRep::EPS();
+
+  static constexpr T zero_point_six_eight_seven_five_t = 0.6875;
+
+  static constexpr T negative_zero_point_six_eight_seven_five_t = -0.6875;
+
+  // an arbitrarily chosen special number
+  static constexpr T special_num_t = 10.71875;
+
+  static constexpr T negative_special_num_t = -10.71875;
+
+public:
+  typedef XType (*BitsFxFunc)(T);
+
+  void testSpecialNumbers(BitsFxFunc func) {
+    EXPECT_EQ(static_cast<XType>(0), func(zero));
+    EXPECT_EQ(static_cast<XType>(1ULL << (FXRep::FRACTION_LEN - 1)),
+              func(one_half));
+    EXPECT_EQ(static_cast<XType>(1ULL << (FXRep::FRACTION_LEN - 2)),
+              func(one_fourth));
+    EXPECT_EQ(static_cast<XType>(1), func(eps));
+
+    // (0.6875)_10 = (0.1011)_2
+    EXPECT_EQ(static_cast<XType>(11ULL << (FXRep::FRACTION_LEN - 4)),
+              func(zero_point_six_eight_seven_five_t));
+
+    if constexpr (FXRep::SIGN_LEN > 0)
+      EXPECT_EQ(static_cast<XType>(-(11ULL << (FXRep::FRACTION_LEN - 4))),
+                func(negative_zero_point_six_eight_seven_five_t));
+
+    if constexpr (FXRep::INTEGRAL_LEN > 0) {
+      constexpr size_t kMinFbits = 7;
+
+      if (max >= 11 && FXRep::FRACTION_LEN >= kMinFbits) {
+        // (10.71875)_10 = (1010.1011100)_2
+        constexpr long long kExpected = 1372;
+        EXPECT_EQ(
+            static_cast<XType>(kExpected << (FXRep::FRACTION_LEN - kMinFbits)),
+            func(special_num_t));
+      }
+
+      if constexpr (FXRep::SIGN_LEN > 0) {
+        if (min <= -11 && FXRep::FRACTION_LEN >= kMinFbits) {
+          // (-10.71875)_10 = (-1010.1011100)_2
+          constexpr long long kExpected = -1372;
+          EXPECT_EQ(static_cast<XType>(kExpected
+                                       << (FXRep::FRACTION_LEN - kMinFbits)),
+                    func(negative_special_num_t));
+        }
+      }
+    }
+  }
+};
+
+#define LIST_BITSFX_TESTS(Name, T, XType, func)                                \
+  using LlvmLibcBits##Name##Test = BitsFxTest<T, XType>;                       \
+  TEST_F(LlvmLibcBits##Name##Test, SpecialNumbers) {                           \
+    testSpecialNumbers(&func);                                                 \
+  }                                                                            \
+  static_assert(true, "Require semicolon.")

diff  --git a/libc/test/src/stdfix/CMakeLists.txt b/libc/test/src/stdfix/CMakeLists.txt
index 8f0226bf41672..8dc0eb854e65c 100644
--- a/libc/test/src/stdfix/CMakeLists.txt
+++ b/libc/test/src/stdfix/CMakeLists.txt
@@ -74,6 +74,20 @@ foreach(suffix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
       libc.src.__support.fixed_point.fx_bits
   )
 
+  add_libc_test(
+    bits${suffix}_test
+    SUITE
+      libc-stdfix-tests
+    HDRS
+      BitsFxTest.h
+    SRCS
+      bits${suffix}_test.cpp
+    DEPENDS
+      libc.src.stdfix.bits${suffix}
+      libc.src.__support.fixed_point.fx_rep
+      libc.src.__support.fixed_point.fx_bits
+  )
+
   add_libc_test(
     countls${suffix}_test
     SUITE

diff  --git a/libc/test/src/stdfix/bitshk_test.cpp b/libc/test/src/stdfix/bitshk_test.cpp
new file mode 100644
index 0000000000000..ca83162d439a6
--- /dev/null
+++ b/libc/test/src/stdfix/bitshk_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bitshk ----------------------------------------------===//
+//
+// 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 "BitsFxTest.h"
+
+#include "llvm-libc-types/stdfix-types.h" // int_hk_t
+#include "src/stdfix/bitshk.h"
+
+LIST_BITSFX_TESTS(hk, short accum, int_hk_t, LIBC_NAMESPACE::bitshk);

diff  --git a/libc/test/src/stdfix/bitshr_test.cpp b/libc/test/src/stdfix/bitshr_test.cpp
new file mode 100644
index 0000000000000..220d7f6a69c16
--- /dev/null
+++ b/libc/test/src/stdfix/bitshr_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bitshr ----------------------------------------------===//
+//
+// 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 "BitsFxTest.h"
+
+#include "llvm-libc-types/stdfix-types.h" // int_hr_t
+#include "src/stdfix/bitshr.h"
+
+LIST_BITSFX_TESTS(hr, short fract, int_hr_t, LIBC_NAMESPACE::bitshr);

diff  --git a/libc/test/src/stdfix/bitsk_test.cpp b/libc/test/src/stdfix/bitsk_test.cpp
new file mode 100644
index 0000000000000..7e0057bae4657
--- /dev/null
+++ b/libc/test/src/stdfix/bitsk_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bitsk -----------------------------------------------===//
+//
+// 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 "BitsFxTest.h"
+
+#include "llvm-libc-types/stdfix-types.h" // int_k_t
+#include "src/stdfix/bitsk.h"
+
+LIST_BITSFX_TESTS(k, accum, int_k_t, LIBC_NAMESPACE::bitsk);

diff  --git a/libc/test/src/stdfix/bitslk_test.cpp b/libc/test/src/stdfix/bitslk_test.cpp
new file mode 100644
index 0000000000000..46c04e2f75511
--- /dev/null
+++ b/libc/test/src/stdfix/bitslk_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bitslk ----------------------------------------------===//
+//
+// 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 "BitsFxTest.h"
+
+#include "llvm-libc-types/stdfix-types.h" // int_lk_t
+#include "src/stdfix/bitslk.h"
+
+LIST_BITSFX_TESTS(lk, long accum, int_lk_t, LIBC_NAMESPACE::bitslk);

diff  --git a/libc/test/src/stdfix/bitslr_test.cpp b/libc/test/src/stdfix/bitslr_test.cpp
new file mode 100644
index 0000000000000..ef68d2831fb9d
--- /dev/null
+++ b/libc/test/src/stdfix/bitslr_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bitslr ----------------------------------------------===//
+//
+// 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 "BitsFxTest.h"
+
+#include "llvm-libc-types/stdfix-types.h" // int_lr_t
+#include "src/stdfix/bitslr.h"
+
+LIST_BITSFX_TESTS(hk, long fract, int_lr_t, LIBC_NAMESPACE::bitslr);

diff  --git a/libc/test/src/stdfix/bitsr_test.cpp b/libc/test/src/stdfix/bitsr_test.cpp
new file mode 100644
index 0000000000000..0aeb980e30382
--- /dev/null
+++ b/libc/test/src/stdfix/bitsr_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bitsr -----------------------------------------------===//
+//
+// 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 "BitsFxTest.h"
+
+#include "llvm-libc-types/stdfix-types.h" // int_r_t
+#include "src/stdfix/bitsr.h"
+
+LIST_BITSFX_TESTS(r, fract, int_r_t, LIBC_NAMESPACE::bitsr);

diff  --git a/libc/test/src/stdfix/bitsuhk_test.cpp b/libc/test/src/stdfix/bitsuhk_test.cpp
new file mode 100644
index 0000000000000..5ddb78383df02
--- /dev/null
+++ b/libc/test/src/stdfix/bitsuhk_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for bitsuhk ---------------------------------------------===//
+//
+// 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 "BitsFxTest.h"
+
+#include "llvm-libc-types/stdfix-types.h" // uint_uhk_t
+#include "src/stdfix/bitsuhk.h"
+
+LIST_BITSFX_TESTS(uhk, unsigned short accum, uint_uhk_t,
+                  LIBC_NAMESPACE::bitsuhk);

diff  --git a/libc/test/src/stdfix/bitsuhr_test.cpp b/libc/test/src/stdfix/bitsuhr_test.cpp
new file mode 100644
index 0000000000000..6f5d559859456
--- /dev/null
+++ b/libc/test/src/stdfix/bitsuhr_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for bitsuhr ---------------------------------------------===//
+//
+// 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 "BitsFxTest.h"
+
+#include "llvm-libc-types/stdfix-types.h" // uint_uhr_t
+#include "src/stdfix/bitsuhr.h"
+
+LIST_BITSFX_TESTS(uhr, unsigned short fract, uint_uhr_t,
+                  LIBC_NAMESPACE::bitsuhr);

diff  --git a/libc/test/src/stdfix/bitsuk_test.cpp b/libc/test/src/stdfix/bitsuk_test.cpp
new file mode 100644
index 0000000000000..309c525f3fd2d
--- /dev/null
+++ b/libc/test/src/stdfix/bitsuk_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bitsuk ----------------------------------------------===//
+//
+// 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 "BitsFxTest.h"
+
+#include "llvm-libc-types/stdfix-types.h" // uint_uk_t
+#include "src/stdfix/bitsuk.h"
+
+LIST_BITSFX_TESTS(uk, unsigned accum, uint_uk_t, LIBC_NAMESPACE::bitsuk);

diff  --git a/libc/test/src/stdfix/bitsulk_test.cpp b/libc/test/src/stdfix/bitsulk_test.cpp
new file mode 100644
index 0000000000000..cba011d5f222d
--- /dev/null
+++ b/libc/test/src/stdfix/bitsulk_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for bitsulk ---------------------------------------------===//
+//
+// 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 "BitsFxTest.h"
+
+#include "llvm-libc-types/stdfix-types.h" // uint_ulk_t
+#include "src/stdfix/bitsulk.h"
+
+LIST_BITSFX_TESTS(ulk, unsigned long accum, uint_ulk_t,
+                  LIBC_NAMESPACE::bitsulk);

diff  --git a/libc/test/src/stdfix/bitsulr_test.cpp b/libc/test/src/stdfix/bitsulr_test.cpp
new file mode 100644
index 0000000000000..39b21c424199e
--- /dev/null
+++ b/libc/test/src/stdfix/bitsulr_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for bitsulr ---------------------------------------------===//
+//
+// 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 "BitsFxTest.h"
+
+#include "llvm-libc-types/stdfix-types.h" // uint_ulr_t
+#include "src/stdfix/bitsulr.h"
+
+LIST_BITSFX_TESTS(ulr, unsigned long fract, uint_ulr_t,
+                  LIBC_NAMESPACE::bitsulr);

diff  --git a/libc/test/src/stdfix/bitsur_test.cpp b/libc/test/src/stdfix/bitsur_test.cpp
new file mode 100644
index 0000000000000..b7c4b0617eb6e
--- /dev/null
+++ b/libc/test/src/stdfix/bitsur_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bitsur ----------------------------------------------===//
+//
+// 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 "BitsFxTest.h"
+
+#include "llvm-libc-types/stdfix-types.h" // uint_ur_t
+#include "src/stdfix/bitsur.h"
+
+LIST_BITSFX_TESTS(ur, unsigned fract, uint_ur_t, LIBC_NAMESPACE::bitsur);


        


More information about the libc-commits mailing list