[libc-commits] [libc] c11b6e8 - [libc][stdfix] Implement fixed point fxbits functions in llvm-libc (#114912)

via libc-commits libc-commits at lists.llvm.org
Mon Nov 11 09:54:20 PST 2024


Author: William Tran-Viet
Date: 2024-11-11T12:54:16-05:00
New Revision: c11b6e80b6121ebbec6fdc32e51938b6a13ef104

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

LOG: [libc][stdfix] Implement fixed point fxbits functions in llvm-libc  (#114912)

Added: 
    libc/include/llvm-libc-types/stdfix-types.h
    libc/src/stdfix/hkbits.cpp
    libc/src/stdfix/hkbits.h
    libc/src/stdfix/hrbits.cpp
    libc/src/stdfix/hrbits.h
    libc/src/stdfix/kbits.cpp
    libc/src/stdfix/kbits.h
    libc/src/stdfix/lkbits.cpp
    libc/src/stdfix/lkbits.h
    libc/src/stdfix/lrbits.cpp
    libc/src/stdfix/lrbits.h
    libc/src/stdfix/rbits.cpp
    libc/src/stdfix/rbits.h
    libc/src/stdfix/uhkbits.cpp
    libc/src/stdfix/uhkbits.h
    libc/src/stdfix/uhrbits.cpp
    libc/src/stdfix/uhrbits.h
    libc/src/stdfix/ukbits.cpp
    libc/src/stdfix/ukbits.h
    libc/src/stdfix/ulkbits.cpp
    libc/src/stdfix/ulkbits.h
    libc/src/stdfix/ulrbits.cpp
    libc/src/stdfix/ulrbits.h
    libc/src/stdfix/urbits.cpp
    libc/src/stdfix/urbits.h
    libc/test/src/stdfix/FxBitsTest.h
    libc/test/src/stdfix/hkbits_test.cpp
    libc/test/src/stdfix/hrbits_test.cpp
    libc/test/src/stdfix/kbits_test.cpp
    libc/test/src/stdfix/lkbits_test.cpp
    libc/test/src/stdfix/lrbits_test.cpp
    libc/test/src/stdfix/rbits_test.cpp
    libc/test/src/stdfix/uhkbits_test.cpp
    libc/test/src/stdfix/uhrbits_test.cpp
    libc/test/src/stdfix/ukbits_test.cpp
    libc/test/src/stdfix/ulkbits_test.cpp
    libc/test/src/stdfix/ulrbits_test.cpp
    libc/test/src/stdfix/urbits_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/include/CMakeLists.txt
    libc/include/llvm-libc-types/CMakeLists.txt
    libc/newhdrgen/yaml/stdfix.yaml
    libc/spec/stdc_ext.td
    libc/src/__support/fixed_point/fx_bits.h
    libc/src/stdfix/CMakeLists.txt
    libc/test/src/stdfix/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index f136711b540966..f59208deba614c 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -458,6 +458,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.sqrtulr
     libc.src.stdfix.uhksqrtus
     libc.src.stdfix.uksqrtui
+    libc.src.stdfix.hrbits
+    libc.src.stdfix.uhrbits
+    libc.src.stdfix.rbits
+    libc.src.stdfix.urbits
+    libc.src.stdfix.lrbits
+    libc.src.stdfix.ulrbits
+    libc.src.stdfix.hkbits
+    libc.src.stdfix.uhkbits
+    libc.src.stdfix.kbits
+    libc.src.stdfix.ukbits
+    libc.src.stdfix.lkbits
+    libc.src.stdfix.ulkbits
   )
 endif()
 

diff  --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 08c36ce8396784..e59c4e843e5d5c 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -453,6 +453,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.sqrtulr
     libc.src.stdfix.uhksqrtus
     libc.src.stdfix.uksqrtui
+    libc.src.stdfix.hrbits
+    libc.src.stdfix.uhrbits
+    libc.src.stdfix.rbits
+    libc.src.stdfix.urbits
+    libc.src.stdfix.lrbits
+    libc.src.stdfix.ulrbits
+    libc.src.stdfix.hkbits
+    libc.src.stdfix.uhkbits
+    libc.src.stdfix.kbits
+    libc.src.stdfix.ukbits
+    libc.src.stdfix.lkbits
+    libc.src.stdfix.ulkbits   
   )
 endif()
 

diff  --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index d63c5d651cc93b..f18d052dde2905 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -717,6 +717,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.sqrtulr
     libc.src.stdfix.uhksqrtus
     libc.src.stdfix.uksqrtui
