11
11
12
12
#include " include/llvm-libc-macros/stdfix-macros.h"
13
13
#include " src/__support/CPP/bit.h"
14
+ #include " src/__support/CPP/limits.h" // numeric_limits
14
15
#include " src/__support/CPP/type_traits.h"
15
- #include " src/__support/macros/attributes.h" // LIBC_INLINE
16
- #include " src/__support/macros/config.h"
16
+ #include " src/__support/macros/attributes.h" // LIBC_INLINE
17
+ #include " src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
17
18
#include " src/__support/macros/optimization.h" // LIBC_UNLIKELY
18
19
#include " src/__support/math_extras.h"
19
20
@@ -50,6 +51,12 @@ template <typename T> struct FXBits {
50
51
static constexpr StorageType SIGN_MASK =
51
52
(fx_rep::SIGN_LEN == 0 ? 0 : StorageType(1 ) << SIGN_OFFSET);
52
53
54
+ // mask for <integral | fraction>
55
+ static constexpr StorageType VALUE_MASK = INTEGRAL_MASK | FRACTION_MASK;
56
+
57
+ // mask for <sign | integral | fraction>
58
+ static constexpr StorageType TOTAL_MASK = SIGN_MASK | VALUE_MASK;
59
+
53
60
public:
54
61
LIBC_INLINE constexpr FXBits () = default;
55
62
@@ -74,6 +81,12 @@ template <typename T> struct FXBits {
74
81
return (value & INTEGRAL_MASK) >> INTEGRAL_OFFSET;
75
82
}
76
83
84
+ // returns complete bitstring representation the fixed point number
85
+ // the bitstring is of the form: padding | sign | integral | fraction
86
+ LIBC_INLINE constexpr StorageType get_bits () {
87
+ return (value & TOTAL_MASK) >> FRACTION_OFFSET;
88
+ }
89
+
77
90
// TODO: replace bool with Sign
78
91
LIBC_INLINE constexpr bool get_sign () {
79
92
return static_cast <bool >((value & SIGN_MASK) >> SIGN_OFFSET);
@@ -163,6 +176,26 @@ template <typename T> LIBC_INLINE constexpr T round(T x, int n) {
163
176
return bit_and ((x + round_bit), rounding_mask);
164
177
}
165
178
179
+ // count leading sign bits
180
+ template <typename T>
181
+ LIBC_INLINE constexpr cpp::enable_if_t <cpp::is_fixed_point_v<T>, int >
182
+ countls (T f) {
183
+ using FXRep = FXRep<T>;
184
+ using BitType = typename FXRep::StorageType;
185
+ using FXBits = FXBits<T>;
186
+
187
+ constexpr int CONTAIN_LEN = cpp::numeric_limits<BitType>::digits;
188
+ constexpr int PADDING_LEN = CONTAIN_LEN - FXRep::TOTAL_LEN;
189
+
190
+ if constexpr (FXRep::SIGN_LEN != 0 ) {
191
+ if (x < 0 )
192
+ x = bit_not (x);
193
+ }
194
+
195
+ BitType value_bits = FXBits (x)::get_bits ();
196
+ return cpp::countl_zero (value_bits) - PADDING_LEN;
197
+ }
198
+
166
199
} // namespace fixed_point
167
200
} // namespace LIBC_NAMESPACE_DECL
168
201
0 commit comments