[libc-commits] [libc] [libc][stdfix] Implement fixed point fxbits functions in llvm libc (PR #114694)
William Tran-Viet via libc-commits
libc-commits at lists.llvm.org
Sat Nov 2 21:24:29 PDT 2024
https://github.com/smallp-o-p created https://github.com/llvm/llvm-project/pull/114694
Still a bit unsure on the base type choices for the u?int_fx_t types, would like some input on that.
>From 5525a44c1213aa414b80a2798572b38cb6800703 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Wed, 30 Oct 2024 17:55:31 -0400
Subject: [PATCH 1/9] Add fxbits functions to be generated into stdfix.h: Add
each function to stdfix.yaml, and to entrypoints.txt for each target that
supports stdfix. Also create files to be filled in.
---
libc/config/baremetal/arm/entrypoints.txt | 12 +++
libc/config/baremetal/riscv/entrypoints.txt | 12 +++
libc/config/linux/riscv/entrypoints.txt | 12 +++
libc/config/linux/x86_64/entrypoints.txt | 12 +++
libc/newhdrgen/yaml/stdfix.yaml | 87 ++++++++++++++++++++-
libc/src/stdfix/CMakeLists.txt | 14 ++++
libc/src/stdfix/hkbits.cpp | 0
libc/src/stdfix/hkbits.h | 0
libc/src/stdfix/hrbits.cpp | 12 +++
libc/src/stdfix/hrbits.h | 11 +++
libc/src/stdfix/kbits.cpp | 0
libc/src/stdfix/kbits.h | 0
libc/src/stdfix/lkbits.cpp | 0
libc/src/stdfix/lkbits.h | 0
libc/src/stdfix/lrbits.cpp | 0
libc/src/stdfix/lrbits.h | 0
libc/src/stdfix/rbits.cpp | 0
libc/src/stdfix/rbits.h | 0
libc/src/stdfix/uhkbits.cpp | 0
libc/src/stdfix/uhkbits.h | 0
libc/src/stdfix/uhrbits.cpp | 0
libc/src/stdfix/uhrbits.h | 0
libc/src/stdfix/ukbits.cpp | 0
libc/src/stdfix/ukbits.h | 0
libc/src/stdfix/ulkbits.cpp | 0
libc/src/stdfix/ulkbits.h | 0
libc/src/stdfix/ulrbits.cpp | 0
libc/src/stdfix/ulrbits.h | 0
libc/src/stdfix/urbits.cpp | 0
libc/src/stdfix/urbits.h | 0
30 files changed, 171 insertions(+), 1 deletion(-)
create mode 100644 libc/src/stdfix/hkbits.cpp
create mode 100644 libc/src/stdfix/hkbits.h
create mode 100644 libc/src/stdfix/hrbits.cpp
create mode 100644 libc/src/stdfix/hrbits.h
create mode 100644 libc/src/stdfix/kbits.cpp
create mode 100644 libc/src/stdfix/kbits.h
create mode 100644 libc/src/stdfix/lkbits.cpp
create mode 100644 libc/src/stdfix/lkbits.h
create mode 100644 libc/src/stdfix/lrbits.cpp
create mode 100644 libc/src/stdfix/lrbits.h
create mode 100644 libc/src/stdfix/rbits.cpp
create mode 100644 libc/src/stdfix/rbits.h
create mode 100644 libc/src/stdfix/uhkbits.cpp
create mode 100644 libc/src/stdfix/uhkbits.h
create mode 100644 libc/src/stdfix/uhrbits.cpp
create mode 100644 libc/src/stdfix/uhrbits.h
create mode 100644 libc/src/stdfix/ukbits.cpp
create mode 100644 libc/src/stdfix/ukbits.h
create mode 100644 libc/src/stdfix/ulkbits.cpp
create mode 100644 libc/src/stdfix/ulkbits.h
create mode 100644 libc/src/stdfix/ulrbits.cpp
create mode 100644 libc/src/stdfix/ulrbits.h
create mode 100644 libc/src/stdfix/urbits.cpp
create mode 100644 libc/src/stdfix/urbits.h
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 68030f7f1775b5..b85ae1119345dd 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -455,6 +455,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 5894b591072ef0..199a030ee6371e 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -450,6 +450,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 5c09edf7cfb266..7263f69fb08268 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -704,6 +704,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 a2fb97d04584d5..536884779c433e 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -808,6 +808,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/newhdrgen/yaml/stdfix.yaml b/libc/newhdrgen/yaml/stdfix.yaml
index ca6658939e2278..72a9c7cc774eeb 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_t
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/src/stdfix/CMakeLists.txt b/libc/src/stdfix/CMakeLists.txt
index 10d76ae31349f9..cac0e15dbdf349 100644
--- a/libc/src/stdfix/CMakeLists.txt
+++ b/libc/src/stdfix/CMakeLists.txt
@@ -44,6 +44,20 @@ foreach(suffix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
)
endforeach()
+foreach(prefix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
+ add_entrypoint_object(
+ ${prefix}bits
+ HDRS
+ ${prefix}bits.h
+ SRCS
+ ${prefix}bits.cpp
+ COMPILE_OPTIONS
+ -O3
+ DEPENDS
+ libc.src.__support.fixed_point.fx_bits
+ )
+endforeach()
+
add_entrypoint_object(
uhksqrtus
HDRS
diff --git a/libc/src/stdfix/hkbits.cpp b/libc/src/stdfix/hkbits.cpp
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/hkbits.h b/libc/src/stdfix/hkbits.h
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/hrbits.cpp b/libc/src/stdfix/hrbits.cpp
new file mode 100644
index 00000000000000..cd7fbb9648d5b0
--- /dev/null
+++ b/libc/src/stdfix/hrbits.cpp
@@ -0,0 +1,12 @@
+#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 fixed_point::bits(x);
+}
+
+}
diff --git a/libc/src/stdfix/hrbits.h b/libc/src/stdfix/hrbits.h
new file mode 100644
index 00000000000000..e66192b8ee4d2d
--- /dev/null
+++ b/libc/src/stdfix/hrbits.h
@@ -0,0 +1,11 @@
+#ifndef LLVM_LIBC_SRC_STDFIX_HRBITS_H
+#define LLVM_LIBC_SRC_STDFIX_HRBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+namespace LIBC_NAMESPACE_DECL {
+
+short fract hrbits(int_hr_t x);
+
+}
+#endif
diff --git a/libc/src/stdfix/kbits.cpp b/libc/src/stdfix/kbits.cpp
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/kbits.h b/libc/src/stdfix/kbits.h
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/lkbits.cpp b/libc/src/stdfix/lkbits.cpp
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/lkbits.h b/libc/src/stdfix/lkbits.h
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/lrbits.cpp b/libc/src/stdfix/lrbits.cpp
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/lrbits.h b/libc/src/stdfix/lrbits.h
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/rbits.cpp b/libc/src/stdfix/rbits.cpp
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/rbits.h b/libc/src/stdfix/rbits.h
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/uhkbits.cpp b/libc/src/stdfix/uhkbits.cpp
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/uhkbits.h b/libc/src/stdfix/uhkbits.h
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/uhrbits.cpp b/libc/src/stdfix/uhrbits.cpp
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/uhrbits.h b/libc/src/stdfix/uhrbits.h
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/ukbits.cpp b/libc/src/stdfix/ukbits.cpp
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/ukbits.h b/libc/src/stdfix/ukbits.h
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/ulkbits.cpp b/libc/src/stdfix/ulkbits.cpp
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/ulkbits.h b/libc/src/stdfix/ulkbits.h
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/ulrbits.cpp b/libc/src/stdfix/ulrbits.cpp
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/ulrbits.h b/libc/src/stdfix/ulrbits.h
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/urbits.cpp b/libc/src/stdfix/urbits.cpp
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/src/stdfix/urbits.h b/libc/src/stdfix/urbits.h
new file mode 100644
index 00000000000000..e69de29bb2d1d6
>From 63fe052d1ab25a20190c0821d658ee50235d2c13 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Wed, 30 Oct 2024 18:39:35 -0400
Subject: [PATCH 2/9] Add uint and int typedefs for arguments passed into
fxbits(). Should come back to this later.
---
libc/include/llvm-libc-macros/stdfix-macros.h | 13 +++++++++++++
libc/newhdrgen/yaml/stdfix.yaml | 3 +--
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/libc/include/llvm-libc-macros/stdfix-macros.h b/libc/include/llvm-libc-macros/stdfix-macros.h
index 554ebe544a42ed..9be7584dbaee04 100644
--- a/libc/include/llvm-libc-macros/stdfix-macros.h
+++ b/libc/include/llvm-libc-macros/stdfix-macros.h
@@ -323,6 +323,19 @@
#define ULACCUM_EPSILON 0x1.0p-32ULK
#endif // ULACCUM_EPSILON
+typedef signed char int_hr_t;
+typedef unsigned char uint_uhr_t;
+typedef signed short int int_r_t;
+typedef unsigned short int uint_ur_t;
+typedef signed int int_lr_t;
+typedef unsigned int uint_ulr_t;
+typedef signed short int_hk_t;
+typedef unsigned short uint_uhk_t;
+typedef signed int int_k_t;
+typedef unsigned int uint_uk_t;
+typedef signed long int_lk_t;
+typedef unsigned long uint_ulk_t;
+
#endif // LIBC_COMPILER_HAS_FIXED_POINT
#endif // LLVM_LIBC_MACROS_STDFIX_MACROS_H
diff --git a/libc/newhdrgen/yaml/stdfix.yaml b/libc/newhdrgen/yaml/stdfix.yaml
index 72a9c7cc774eeb..02fb7adb1fed8c 100644
--- a/libc/newhdrgen/yaml/stdfix.yaml
+++ b/libc/newhdrgen/yaml/stdfix.yaml
@@ -1,7 +1,6 @@
header: stdfix.h
macros: []
-types:
- - type_name: stdfix_t
+types: []
enums: []
objects: []
functions:
>From 072b6f27c9c01ca1035f418c8be7124463e3c6d8 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Wed, 30 Oct 2024 22:10:57 -0400
Subject: [PATCH 3/9] Implement fxbits()
---
libc/src/__support/fixed_point/fx_bits.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/libc/src/__support/fixed_point/fx_bits.h b/libc/src/__support/fixed_point/fx_bits.h
index 0a4c21fb6a14f7..448845103ccddb 100644
--- a/libc/src/__support/fixed_point/fx_bits.h
+++ b/libc/src/__support/fixed_point/fx_bits.h
@@ -163,6 +163,13 @@ template <typename T> LIBC_INLINE constexpr T round(T x, int n) {
return bit_and((x + round_bit), rounding_mask);
}
+// u?int_fx_t --> Fixed point
+template <typename T, typename XType> LIBC_INLINE constexpr T fxbits(XType x) {
+ // Example: rbits(0x2000) where fract has 15 fractional bits,
+ // 0x2000 --> 0010 0000 0000 0000 --> 0.010 0000 0000 0000 = 0.25
+
+ return cpp::bit_cast<T, XType>(x);
+}
} // namespace fixed_point
} // namespace LIBC_NAMESPACE_DECL
>From cba0fe09c918ab91929bf4310c42ea0dee9bbcbc Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Wed, 30 Oct 2024 22:11:33 -0400
Subject: [PATCH 4/9] Implement rbits and add a test fixture
---
libc/src/stdfix/rbits.cpp | 13 ++++++++++
libc/src/stdfix/rbits.h | 12 ++++++++++
libc/test/src/stdfix/CMakeLists.txt | 17 +++++++++++++
libc/test/src/stdfix/FxbitsTest.h | 37 +++++++++++++++++++++++++++++
libc/test/src/stdfix/rbits_test.cpp | 7 ++++++
5 files changed, 86 insertions(+)
create mode 100644 libc/test/src/stdfix/FxbitsTest.h
create mode 100644 libc/test/src/stdfix/rbits_test.cpp
diff --git a/libc/src/stdfix/rbits.cpp b/libc/src/stdfix/rbits.cpp
index e69de29bb2d1d6..9a2fd3a2f82469 100644
--- a/libc/src/stdfix/rbits.cpp
+++ b/libc/src/stdfix/rbits.cpp
@@ -0,0 +1,13 @@
+#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 fixed_point::fxbits<fract, int_r_t>(x);
+}
+
+}
diff --git a/libc/src/stdfix/rbits.h b/libc/src/stdfix/rbits.h
index e69de29bb2d1d6..4ac494d7ce530b 100644
--- a/libc/src/stdfix/rbits.h
+++ b/libc/src/stdfix/rbits.h
@@ -0,0 +1,12 @@
+#ifndef LLVM_LIBC_SRC_STDFIX_HRBITS_H
+#define LLVM_LIBC_SRC_STDFIX_HRBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+namespace LIBC_NAMESPACE_DECL {
+
+fract rbits(int_r_t x);
+
+}
+
+#endif
diff --git a/libc/test/src/stdfix/CMakeLists.txt b/libc/test/src/stdfix/CMakeLists.txt
index 74a1fb13127cc3..d7369885335cf8 100644
--- a/libc/test/src/stdfix/CMakeLists.txt
+++ b/libc/test/src/stdfix/CMakeLists.txt
@@ -59,6 +59,23 @@ foreach(suffix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
)
endforeach()
+foreach(prefix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
+ add_libc_test(
+ ${prefix}bits_test
+ SUITE
+ libc-stdfix-tests
+ HDRS
+ FxbitsTest.h
+ SRCS
+ ${prefix}bits_test.cpp
+ COMPILE_OPTIONS
+ -O3
+ DEPENDS
+ libc.src.stdfix.${prefix}bits
+ libc.src.__support.fixed_point.fx_bits
+ )
+endforeach()
+
add_libc_test(
uhksqrtus_test
SUITE
diff --git a/libc/test/src/stdfix/FxbitsTest.h b/libc/test/src/stdfix/FxbitsTest.h
new file mode 100644
index 00000000000000..d698f140a690a5
--- /dev/null
+++ b/libc/test/src/stdfix/FxbitsTest.h
@@ -0,0 +1,37 @@
+//===-- Utility class to test fxbits -----------------*- 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 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 neg_half = static_cast<T>(-0.5);
+ static constexpr T one =
+ (FXRep::INTEGRAL_LEN > 0) ? static_cast<T>(1) : FXRep::MAX();
+ static constexpr T neg_one = static_cast<T>(-1);
+ static constexpr T eps = FXRep::EPS();
+
+public:
+ typedef T (*FxbitsFunc)(XType);
+
+ void testSpecialNumbers(FxbitsFunc func) {
+ EXPECT_EQ(zero, func(0));
+ EXPECT_EQ(half, func((XType) (0b1 << (FXRep::FRACTION_LEN - 1)))); // 0.1000...b
+ }
+};
+
+
+#define LIST_FXBITS_TEST(T, XType, func) \
+ using LlvmLibcFxbitsTest = FxbitsTest<T, XType>; \
+ TEST_F(LlvmLibcFxbitsTest, SpecialNumbers) { testSpecialNumbers(&func); } \
+ static_assert(true, "Require semicolon.")
diff --git a/libc/test/src/stdfix/rbits_test.cpp b/libc/test/src/stdfix/rbits_test.cpp
new file mode 100644
index 00000000000000..c1725b2ebeaf44
--- /dev/null
+++ b/libc/test/src/stdfix/rbits_test.cpp
@@ -0,0 +1,7 @@
+
+#include "FxbitsTest.h"
+
+#include "src/stdfix/rbits.h"
+
+LIST_FXBITS_TEST(fract, int_r_t, LIBC_NAMESPACE::rbits);
+
>From 4d7163648a4987d5208dcf24d0c05746e1fdfb75 Mon Sep 17 00:00:00 2001
From: smallp-o-p <william.tranviet at gmail.com>
Date: Thu, 31 Oct 2024 21:39:31 -0400
Subject: [PATCH 5/9] Implement fxbits
---
libc/src/__support/fixed_point/fx_bits.h | 21 ++++++++++++++++-----
libc/src/stdfix/hkbits.cpp | 22 ++++++++++++++++++++++
libc/src/stdfix/hkbits.h | 20 ++++++++++++++++++++
libc/src/stdfix/hrbits.cpp | 11 ++++++++++-
libc/src/stdfix/hrbits.h | 10 +++++++++-
libc/src/stdfix/kbits.cpp | 21 +++++++++++++++++++++
libc/src/stdfix/kbits.h | 21 +++++++++++++++++++++
libc/src/stdfix/lkbits.cpp | 21 +++++++++++++++++++++
libc/src/stdfix/lkbits.h | 19 +++++++++++++++++++
libc/src/stdfix/lrbits.cpp | 21 +++++++++++++++++++++
libc/src/stdfix/lrbits.h | 19 +++++++++++++++++++
libc/src/stdfix/rbits.cpp | 12 ++++++++++--
libc/src/stdfix/rbits.h | 12 ++++++++++--
libc/src/stdfix/uhkbits.cpp | 21 +++++++++++++++++++++
libc/src/stdfix/uhkbits.h | 20 ++++++++++++++++++++
libc/src/stdfix/uhrbits.cpp | 21 +++++++++++++++++++++
libc/src/stdfix/uhrbits.h | 20 ++++++++++++++++++++
libc/src/stdfix/ukbits.cpp | 21 +++++++++++++++++++++
libc/src/stdfix/ukbits.h | 20 ++++++++++++++++++++
libc/src/stdfix/ulkbits.cpp | 21 +++++++++++++++++++++
libc/src/stdfix/ulkbits.h | 20 ++++++++++++++++++++
libc/src/stdfix/ulrbits.cpp | 21 +++++++++++++++++++++
libc/src/stdfix/ulrbits.h | 20 ++++++++++++++++++++
libc/src/stdfix/urbits.cpp | 21 +++++++++++++++++++++
libc/src/stdfix/urbits.h | 20 ++++++++++++++++++++
25 files changed, 465 insertions(+), 11 deletions(-)
diff --git a/libc/src/__support/fixed_point/fx_bits.h b/libc/src/__support/fixed_point/fx_bits.h
index 448845103ccddb..333e46de41e425 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"
@@ -163,12 +163,23 @@ template <typename T> LIBC_INLINE constexpr T round(T x, int n) {
return bit_and((x + round_bit), rounding_mask);
}
-// u?int_fx_t --> Fixed point
+// (u)?int_fx_t --> Fixed point
template <typename T, typename XType> LIBC_INLINE constexpr T fxbits(XType x) {
- // Example: rbits(0x2000) where fract has 15 fractional bits,
- // 0x2000 --> 0010 0000 0000 0000 --> 0.010 0000 0000 0000 = 0.25
+ using FXRep = FXRep<T>;
+
+ // Shift number by FX_IBITS so the bits are in the right spot.
+ // If the number is negative we need to make it positive, shift it and then
+ // renegate it to get the correct value.
+ if (cpp::is_signed_v<XType> &&
+ ((1 << (FXRep::TOTAL_LEN - 1)) & x)) {
+ x = -x;
+ x >>= FXRep::INTEGRAL_LEN;
+ x = -x;
+ } else {
+ x >>= FXRep::INTEGRAL_LEN;
+ }
- return cpp::bit_cast<T, XType>(x);
+ return cpp::bit_cast<T, XType>(x);
}
} // namespace fixed_point
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/hkbits.cpp b/libc/src/stdfix/hkbits.cpp
index e69de29bb2d1d6..f09e92d62ed5c1 100644
--- a/libc/src/stdfix/hkbits.cpp
+++ b/libc/src/stdfix/hkbits.cpp
@@ -0,0 +1,22 @@
+//===-- 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 fixed_point::fxbits<short accum, int_hk_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/hkbits.h b/libc/src/stdfix/hkbits.h
index e69de29bb2d1d6..9cfff9c1ef12b8 100644
--- a/libc/src/stdfix/hkbits.h
+++ b/libc/src/stdfix/hkbits.h
@@ -0,0 +1,20 @@
+//===-- 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 "src/__support/macros/config.h"
+namespace LIBC_NAMESPACE_DECL {
+
+short accum hkbits(int_hk_t x);
+
+}
+
+#endif
diff --git a/libc/src/stdfix/hrbits.cpp b/libc/src/stdfix/hrbits.cpp
index cd7fbb9648d5b0..67a974568b9409 100644
--- a/libc/src/stdfix/hrbits.cpp
+++ b/libc/src/stdfix/hrbits.cpp
@@ -1,4 +1,13 @@
+//===-- 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"
@@ -6,7 +15,7 @@
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(short fract, hrbits, (int_hr_t x)) {
- return fixed_point::bits(x);
+ return fixed_point::fxbits(x);
}
}
diff --git a/libc/src/stdfix/hrbits.h b/libc/src/stdfix/hrbits.h
index e66192b8ee4d2d..3499e471ced4d8 100644
--- a/libc/src/stdfix/hrbits.h
+++ b/libc/src/stdfix/hrbits.h
@@ -1,6 +1,14 @@
+//===-- 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 "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/stdfix/kbits.cpp b/libc/src/stdfix/kbits.cpp
index e69de29bb2d1d6..e49220671ef34d 100644
--- a/libc/src/stdfix/kbits.cpp
+++ b/libc/src/stdfix/kbits.cpp
@@ -0,0 +1,21 @@
+//===-- 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 fixed_point::fxbits<accum, int_k_t>(x);
+}
+
+}
diff --git a/libc/src/stdfix/kbits.h b/libc/src/stdfix/kbits.h
index e69de29bb2d1d6..a2d2624a6793f7 100644
--- a/libc/src/stdfix/kbits.h
+++ b/libc/src/stdfix/kbits.h
@@ -0,0 +1,21 @@
+//===-- 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 "src/__support/macros/config.h"
+namespace LIBC_NAMESPACE_DECL {
+
+accum kbits(int_k_t x);
+
+}
+
+#endif
diff --git a/libc/src/stdfix/lkbits.cpp b/libc/src/stdfix/lkbits.cpp
index e69de29bb2d1d6..98e00bfd5e262b 100644
--- a/libc/src/stdfix/lkbits.cpp
+++ b/libc/src/stdfix/lkbits.cpp
@@ -0,0 +1,21 @@
+//===-- 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 fixed_point::fxbits<long accum, int_lk_t>(x);
+}
+
+}
diff --git a/libc/src/stdfix/lkbits.h b/libc/src/stdfix/lkbits.h
index e69de29bb2d1d6..01c4d50f7d6f2f 100644
--- a/libc/src/stdfix/lkbits.h
+++ b/libc/src/stdfix/lkbits.h
@@ -0,0 +1,19 @@
+//===-- 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 "src/__support/macros/config.h"
+namespace LIBC_NAMESPACE_DECL {
+
+long accum lkbits(int_lk_t x);
+
+}
+#endif
diff --git a/libc/src/stdfix/lrbits.cpp b/libc/src/stdfix/lrbits.cpp
index e69de29bb2d1d6..8f5cf532e99221 100644
--- a/libc/src/stdfix/lrbits.cpp
+++ b/libc/src/stdfix/lrbits.cpp
@@ -0,0 +1,21 @@
+//===-- 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 fixed_point::fxbits<long fract, int_lr_t>(x);
+}
+
+}
diff --git a/libc/src/stdfix/lrbits.h b/libc/src/stdfix/lrbits.h
index e69de29bb2d1d6..dec00b279941dc 100644
--- a/libc/src/stdfix/lrbits.h
+++ b/libc/src/stdfix/lrbits.h
@@ -0,0 +1,19 @@
+//===-- 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_LRBITS_H
+#define LLVM_LIBC_SRC_STDFIX_LRBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+namespace LIBC_NAMESPACE_DECL {
+
+long fract lrbits(int_lr_t x);
+
+}
+#endif
diff --git a/libc/src/stdfix/rbits.cpp b/libc/src/stdfix/rbits.cpp
index 9a2fd3a2f82469..d94eb6f0c592c9 100644
--- a/libc/src/stdfix/rbits.cpp
+++ b/libc/src/stdfix/rbits.cpp
@@ -1,3 +1,11 @@
+//===-- 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"
@@ -7,7 +15,7 @@
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(fract, rbits, (int_r_t x)) {
- return fixed_point::fxbits<fract, int_r_t>(x);
+ return fixed_point::fxbits<fract, int_r_t>(x);
}
-}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/rbits.h b/libc/src/stdfix/rbits.h
index 4ac494d7ce530b..b6b80a2369b470 100644
--- a/libc/src/stdfix/rbits.h
+++ b/libc/src/stdfix/rbits.h
@@ -1,5 +1,13 @@
-#ifndef LLVM_LIBC_SRC_STDFIX_HRBITS_H
-#define LLVM_LIBC_SRC_STDFIX_HRBITS_H
+//===-- 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 "src/__support/macros/config.h"
diff --git a/libc/src/stdfix/uhkbits.cpp b/libc/src/stdfix/uhkbits.cpp
index e69de29bb2d1d6..8e2cdbb8a19a60 100644
--- a/libc/src/stdfix/uhkbits.cpp
+++ b/libc/src/stdfix/uhkbits.cpp
@@ -0,0 +1,21 @@
+//===-- 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 fixed_point::fxbits<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
index e69de29bb2d1d6..c2be44bd96034c 100644
--- a/libc/src/stdfix/uhkbits.h
+++ b/libc/src/stdfix/uhkbits.h
@@ -0,0 +1,20 @@
+//===-- 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 "src/__support/macros/config.h"
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned short accum uhkbits(uint_uhk_t x);
+
+}
+
+#endif
diff --git a/libc/src/stdfix/uhrbits.cpp b/libc/src/stdfix/uhrbits.cpp
index e69de29bb2d1d6..bf9226a011f768 100644
--- a/libc/src/stdfix/uhrbits.cpp
+++ b/libc/src/stdfix/uhrbits.cpp
@@ -0,0 +1,21 @@
+//===-- 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 fixed_point::fxbits<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
index e69de29bb2d1d6..fa86bcbfe311b8 100644
--- a/libc/src/stdfix/uhrbits.h
+++ b/libc/src/stdfix/uhrbits.h
@@ -0,0 +1,20 @@
+//===-- 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 "src/__support/macros/config.h"
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned short fract uhrbits(uint_uhr_t x);
+
+}
+
+#endif
diff --git a/libc/src/stdfix/ukbits.cpp b/libc/src/stdfix/ukbits.cpp
index e69de29bb2d1d6..8e8c263f958b75 100644
--- a/libc/src/stdfix/ukbits.cpp
+++ b/libc/src/stdfix/ukbits.cpp
@@ -0,0 +1,21 @@
+//===-- 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 fixed_point::fxbits<unsigned accum, uint_uk_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/ukbits.h b/libc/src/stdfix/ukbits.h
index e69de29bb2d1d6..2eaedd7d92a3e2 100644
--- a/libc/src/stdfix/ukbits.h
+++ b/libc/src/stdfix/ukbits.h
@@ -0,0 +1,20 @@
+//===-- 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 "src/__support/macros/config.h"
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned accum ukbits(uint_uk_t x);
+
+}
+
+#endif
diff --git a/libc/src/stdfix/ulkbits.cpp b/libc/src/stdfix/ulkbits.cpp
index e69de29bb2d1d6..654463a0a682a2 100644
--- a/libc/src/stdfix/ulkbits.cpp
+++ b/libc/src/stdfix/ulkbits.cpp
@@ -0,0 +1,21 @@
+//===-- 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 fixed_point::fxbits<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
index e69de29bb2d1d6..a922a18c72b259 100644
--- a/libc/src/stdfix/ulkbits.h
+++ b/libc/src/stdfix/ulkbits.h
@@ -0,0 +1,20 @@
+//===-- 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 "src/__support/macros/config.h"
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned long accum ulkbits(uint_ulk_t x);
+
+}
+
+#endif
diff --git a/libc/src/stdfix/ulrbits.cpp b/libc/src/stdfix/ulrbits.cpp
index e69de29bb2d1d6..ad3ebf21e6295d 100644
--- a/libc/src/stdfix/ulrbits.cpp
+++ b/libc/src/stdfix/ulrbits.cpp
@@ -0,0 +1,21 @@
+//===-- 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 fixed_point::fxbits<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
index e69de29bb2d1d6..fc5ebe9845ae80 100644
--- a/libc/src/stdfix/ulrbits.h
+++ b/libc/src/stdfix/ulrbits.h
@@ -0,0 +1,20 @@
+//===-- 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 "src/__support/macros/config.h"
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned long fract ulrbits(uint_ulr_t x);
+
+}
+
+#endif
diff --git a/libc/src/stdfix/urbits.cpp b/libc/src/stdfix/urbits.cpp
index e69de29bb2d1d6..06f47734c4ecf7 100644
--- a/libc/src/stdfix/urbits.cpp
+++ b/libc/src/stdfix/urbits.cpp
@@ -0,0 +1,21 @@
+//===-- 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 fixed_point::fxbits<unsigned fract, uint_ur_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/urbits.h b/libc/src/stdfix/urbits.h
index e69de29bb2d1d6..2fbbfb68792463 100644
--- a/libc/src/stdfix/urbits.h
+++ b/libc/src/stdfix/urbits.h
@@ -0,0 +1,20 @@
+//===-- 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 "src/__support/macros/config.h"
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned fract urbits(uint_ur_t x);
+
+}
+
+#endif
>From aec4183a3c7205ccffa62886b761f794760be227 Mon Sep 17 00:00:00 2001
From: smallp-o-p <william.tranviet at gmail.com>
Date: Sat, 2 Nov 2024 23:22:14 -0400
Subject: [PATCH 6/9] Fix shift overflow compile error
---
libc/src/__support/fixed_point/fx_bits.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/libc/src/__support/fixed_point/fx_bits.h b/libc/src/__support/fixed_point/fx_bits.h
index 333e46de41e425..6bc4cdbfcd6ff8 100644
--- a/libc/src/__support/fixed_point/fx_bits.h
+++ b/libc/src/__support/fixed_point/fx_bits.h
@@ -166,12 +166,11 @@ template <typename T> LIBC_INLINE constexpr T round(T x, int n) {
// (u)?int_fx_t --> Fixed point
template <typename T, typename XType> LIBC_INLINE constexpr T fxbits(XType x) {
using FXRep = FXRep<T>;
-
// Shift number by FX_IBITS so the bits are in the right spot.
// If the number is negative we need to make it positive, shift it and then
// renegate it to get the correct value.
if (cpp::is_signed_v<XType> &&
- ((1 << (FXRep::TOTAL_LEN - 1)) & x)) {
+ (x >> (FXRep::TOTAL_LEN - FXRep::SIGN_LEN))) {
x = -x;
x >>= FXRep::INTEGRAL_LEN;
x = -x;
>From fe66e6a26bb9bf7ee63082537b8fd550df156996 Mon Sep 17 00:00:00 2001
From: smallp-o-p <william.tranviet at gmail.com>
Date: Sat, 2 Nov 2024 23:22:36 -0400
Subject: [PATCH 7/9] Specify proper fxbits template for hrbits
---
libc/src/stdfix/hrbits.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/stdfix/hrbits.cpp b/libc/src/stdfix/hrbits.cpp
index 67a974568b9409..ece82c9e54826a 100644
--- a/libc/src/stdfix/hrbits.cpp
+++ b/libc/src/stdfix/hrbits.cpp
@@ -15,7 +15,7 @@
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(short fract, hrbits, (int_hr_t x)) {
- return fixed_point::fxbits(x);
+ return fixed_point::fxbits<short fract, int_hr_t>(x);
}
}
>From 46b066d857a176d9e0653a1ac9079387cee8128f Mon Sep 17 00:00:00 2001
From: smallp-o-p <william.tranviet at gmail.com>
Date: Sat, 2 Nov 2024 23:23:22 -0400
Subject: [PATCH 8/9] Add test cases for all fxbits functions
---
libc/test/src/stdfix/FxbitsTest.h | 7 +++++--
libc/test/src/stdfix/hkbits_test.cpp | 4 ++++
libc/test/src/stdfix/hrbits_test.cpp | 4 ++++
libc/test/src/stdfix/kbits_test.cpp | 4 ++++
libc/test/src/stdfix/lkbits_test.cpp | 5 +++++
libc/test/src/stdfix/lrbits_test.cpp | 4 ++++
libc/test/src/stdfix/rbits_test.cpp | 3 ---
libc/test/src/stdfix/uhkbits_test.cpp | 4 ++++
libc/test/src/stdfix/uhrbits_test.cpp | 4 ++++
libc/test/src/stdfix/ukbits_test.cpp | 5 +++++
libc/test/src/stdfix/ulkbits_test.cpp | 5 +++++
libc/test/src/stdfix/ulrbits_test.cpp | 4 ++++
libc/test/src/stdfix/urbits_test.cpp | 4 ++++
13 files changed, 52 insertions(+), 5 deletions(-)
create mode 100644 libc/test/src/stdfix/hkbits_test.cpp
create mode 100644 libc/test/src/stdfix/hrbits_test.cpp
create mode 100644 libc/test/src/stdfix/kbits_test.cpp
create mode 100644 libc/test/src/stdfix/lkbits_test.cpp
create mode 100644 libc/test/src/stdfix/lrbits_test.cpp
create mode 100644 libc/test/src/stdfix/uhkbits_test.cpp
create mode 100644 libc/test/src/stdfix/uhrbits_test.cpp
create mode 100644 libc/test/src/stdfix/ukbits_test.cpp
create mode 100644 libc/test/src/stdfix/ulkbits_test.cpp
create mode 100644 libc/test/src/stdfix/ulrbits_test.cpp
create mode 100644 libc/test/src/stdfix/urbits_test.cpp
diff --git a/libc/test/src/stdfix/FxbitsTest.h b/libc/test/src/stdfix/FxbitsTest.h
index d698f140a690a5..0ee58e1293b64f 100644
--- a/libc/test/src/stdfix/FxbitsTest.h
+++ b/libc/test/src/stdfix/FxbitsTest.h
@@ -27,11 +27,14 @@ template <typename T, typename XType> class FxbitsTest : public LIBC_NAMESPACE::
void testSpecialNumbers(FxbitsFunc func) {
EXPECT_EQ(zero, func(0));
EXPECT_EQ(half, func((XType) (0b1 << (FXRep::FRACTION_LEN - 1)))); // 0.1000...b
+ EXPECT_EQ(min, func((XType) 0x1));
+ EXPECT_EQ(one, func(1));
+ EXPECT_EQ(neg_one, func(-1));
}
};
#define LIST_FXBITS_TEST(T, XType, func) \
- using LlvmLibcFxbitsTest = FxbitsTest<T, XType>; \
- TEST_F(LlvmLibcFxbitsTest, SpecialNumbers) { testSpecialNumbers(&func); } \
+ using LlvmLibcFxbitsTest = FxbitsTest<T, XType>; \
+ TEST_F(LlvmLibcFxbitsTest, SpecialNumbers) { testSpecialNumbers(&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..b0cda93aa5d297
--- /dev/null
+++ b/libc/test/src/stdfix/hkbits_test.cpp
@@ -0,0 +1,4 @@
+#include "FxbitsTest.h"
+#include "src/stdfix/hkbits.h"
+
+LIST_FXBITS_TEST(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..a2807b90d88a41
--- /dev/null
+++ b/libc/test/src/stdfix/hrbits_test.cpp
@@ -0,0 +1,4 @@
+#include "FxbitsTest.h"
+#include "src/stdfix/hrbits.h"
+
+LIST_FXBITS_TEST(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..b9e75ff0fa33a9
--- /dev/null
+++ b/libc/test/src/stdfix/kbits_test.cpp
@@ -0,0 +1,4 @@
+#include "FxbitsTest.h"
+#include "src/stdfix/kbits.h"
+
+LIST_FXBITS_TEST(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..d0956e0deb9d78
--- /dev/null
+++ b/libc/test/src/stdfix/lkbits_test.cpp
@@ -0,0 +1,5 @@
+#include "FxbitsTest.h"
+#include "src/stdfix/lkbits.h"
+
+LIST_FXBITS_TEST(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..2f7b0d6dc56100
--- /dev/null
+++ b/libc/test/src/stdfix/lrbits_test.cpp
@@ -0,0 +1,4 @@
+#include "FxbitsTest.h"
+#include "src/stdfix/lrbits.h"
+
+LIST_FXBITS_TEST(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
index c1725b2ebeaf44..7c00143697308f 100644
--- a/libc/test/src/stdfix/rbits_test.cpp
+++ b/libc/test/src/stdfix/rbits_test.cpp
@@ -1,7 +1,4 @@
-
#include "FxbitsTest.h"
-
#include "src/stdfix/rbits.h"
LIST_FXBITS_TEST(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..bd7cb07b838bdb
--- /dev/null
+++ b/libc/test/src/stdfix/uhkbits_test.cpp
@@ -0,0 +1,4 @@
+#include "FxbitsTest.h"
+#include "src/stdfix/uhkbits.h"
+
+LIST_FXBITS_TEST(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..a866e414ceb2e9
--- /dev/null
+++ b/libc/test/src/stdfix/uhrbits_test.cpp
@@ -0,0 +1,4 @@
+#include "FxbitsTest.h"
+#include "src/stdfix/uhrbits.h"
+
+LIST_FXBITS_TEST(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..cd54ff7847b4b4
--- /dev/null
+++ b/libc/test/src/stdfix/ukbits_test.cpp
@@ -0,0 +1,5 @@
+#include "FxbitsTest.h"
+#include "src/stdfix/ukbits.h"
+
+LIST_FXBITS_TEST(unsigned accum, uint_uk_t, LIBC_NAMESAPCE::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..90f2dce2772c50
--- /dev/null
+++ b/libc/test/src/stdfix/ulkbits_test.cpp
@@ -0,0 +1,5 @@
+#include "FxbitsTest.h"
+#include "src/stdfix/ulkbits.h"
+
+LIST_FXBITS_TEST(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..641e58db1fb1e3
--- /dev/null
+++ b/libc/test/src/stdfix/ulrbits_test.cpp
@@ -0,0 +1,4 @@
+#include "FxbitsTest.h"
+#include "src/stdfix/ulrbits.h"
+
+LIST_FXBITS_TEST(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..4f197851a0229b
--- /dev/null
+++ b/libc/test/src/stdfix/urbits_test.cpp
@@ -0,0 +1,4 @@
+#include "FxbitsTest.h"
+#include "src/stdfix/urbits.h"
+
+LIST_FXBITS_TEST(unsigned fract, uint_ur_t, LIBC_NAMESPACE::urbits);
>From 5a3932eb2bfa45622e55d89d91a5fb19efe7ff11 Mon Sep 17 00:00:00 2001
From: smallp-o-p <william.tranviet at gmail.com>
Date: Sun, 3 Nov 2024 00:16:30 -0400
Subject: [PATCH 9/9] Update documentation
---
libc/docs/math/stdfix.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/docs/math/stdfix.rst b/libc/docs/math/stdfix.rst
index d8dcb0cfa4c521..0751f2518bc247 100644
--- a/libc/docs/math/stdfix.rst
+++ b/libc/docs/math/stdfix.rst
@@ -71,7 +71,7 @@ The following functions are included in the ISO/IEC TR 18037:2008 standard.
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| bits\* | | | | | | | | | | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
-| \*bits | | | | | | | | | | | | |
+| \*bits | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| countls | | | | | | | | | | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
More information about the libc-commits
mailing list