+    libc.src.stdfix.hrbits
+    libc.src.stdfix.uhrbits
+    libc.src.stdfix.rbits
+    libc.src.stdfix.urbits
+    libc.src.stdfix.lrbits
+    libc.src.stdfix.ulrbits
+    libc.src.stdfix.hkbits
+    libc.src.stdfix.uhkbits
+    libc.src.stdfix.kbits
+    libc.src.stdfix.ukbits
+    libc.src.stdfix.lkbits
+    libc.src.stdfix.ulkbits
   )
 endif()
 

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index d4f552617c279a..5c1db3f44558d4 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -828,6 +828,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.sqrtulr
     libc.src.stdfix.uhksqrtus
     libc.src.stdfix.uksqrtui
+    libc.src.stdfix.hrbits
+    libc.src.stdfix.uhrbits
+    libc.src.stdfix.rbits
+    libc.src.stdfix.urbits
+    libc.src.stdfix.lrbits
+    libc.src.stdfix.ulrbits
+    libc.src.stdfix.hkbits
+    libc.src.stdfix.uhkbits
+    libc.src.stdfix.kbits
+    libc.src.stdfix.ukbits
+    libc.src.stdfix.lkbits
+    libc.src.stdfix.ulkbits
   )
 endif()
 

diff  --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 30d0b71d88cc47..91611026df105c 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -178,6 +178,7 @@ add_header_macro(
   stdfix.h
   DEPENDS
     .llvm-libc-macros.stdfix_macros
+    .llvm-libc-types.stdfix-types
 )
 
 # TODO: This should be conditional on POSIX networking being included.

diff  --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index a104ab78689606..81bb0d6e6f50e6 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -155,3 +155,4 @@ DEPENDS
 )
 add_header(locale_t HDR locale_t.h)
 add_header(struct_lconv HDR struct_lconv.h)
+add_header(stdfix-types HDR stdfix-types.h)

diff  --git a/libc/include/llvm-libc-types/stdfix-types.h b/libc/include/llvm-libc-types/stdfix-types.h
new file mode 100644
index 00000000000000..759e59251a5e87
--- /dev/null
+++ b/libc/include/llvm-libc-types/stdfix-types.h
@@ -0,0 +1,25 @@
+//===-- Definition of stdfix integer types --------------------------------===//
+//
+// 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_TYPES_STDFIX_TYPES_H
+#define LLVM_LIBC_TYPES_STDFIX_TYPES_H
+
+typedef signed char int_hr_t;
+typedef signed short int int_r_t;
+typedef signed int int_lr_t;
+typedef signed short int_hk_t;
+typedef signed int int_k_t;
+typedef signed long int_lk_t;
+typedef unsigned char uint_uhr_t;
+typedef unsigned short int uint_ur_t;
+typedef unsigned int uint_ulr_t;
+typedef unsigned short int uint_uhk_t;
+typedef unsigned int uint_uk_t;
+typedef unsigned long uint_ulk_t;
+
+#endif // LLVM_LIBC_TYPES_STDFIX_TYPES_H

diff  --git a/libc/newhdrgen/yaml/stdfix.yaml b/libc/newhdrgen/yaml/stdfix.yaml
index ca6658939e2278..9787eaba45e4ed 100644
--- a/libc/newhdrgen/yaml/stdfix.yaml
+++ b/libc/newhdrgen/yaml/stdfix.yaml
@@ -1,6 +1,7 @@
 header: stdfix.h
 macros: []
-types: []
+types: 
+  - type_name: stdfix-types
 enums: []
 objects: []
 functions:
@@ -62,6 +63,90 @@ functions:
     arguments:
       - type: accum
     guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: hrbits
+    standards:
+      - stdc_ext
+    return_type: short fract
+    arguments:
+      - type: int_hr_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: uhrbits
+    standards:
+      - stdc_ext
+    return_type: unsigned short fract
+    arguments:
+      - type: uint_uhr_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: rbits
+    standards:
+      - stdc_ext
+    return_type: fract
+    arguments:
+      - type: int_r_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: urbits
+    standards:
+      - stdc_ext
+    return_type: unsigned fract
+    arguments:
+      - type: uint_ur_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: lrbits
+    standards:
+      - stdc_ext
+    return_type: long fract
+    arguments:
+      - type: int_lr_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: ulrbits
+    standards:
+      - stdc_ext
+    return_type: unsigned long fract
+    arguments:
+      - type: uint_ulr_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: hkbits
+    standards:
+      - stdc_ext
+    return_type: short accum
+    arguments:
+      - type: int_hk_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: uhkbits
+    standards:
+      - stdc_ext
+    return_type: unsigned short accum
+    arguments:
+      - type: uint_uhk_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: kbits
+    standards:
+      - stdc_ext
+    return_type: accum
+    arguments:
+      - type: int_k_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: ukbits
+    standards:
+      - stdc_ext
+    return_type: unsigned accum
+    arguments:
+      - type: uint_uk_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: lkbits
+    standards:
+      - stdc_ext
+    return_type: long accum
+    arguments:
+      - type: uint_ulr_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: ulkbits
+    standards:
+      - stdc_ext
+    return_type: unsigned long accum
+    arguments:
+      - type: uint_ulk_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
   - name: roundhk
     standards:
       - stdc_ext

diff  --git a/libc/spec/stdc_ext.td b/libc/spec/stdc_ext.td
index 6620142146c471..fc9c9cf85818b5 100644
--- a/libc/spec/stdc_ext.td
+++ b/libc/spec/stdc_ext.td
@@ -15,13 +15,26 @@ def UnsignedShortAccumType : NamedType<"unsigned short accum">;
 def UnsignedAccumType : NamedType<"unsigned accum">;
 def UnsignedLongAccumType : NamedType<"unsigned long accum">;
 
+def IntHrT : NamedType <"int_hr_t">; 
+def IntRT : NamedTypes<"int_r_t">;
+def IntLrT : NamedType<"int_lr_t">;
+def IntHkT : NamedType<"int_hk_t">;
+def IntKT : NamedType<"int_k_t">;
+def IntLkT : NamedType<"int_lk_t">;
+def UIntUhrT : NamedType<"uint_uhr_t">;
+def UIntUrT : NamedType<"uint_ur_t">;
+def UIntUlrT : NamedType<"uint_ulr_t">;
+def UIntUhkT : NamedType<"uint_uhk_t">;
+def UIntUkT : NamedType<"uint_uk_t">;
+def UIntUlkT : NamedType<"uint_ulk_t">;
+
 def StdcExt : StandardSpec<"stdc_ext"> {
   // From ISO/IEC TR 18037:2008 standard:
   // https://standards.iso.org/ittf/PubliclyAvailableStandards/c051126_ISO_IEC_TR_18037_2008.zip
   HeaderSpec StdFix = HeaderSpec<
       "stdfix.h",
       [],  // macros
-      [],  // types
+      [IntHrT,IntRT, IntLrT, IntHkT, IntKT, IntLkT, UIntUhrT, UIntUrT, UIntUlrT, UIntUhkT, UIntUkT, UIntUlkT],  // types
       [],  // enums
       [    // functions
           GuardedFunctionSpec<"abshr", RetValSpec<ShortFractType>, [ArgSpec<ShortFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
@@ -47,6 +60,19 @@ def StdcExt : StandardSpec<"stdc_ext"> {
           GuardedFunctionSpec<"rounduhk", RetValSpec<UnsignedShortAccumType>, [ArgSpec<UnsignedShortAccumType>, ArgSpec<IntType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
           GuardedFunctionSpec<"rounduk", RetValSpec<UnsignedAccumType>, [ArgSpec<UnsignedAccumType>, ArgSpec<IntType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
           GuardedFunctionSpec<"roundulk", RetValSpec<UnsignedLongAccumType>, [ArgSpec<UnsignedLongAccumType>, ArgSpec<IntType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
+
+          GuardedFunctionSpec<"hrbits", RetValSpec<ShortFractType>, [ArgSpec<IntHrT>], "LIBC_COMPILER_HAS_FIXED_POINT">,
+          GuardedFunctionSpec<"rbits", RetValSpec<FractType>, [ArgSpec<IntRT>], "LIBC_COMPILER_HAS_FIXED_POINT">,
+          GuardedFunctionSpec<"lrbits", RetValSpec<LongFractType>, [ArgSpec<IntLrT>], "LIBC_COMPILER_HAS_FIXED_POINT">,
+          GuardedFunctionSpec<"hkbits", RetValSpec<ShortAccumType>, [ArgSpec<IntHkT>], "LIBC_COMPILER_HAS_FIXED_POINT">,
+          GuardedFunctionSpec<"kbits", RetValSpec<AccumType>, [ArgSpec<IntKT>], "LIBC_COMPILER_HAS_FIXED_POINT">,
+          GuardedFunctionSpec<"lkbits", RetValSpec<LongAccumType>, [ArgSpec<IntLkT>], "LIBC_COMPILER_HAS_FIXED_POINT">,
+          GuardedFunctionSpec<"uhrbits", RetValSpec<UnsignedShortFractType>, [ArgSpec<UIntUhrT>], "LIBC_COMPILER_HAS_FIXED_POINT">,
+          GuardedFunctionSpec<"urbits", RetValSpec<UnsignedFractType>, [ArgSpec<UIntUrT>], "LIBC_COMPILER_HAS_FIXED_POINT">,
+          GuardedFunctionSpec<"ukbits", RetValSpec<UnsignedAccumType>, [ArgSpec<UIntUkT>], "LIBC_COMPILER_HAS_FIXED_POINT">
+          GuardedFunctionSpec<"ulrbits", RetValSpec<UnsignedLongFractType>, [ArgSpec<UIntUlrT>], "LIBC_COMPILER_HAS_FIXED_POINT">,
+          GuardedFunctionSpec<"uhkbits", RetValSpec<UnsignedShortAccumType>, [ArgSpec<UIntUhkT>], "LIBC_COMPILER_HAS_FIXED_POINT">
+          GuardedFunctionSpec<"ulkbits", RetValSpec<UnsignedLongAccumType>, [ArgSpec<UIntUlkT>], "LIBC_COMPILER_HAS_FIXED_POINT">
       ]
   >;
 

diff  --git a/libc/src/__support/fixed_point/fx_bits.h b/libc/src/__support/fixed_point/fx_bits.h
index 0a4c21fb6a14f7..225ea417760a03 100644
--- a/libc/src/__support/fixed_point/fx_bits.h
+++ b/libc/src/__support/fixed_point/fx_bits.h
@@ -12,7 +12,7 @@
 #include "include/llvm-libc-macros/stdfix-macros.h"
 #include "src/__support/CPP/bit.h"
 #include "src/__support/CPP/type_traits.h"
-#include "src/__support/macros/attributes.h"   // LIBC_INLINE
+#include "src/__support/macros/attributes.h" // LIBC_INLINE
 #include "src/__support/macros/config.h"
 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
 #include "src/__support/math_extras.h"

diff  --git a/libc/src/stdfix/CMakeLists.txt b/libc/src/stdfix/CMakeLists.txt
index 10d76ae31349f9..238b86728188ad 100644
--- a/libc/src/stdfix/CMakeLists.txt
+++ b/libc/src/stdfix/CMakeLists.txt
@@ -42,6 +42,17 @@ foreach(suffix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
     DEPENDS
       libc.src.__support.fixed_point.fx_bits
   )
+
+  add_entrypoint_object(
+    ${suffix}bits
+    HDRS
+      ${suffix}bits.h
+    SRCS
+      ${suffix}bits.cpp
+    DEPENDS
+      libc.src.__support.CPP.bit
+      libc.src.__support.fixed_point.fx_bits
+  )
 endforeach()
 
 add_entrypoint_object(

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

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

diff  --git a/libc/src/stdfix/hrbits.cpp b/libc/src/stdfix/hrbits.cpp
new file mode 100644
index 00000000000000..cc314fee51b11d
--- /dev/null
+++ b/libc/src/stdfix/hrbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of hrbits 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 "hrbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(short fract, hrbits, (int_hr_t x)) {
+  return cpp::bit_cast<short fract, int_hr_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

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

diff  --git a/libc/src/stdfix/kbits.cpp b/libc/src/stdfix/kbits.cpp
new file mode 100644
index 00000000000000..61fd4f656db27d
--- /dev/null
+++ b/libc/src/stdfix/kbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of kbits 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 "kbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(accum, kbits, (int_k_t x)) {
+  return cpp::bit_cast<accum, int_k_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/kbits.h b/libc/src/stdfix/kbits.h
new file mode 100644
index 00000000000000..7e709af442466a
--- /dev/null
+++ b/libc/src/stdfix/kbits.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for kbits -------------------------*- 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_KBITS_H
+#define LLVM_LIBC_SRC_STDFIX_KBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "include/llvm-libc-types/stdfix-types.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+accum kbits(int_k_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_KBITS_H

diff  --git a/libc/src/stdfix/lkbits.cpp b/libc/src/stdfix/lkbits.cpp
new file mode 100644
index 00000000000000..83f3433c26f614
--- /dev/null
+++ b/libc/src/stdfix/lkbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of lkbits 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 "lkbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(long accum, lkbits, (int_lk_t x)) {
+  return cpp::bit_cast<long accum, int_lk_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/lkbits.h b/libc/src/stdfix/lkbits.h
new file mode 100644
index 00000000000000..177f121e2358e8
--- /dev/null
+++ b/libc/src/stdfix/lkbits.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for lkbits ------------------------*- 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_LKBITS_H
+#define LLVM_LIBC_SRC_STDFIX_LKBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "include/llvm-libc-types/stdfix-types.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+long accum lkbits(int_lk_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_LKBITS_H

diff  --git a/libc/src/stdfix/lrbits.cpp b/libc/src/stdfix/lrbits.cpp
new file mode 100644
index 00000000000000..a726816813b411
--- /dev/null
+++ b/libc/src/stdfix/lrbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of lrbits 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 "lrbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(long fract, lrbits, (int_lr_t x)) {
+  return cpp::bit_cast<long fract, int_lr_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/lrbits.h b/libc/src/stdfix/lrbits.h
new file mode 100644
index 00000000000000..087aa19779e62c
--- /dev/null
+++ b/libc/src/stdfix/lrbits.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for lrbits ------------------------*- 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_LRBITS_H
+#define LLVM_LIBC_SRC_STDFIX_LRBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "include/llvm-libc-types/stdfix-types.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+long fract lrbits(int_lr_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_LRBITS_H

diff  --git a/libc/src/stdfix/rbits.cpp b/libc/src/stdfix/rbits.cpp
new file mode 100644
index 00000000000000..c31df6e88b832d
--- /dev/null
+++ b/libc/src/stdfix/rbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of rbits 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 "rbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(fract, rbits, (int_r_t x)) {
+  return cpp::bit_cast<fract, int_r_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/rbits.h b/libc/src/stdfix/rbits.h
new file mode 100644
index 00000000000000..4922e1c3a2e5fa
--- /dev/null
+++ b/libc/src/stdfix/rbits.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for rbits -------------------------*- 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_RBITS_H
+#define LLVM_LIBC_SRC_STDFIX_RBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "include/llvm-libc-types/stdfix-types.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+fract rbits(int_r_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_RBITS_H

diff  --git a/libc/src/stdfix/uhkbits.cpp b/libc/src/stdfix/uhkbits.cpp
new file mode 100644
index 00000000000000..8a91c414312ba5
--- /dev/null
+++ b/libc/src/stdfix/uhkbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of uhkbits 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 "uhkbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(unsigned short accum, uhkbits, (uint_uhk_t x)) {
+  return cpp::bit_cast<unsigned short accum, uint_uhk_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/uhkbits.h b/libc/src/stdfix/uhkbits.h
new file mode 100644
index 00000000000000..7ef15986f696ce
--- /dev/null
+++ b/libc/src/stdfix/uhkbits.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for uhkbits -----------------------*- 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_UHKBITS_H
+#define LLVM_LIBC_SRC_STDFIX_UHKBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "include/llvm-libc-types/stdfix-types.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned short accum uhkbits(uint_uhk_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_UHKBITS_H

diff  --git a/libc/src/stdfix/uhrbits.cpp b/libc/src/stdfix/uhrbits.cpp
new file mode 100644
index 00000000000000..fd6bb1349134d0
--- /dev/null
+++ b/libc/src/stdfix/uhrbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of uhrbits 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 "uhrbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(unsigned short fract, uhrbits, (uint_uhr_t x)) {
+  return cpp::bit_cast<unsigned short fract, uint_uhr_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/uhrbits.h b/libc/src/stdfix/uhrbits.h
new file mode 100644
index 00000000000000..4011a0e118c7bc
--- /dev/null
+++ b/libc/src/stdfix/uhrbits.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for uhrbits -----------------------*- 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_UHRBITS_H
+#define LLVM_LIBC_SRC_STDFIX_UHRBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "include/llvm-libc-types/stdfix-types.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned short fract uhrbits(uint_uhr_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_UHRBITS_H

diff  --git a/libc/src/stdfix/ukbits.cpp b/libc/src/stdfix/ukbits.cpp
new file mode 100644
index 00000000000000..f83a354946cac9
--- /dev/null
+++ b/libc/src/stdfix/ukbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of ukbits 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 "ukbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(unsigned accum, ukbits, (uint_uk_t x)) {
+  return cpp::bit_cast<unsigned accum, uint_uk_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/ukbits.h b/libc/src/stdfix/ukbits.h
new file mode 100644
index 00000000000000..2374f48a4dbb69
--- /dev/null
+++ b/libc/src/stdfix/ukbits.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for ukbits ------------------------*- 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_UKBITS_H
+#define LLVM_LIBC_SRC_STDFIX_UKBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "include/llvm-libc-types/stdfix-types.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned accum ukbits(uint_uk_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_UKBITS_H

diff  --git a/libc/src/stdfix/ulkbits.cpp b/libc/src/stdfix/ulkbits.cpp
new file mode 100644
index 00000000000000..eaf4057bb2ae76
--- /dev/null
+++ b/libc/src/stdfix/ulkbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of ulkbits 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 "ulkbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(unsigned long accum, ulkbits, (uint_ulk_t x)) {
+  return cpp::bit_cast<unsigned long accum, uint_ulk_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/ulkbits.h b/libc/src/stdfix/ulkbits.h
new file mode 100644
index 00000000000000..955c96c6a49577
--- /dev/null
+++ b/libc/src/stdfix/ulkbits.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for ulkbits -----------------------*- 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_ULKBITS_H
+#define LLVM_LIBC_SRC_STDFIX_ULKBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "include/llvm-libc-types/stdfix-types.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned long accum ulkbits(uint_ulk_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_ULKBITS_H

diff  --git a/libc/src/stdfix/ulrbits.cpp b/libc/src/stdfix/ulrbits.cpp
new file mode 100644
index 00000000000000..92f34705e9e571
--- /dev/null
+++ b/libc/src/stdfix/ulrbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of ulrbits 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 "ulrbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(unsigned long fract, ulrbits, (uint_ulr_t x)) {
+  return cpp::bit_cast<unsigned long fract, uint_ulr_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/ulrbits.h b/libc/src/stdfix/ulrbits.h
new file mode 100644
index 00000000000000..7ae49ba212b720
--- /dev/null
+++ b/libc/src/stdfix/ulrbits.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for ulrbits -----------------------*- 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_ULRBITS_H
+#define LLVM_LIBC_SRC_STDFIX_ULRBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "include/llvm-libc-types/stdfix-types.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned long fract ulrbits(uint_ulr_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_ULRBITS_H

diff  --git a/libc/src/stdfix/urbits.cpp b/libc/src/stdfix/urbits.cpp
new file mode 100644
index 00000000000000..25801e31259007
--- /dev/null
+++ b/libc/src/stdfix/urbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of urbits 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 "urbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(unsigned fract, urbits, (uint_ur_t x)) {
+  return cpp::bit_cast<unsigned fract, uint_ur_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/stdfix/urbits.h b/libc/src/stdfix/urbits.h
new file mode 100644
index 00000000000000..8fc0881cf645b9
--- /dev/null
+++ b/libc/src/stdfix/urbits.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for urbits ------------------------*- 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_URBITS_H
+#define LLVM_LIBC_SRC_STDFIX_URBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "include/llvm-libc-types/stdfix-types.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned fract urbits(uint_ur_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_URBITS_H

diff  --git a/libc/test/src/stdfix/CMakeLists.txt b/libc/test/src/stdfix/CMakeLists.txt
index 74a1fb13127cc3..60e38c9098c387 100644
--- a/libc/test/src/stdfix/CMakeLists.txt
+++ b/libc/test/src/stdfix/CMakeLists.txt
@@ -57,6 +57,22 @@ foreach(suffix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
       libc.src.stdfix.round${suffix}
       libc.src.__support.fixed_point.fx_bits
   )
+  
+  add_libc_test(
+    ${suffix}bits_test
+    SUITE
+      libc-stdfix-tests
+    HDRS
+      FxBitsTest.h
+    SRCS
+      ${suffix}bits_test.cpp
+    COMPILE_OPTIONS
+      -O3
+    DEPENDS
+      libc.src.stdfix.${suffix}bits
+      libc.src.__support.CPP.bit
+      libc.src.__support.fixed_point.fx_bits
+  )
 endforeach()
 
 add_libc_test(

diff  --git a/libc/test/src/stdfix/FxBitsTest.h b/libc/test/src/stdfix/FxBitsTest.h
new file mode 100644
index 00000000000000..ae04cc145f271c
--- /dev/null
+++ b/libc/test/src/stdfix/FxBitsTest.h
@@ -0,0 +1,55 @@
+//===-- Utility class to test int to fixed point conversions ----*- 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 "include/llvm-libc-types/stdfix-types.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/fixed_point/fx_bits.h"
+
+template <typename T, typename XType>
+class FxBitsTest : public LIBC_NAMESPACE::testing::Test {
+  using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<T>;
+  static constexpr T zero = FXRep::ZERO();
+  static constexpr T min = FXRep::MIN();
+  static constexpr T max = FXRep::MAX();
+  static constexpr T half = static_cast<T>(0.5);
+  static constexpr T quarter = static_cast<T>(0.25);
+  static constexpr T one =
+      (FXRep::INTEGRAL_LEN > 0) ? static_cast<T>(1) : FXRep::MAX();
+  static constexpr T eps = FXRep::EPS();
+  constexpr XType get_one_or_saturated_fraction() {
+    if (FXRep::INTEGRAL_LEN > 0) {
+      return static_cast<XType>(static_cast<XType>(0x1) << FXRep::FRACTION_LEN);
+    } else {
+      return static_cast<XType>(
+          LIBC_NAMESPACE::mask_trailing_ones<typename FXRep::StorageType,
+                                             FXRep::FRACTION_LEN>());
+    }
+  }
+
+public:
+  typedef T (*FxBitsFunc)(XType);
+
+  void test_special_numbers(FxBitsFunc func) {
+    EXPECT_EQ(zero, func(0));
+    EXPECT_EQ(eps, func(0x1));
+    // x.1000...
+    EXPECT_EQ(half, func(static_cast<XType>(0x1) << (FXRep::FRACTION_LEN - 1)));
+    // Occupy the bit to the left of the fixed point for Accum types
+    // Saturate fraction portion for Fract types
+    EXPECT_EQ(one, func(get_one_or_saturated_fraction()));
+  }
+};
+
+#define LIST_FXBITS_TEST(Name, T, XType, func)                                 \
+  using LlvmLibc##Name##BitsTest = FxBitsTest<T, XType>;                       \
+  TEST_F(LlvmLibc##Name##BitsTest, SpecialNumbers) {                           \
+    test_special_numbers(&func);                                               \
+  }                                                                            \
+  static_assert(true, "Require semicolon.")

diff  --git a/libc/test/src/stdfix/hkbits_test.cpp b/libc/test/src/stdfix/hkbits_test.cpp
new file mode 100644
index 00000000000000..c4b55e13502b55
--- /dev/null
+++ b/libc/test/src/stdfix/hkbits_test.cpp
@@ -0,0 +1,12 @@
+//===-- Unittests for hkbits ----------------------------------------------===//
+//
+// 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 "FxBitsTest.h"
+#include "src/stdfix/hkbits.h"
+
+LIST_FXBITS_TEST(hk, short accum, int_hk_t, LIBC_NAMESPACE::hkbits);

diff  --git a/libc/test/src/stdfix/hrbits_test.cpp b/libc/test/src/stdfix/hrbits_test.cpp
new file mode 100644
index 00000000000000..d47456a8b1d6ed
--- /dev/null
+++ b/libc/test/src/stdfix/hrbits_test.cpp
@@ -0,0 +1,12 @@
+//===-- Unittests for hrbits ----------------------------------------------===//
+//
+// 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 "FxBitsTest.h"
+#include "src/stdfix/hrbits.h"
+
+LIST_FXBITS_TEST(hr, short fract, int_hr_t, LIBC_NAMESPACE::hrbits);

diff  --git a/libc/test/src/stdfix/kbits_test.cpp b/libc/test/src/stdfix/kbits_test.cpp
new file mode 100644
index 00000000000000..f646e13badc8f2
--- /dev/null
+++ b/libc/test/src/stdfix/kbits_test.cpp
@@ -0,0 +1,12 @@
+//===-- Unittests for kbits -----------------------------------------------===//
+//
+// 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 "FxBitsTest.h"
+#include "src/stdfix/kbits.h"
+
+LIST_FXBITS_TEST(k, accum, int_k_t, LIBC_NAMESPACE::kbits);

diff  --git a/libc/test/src/stdfix/lkbits_test.cpp b/libc/test/src/stdfix/lkbits_test.cpp
new file mode 100644
index 00000000000000..f8fd3a69a2b739
--- /dev/null
+++ b/libc/test/src/stdfix/lkbits_test.cpp
@@ -0,0 +1,12 @@
+//===-- Unittests for lkbits ----------------------------------------------===//
+//
+// 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 "FxBitsTest.h"
+#include "src/stdfix/lkbits.h"
+
+LIST_FXBITS_TEST(lk, long accum, int_lk_t, LIBC_NAMESPACE::lkbits);

diff  --git a/libc/test/src/stdfix/lrbits_test.cpp b/libc/test/src/stdfix/lrbits_test.cpp
new file mode 100644
index 00000000000000..881a8c980642bf
--- /dev/null
+++ b/libc/test/src/stdfix/lrbits_test.cpp
@@ -0,0 +1,12 @@
+//===-- Unittests for lrbits ----------------------------------------------===//
+//
+// 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 "FxBitsTest.h"
+#include "src/stdfix/lrbits.h"
+
+LIST_FXBITS_TEST(lr, long fract, int_lr_t, LIBC_NAMESPACE::lrbits);

diff  --git a/libc/test/src/stdfix/rbits_test.cpp b/libc/test/src/stdfix/rbits_test.cpp
new file mode 100644
index 00000000000000..12c95a5816a2e2
--- /dev/null
+++ b/libc/test/src/stdfix/rbits_test.cpp
@@ -0,0 +1,12 @@
+//===-- Unittests for rbits -----------------------------------------------===//
+//
+// 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 "FxBitsTest.h"
+#include "src/stdfix/rbits.h"
+
+LIST_FXBITS_TEST(r, fract, int_r_t, LIBC_NAMESPACE::rbits);

diff  --git a/libc/test/src/stdfix/uhkbits_test.cpp b/libc/test/src/stdfix/uhkbits_test.cpp
new file mode 100644
index 00000000000000..b57e23b1cffd64
--- /dev/null
+++ b/libc/test/src/stdfix/uhkbits_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for uhkbits ---------------------------------------------===//
+//
+// 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 "FxBitsTest.h"
+#include "src/stdfix/uhkbits.h"
+
+LIST_FXBITS_TEST(uhk, unsigned short accum, uint_uhk_t,
+                 LIBC_NAMESPACE::uhkbits);

diff  --git a/libc/test/src/stdfix/uhrbits_test.cpp b/libc/test/src/stdfix/uhrbits_test.cpp
new file mode 100644
index 00000000000000..1a9d2c6cecca20
--- /dev/null
+++ b/libc/test/src/stdfix/uhrbits_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for uhrbits ---------------------------------------------===//
+//
+// 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 "FxBitsTest.h"
+#include "src/stdfix/uhrbits.h"
+
+LIST_FXBITS_TEST(uhr, unsigned short fract, uint_uhr_t,
+                 LIBC_NAMESPACE::uhrbits);

diff  --git a/libc/test/src/stdfix/ukbits_test.cpp b/libc/test/src/stdfix/ukbits_test.cpp
new file mode 100644
index 00000000000000..bad707f49474b8
--- /dev/null
+++ b/libc/test/src/stdfix/ukbits_test.cpp
@@ -0,0 +1,12 @@
+//===-- Unittests for ukbits ----------------------------------------------===//
+//
+// 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 "FxBitsTest.h"
+#include "src/stdfix/ukbits.h"
+
+LIST_FXBITS_TEST(uk, unsigned accum, uint_uk_t, LIBC_NAMESPACE::ukbits);

diff  --git a/libc/test/src/stdfix/ulkbits_test.cpp b/libc/test/src/stdfix/ulkbits_test.cpp
new file mode 100644
index 00000000000000..3ee54be4c4f003
--- /dev/null
+++ b/libc/test/src/stdfix/ulkbits_test.cpp
@@ -0,0 +1,12 @@
+//===-- Unittests for ulkbits ---------------------------------------------===//
+//
+// 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 "FxBitsTest.h"
+#include "src/stdfix/ulkbits.h"
+
+LIST_FXBITS_TEST(ulk, unsigned long accum, uint_ulk_t, LIBC_NAMESPACE::ulkbits);

diff  --git a/libc/test/src/stdfix/ulrbits_test.cpp b/libc/test/src/stdfix/ulrbits_test.cpp
new file mode 100644
index 00000000000000..a248deb6e5aad3
--- /dev/null
+++ b/libc/test/src/stdfix/ulrbits_test.cpp
@@ -0,0 +1,12 @@
+//===-- Unittests for ulrbits ---------------------------------------------===//
+//
+// 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 "FxBitsTest.h"
+#include "src/stdfix/ulrbits.h"
+
+LIST_FXBITS_TEST(ulr, unsigned long fract, uint_ulr_t, LIBC_NAMESPACE::ulrbits);

diff  --git a/libc/test/src/stdfix/urbits_test.cpp b/libc/test/src/stdfix/urbits_test.cpp
new file mode 100644
index 00000000000000..285b0170a3bf38
--- /dev/null
+++ b/libc/test/src/stdfix/urbits_test.cpp
@@ -0,0 +1,12 @@
+//===-- Unittests for urbits ----------------------------------------------===//
+//
+// 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 "FxBitsTest.h"
+#include "src/stdfix/urbits.h"
+
+LIST_FXBITS_TEST(ur, unsigned fract, uint_ur_t, LIBC_NAMESPACE::urbits);


        


More information about the libc-commits mailing list