Skip to content

Commit 9a1dcf3

Browse files
krishna2803sivan-shani
authored andcommitted
[libc][stdfix] Implement countlsfx functions in libc. (llvm#126597)
fixes llvm#113357 --------- Signed-off-by: krishna2803 <[email protected]>
1 parent bae24f3 commit 9a1dcf3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+919
-27
lines changed

libc/config/baremetal/arm/entrypoints.txt

+12
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
469469
libc.src.stdfix.ukbits
470470
libc.src.stdfix.lkbits
471471
libc.src.stdfix.ulkbits
472+
libc.src.stdfix.countlshr
473+
libc.src.stdfix.countlsr
474+
libc.src.stdfix.countlslr
475+
libc.src.stdfix.countlshk
476+
libc.src.stdfix.countlsk
477+
libc.src.stdfix.countlslk
478+
libc.src.stdfix.countlsuhr
479+
libc.src.stdfix.countlsur
480+
libc.src.stdfix.countlsulr
481+
libc.src.stdfix.countlsuhk
482+
libc.src.stdfix.countlsuk
483+
libc.src.stdfix.countlsulk
472484
)
473485
endif()
474486

libc/config/baremetal/riscv/entrypoints.txt

+12
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
464464
libc.src.stdfix.ukbits
465465
libc.src.stdfix.lkbits
466466
libc.src.stdfix.ulkbits
467+
libc.src.stdfix.countlshr
468+
libc.src.stdfix.countlsr
469+
libc.src.stdfix.countlslr
470+
libc.src.stdfix.countlshk
471+
libc.src.stdfix.countlsk
472+
libc.src.stdfix.countlslk
473+
libc.src.stdfix.countlsuhr
474+
libc.src.stdfix.countlsur
475+
libc.src.stdfix.countlsulr
476+
libc.src.stdfix.countlsuhk
477+
libc.src.stdfix.countlsuk
478+
libc.src.stdfix.countlsulk
467479
)
468480
endif()
469481

libc/config/linux/riscv/entrypoints.txt

+12
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
749749
# TODO: https://github.com/llvm/llvm-project/issues/115778
750750
libc.src.stdfix.lkbits
751751
libc.src.stdfix.ulkbits
752+
libc.src.stdfix.countlshr
753+
libc.src.stdfix.countlsr
754+
libc.src.stdfix.countlslr
755+
libc.src.stdfix.countlshk
756+
libc.src.stdfix.countlsk
757+
libc.src.stdfix.countlslk
758+
libc.src.stdfix.countlsuhr
759+
libc.src.stdfix.countlsur
760+
libc.src.stdfix.countlsulr
761+
libc.src.stdfix.countlsuhk
762+
libc.src.stdfix.countlsuk
763+
libc.src.stdfix.countlsulk
752764
)
753765
endif()
754766

libc/config/linux/x86_64/entrypoints.txt

+12
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
875875
libc.src.stdfix.ukbits
876876
libc.src.stdfix.lkbits
877877
libc.src.stdfix.ulkbits
878+
libc.src.stdfix.countlshr
879+
libc.src.stdfix.countlsr
880+
libc.src.stdfix.countlslr
881+
libc.src.stdfix.countlshk
882+
libc.src.stdfix.countlsk
883+
libc.src.stdfix.countlslk
884+
libc.src.stdfix.countlsuhr
885+
libc.src.stdfix.countlsur
886+
libc.src.stdfix.countlsulr
887+
libc.src.stdfix.countlsuhk
888+
libc.src.stdfix.countlsuk
889+
libc.src.stdfix.countlsulk
878890
)
879891
endif()
880892

libc/docs/headers/math/stdfix.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ The following functions are included in the ISO/IEC TR 18037:2008 standard.
7373
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
7474
| \*bits | | | | | | | | | | | | |
7575
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
76-
| countls | | | | | | | | | | | | |
76+
| countls | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
7777
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
7878
| divi | | | | | | | | | | | | |
7979
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+

libc/include/stdfix.yaml

+84
Original file line numberDiff line numberDiff line change
@@ -306,3 +306,87 @@ functions:
306306
arguments:
307307
- type: unsigned int
308308
guard: LIBC_COMPILER_HAS_FIXED_POINT
309+
- name: countlshr
310+
standards:
311+
- stdc_ext
312+
return_type: int
313+
arguments:
314+
- type: short fract
315+
guard: LIBC_COMPILER_HAS_FIXED_POINT
316+
- name: countlsr
317+
standards:
318+
- stdc_ext
319+
return_type: int
320+
arguments:
321+
- type: fract
322+
guard: LIBC_COMPILER_HAS_FIXED_POINT
323+
- name: countlslr
324+
standards:
325+
- stdc_ext
326+
return_type: int
327+
arguments:
328+
- type: long fract
329+
guard: LIBC_COMPILER_HAS_FIXED_POINT
330+
- name: countlshk
331+
standards:
332+
- stdc_ext
333+
return_type: int
334+
arguments:
335+
- type: short accum
336+
guard: LIBC_COMPILER_HAS_FIXED_POINT
337+
- name: countlsk
338+
standards:
339+
- stdc_ext
340+
return_type: int
341+
arguments:
342+
- type: accum
343+
guard: LIBC_COMPILER_HAS_FIXED_POINT
344+
- name: countlslk
345+
standards:
346+
- stdc_ext
347+
return_type: int
348+
arguments:
349+
- type: long accum
350+
guard: LIBC_COMPILER_HAS_FIXED_POINT
351+
- name: countlsuhr
352+
standards:
353+
- stdc_ext
354+
return_type: int
355+
arguments:
356+
- type: unsigned short fract
357+
guard: LIBC_COMPILER_HAS_FIXED_POINT
358+
- name: countlsur
359+
standards:
360+
- stdc_ext
361+
return_type: int
362+
arguments:
363+
- type: unsigned fract
364+
guard: LIBC_COMPILER_HAS_FIXED_POINT
365+
- name: countlsulr
366+
standards:
367+
- stdc_ext
368+
return_type: int
369+
arguments:
370+
- type: unsigned long fract
371+
guard: LIBC_COMPILER_HAS_FIXED_POINT
372+
- name: countlsuhk
373+
standards:
374+
- stdc_ext
375+
return_type: int
376+
arguments:
377+
- type: unsigned short accum
378+
guard: LIBC_COMPILER_HAS_FIXED_POINT
379+
- name: countlsuk
380+
standards:
381+
- stdc_ext
382+
return_type: int
383+
arguments:
384+
- type: unsigned accum
385+
guard: LIBC_COMPILER_HAS_FIXED_POINT
386+
- name: countlsulk
387+
standards:
388+
- stdc_ext
389+
return_type: int
390+
arguments:
391+
- type: unsigned long accum
392+
guard: LIBC_COMPILER_HAS_FIXED_POINT

libc/src/__support/fixed_point/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ add_header_library(
1919
libc.src.__support.macros.optimization
2020
libc.src.__support.CPP.type_traits
2121
libc.src.__support.CPP.bit
22+
libc.src.__support.CPP.limits
2223
libc.src.__support.math_extras
2324
)
2425

libc/src/__support/fixed_point/fx_bits.h

+33-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111

1212
#include "include/llvm-libc-macros/stdfix-macros.h"
1313
#include "src/__support/CPP/bit.h"
14+
#include "src/__support/CPP/limits.h" // numeric_limits
1415
#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
1718
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
1819
#include "src/__support/math_extras.h"
1920

@@ -50,6 +51,12 @@ template <typename T> struct FXBits {
5051
static constexpr StorageType SIGN_MASK =
5152
(fx_rep::SIGN_LEN == 0 ? 0 : StorageType(1) << SIGN_OFFSET);
5253

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+
5360
public:
5461
LIBC_INLINE constexpr FXBits() = default;
5562

@@ -74,6 +81,12 @@ template <typename T> struct FXBits {
7481
return (value & INTEGRAL_MASK) >> INTEGRAL_OFFSET;
7582
}
7683

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+
7790
// TODO: replace bool with Sign
7891
LIBC_INLINE constexpr bool get_sign() {
7992
return static_cast<bool>((value & SIGN_MASK) >> SIGN_OFFSET);
@@ -163,6 +176,24 @@ template <typename T> LIBC_INLINE constexpr T round(T x, int n) {
163176
return bit_and((x + round_bit), rounding_mask);
164177
}
165178

179+
// count leading sign bits
180+
// TODO: support fixed_point_padding
181+
template <typename T>
182+
LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, int>
183+
countls(T f) {
184+
using FXRep = FXRep<T>;
185+
using BitType = typename FXRep::StorageType;
186+
using FXBits = FXBits<T>;
187+
188+
if constexpr (FXRep::SIGN_LEN > 0) {
189+
if (f < 0)
190+
f = bit_not(f);
191+
}
192+
193+
BitType value_bits = FXBits(f).get_bits();
194+
return cpp::countl_zero(value_bits) - FXRep::SIGN_LEN;
195+
}
196+
166197
} // namespace fixed_point
167198
} // namespace LIBC_NAMESPACE_DECL
168199

libc/src/__support/fixed_point/fx_rep.h

+24-24
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ template <> struct FXRep<short fract> {
4343
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
4444
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
4545
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SFRACT_FBIT;
46-
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
47-
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
46+
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
47+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;
4848

4949
LIBC_INLINE static constexpr Type MIN() { return SFRACT_MIN; }
5050
LIBC_INLINE static constexpr Type MAX() { return SFRACT_MAX; }
@@ -63,8 +63,8 @@ template <> struct FXRep<unsigned short fract> {
6363
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
6464
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
6565
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = USFRACT_FBIT;
66-
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
67-
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
66+
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
67+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;
6868

6969
LIBC_INLINE static constexpr Type MIN() { return USFRACT_MIN; }
7070
LIBC_INLINE static constexpr Type MAX() { return USFRACT_MAX; }
@@ -83,8 +83,8 @@ template <> struct FXRep<fract> {
8383
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
8484
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
8585
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = FRACT_FBIT;
86-
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
87-
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
86+
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
87+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;
8888

8989
LIBC_INLINE static constexpr Type MIN() { return FRACT_MIN; }
9090
LIBC_INLINE static constexpr Type MAX() { return FRACT_MAX; }
@@ -103,8 +103,8 @@ template <> struct FXRep<unsigned fract> {
103103
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
104104
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
105105
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = UFRACT_FBIT;
106-
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
107-
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
106+
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
107+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;
108108

109109
LIBC_INLINE static constexpr Type MIN() { return UFRACT_MIN; }
110110
LIBC_INLINE static constexpr Type MAX() { return UFRACT_MAX; }
@@ -123,8 +123,8 @@ template <> struct FXRep<long fract> {
123123
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
124124
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
125125
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = LFRACT_FBIT;
126-
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
127-
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
126+
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
127+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;
128128

129129
LIBC_INLINE static constexpr Type MIN() { return LFRACT_MIN; }
130130
LIBC_INLINE static constexpr Type MAX() { return LFRACT_MAX; }
@@ -143,8 +143,8 @@ template <> struct FXRep<unsigned long fract> {
143143
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
144144
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
145145
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ULFRACT_FBIT;
146-
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
147-
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
146+
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
147+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;
148148

149149
LIBC_INLINE static constexpr Type MIN() { return ULFRACT_MIN; }
150150
LIBC_INLINE static constexpr Type MAX() { return ULFRACT_MAX; }
@@ -163,8 +163,8 @@ template <> struct FXRep<short accum> {
163163
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
164164
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = SACCUM_IBIT;
165165
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SACCUM_FBIT;
166-
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
167-
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
166+
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
167+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;
168168

169169
LIBC_INLINE static constexpr Type MIN() { return SACCUM_MIN; }
170170
LIBC_INLINE static constexpr Type MAX() { return SACCUM_MAX; }
@@ -183,8 +183,8 @@ template <> struct FXRep<unsigned short accum> {
183183
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
184184
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = USACCUM_IBIT;
185185
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = USACCUM_FBIT;
186-
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
187-
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
186+
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
187+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;
188188

189189
LIBC_INLINE static constexpr Type MIN() { return USACCUM_MIN; }
190190
LIBC_INLINE static constexpr Type MAX() { return USACCUM_MAX; }
@@ -203,8 +203,8 @@ template <> struct FXRep<accum> {
203203
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
204204
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ACCUM_IBIT;
205205
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ACCUM_FBIT;
206-
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
207-
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
206+
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
207+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;
208208

209209
LIBC_INLINE static constexpr Type MIN() { return ACCUM_MIN; }
210210
LIBC_INLINE static constexpr Type MAX() { return ACCUM_MAX; }
@@ -223,8 +223,8 @@ template <> struct FXRep<unsigned accum> {
223223
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
224224
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = UACCUM_IBIT;
225225
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = UACCUM_FBIT;
226-
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
227-
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
226+
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
227+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;
228228

229229
LIBC_INLINE static constexpr Type MIN() { return UACCUM_MIN; }
230230
LIBC_INLINE static constexpr Type MAX() { return UACCUM_MAX; }
@@ -243,8 +243,8 @@ template <> struct FXRep<long accum> {
243243
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
244244
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = LACCUM_IBIT;
245245
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = LACCUM_FBIT;
246-
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
247-
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
246+
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
247+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;
248248

249249
LIBC_INLINE static constexpr Type MIN() { return LACCUM_MIN; }
250250
LIBC_INLINE static constexpr Type MAX() { return LACCUM_MAX; }
@@ -263,8 +263,8 @@ template <> struct FXRep<unsigned long accum> {
263263
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
264264
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ULACCUM_IBIT;
265265
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ULACCUM_FBIT;
266-
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
267-
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
266+
LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;
267+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;
268268

269269
LIBC_INLINE static constexpr Type MIN() { return ULACCUM_MIN; }
270270
LIBC_INLINE static constexpr Type MAX() { return ULACCUM_MAX; }

libc/src/stdfix/CMakeLists.txt

+12
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@ foreach(suffix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
4747
libc.src.__support.CPP.bit
4848
libc.src.__support.fixed_point.fx_bits
4949
)
50+
51+
add_entrypoint_object(
52+
countls${suffix}
53+
HDRS
54+
countls${suffix}.h
55+
SRCS
56+
countls${suffix}.cpp
57+
COMPILE_OPTIONS
58+
${libc_opt_high_flag}
59+
DEPENDS
60+
libc.src.__support.fixed_point.fx_bits
61+
)
5062
endforeach()
5163

5264
add_entrypoint_object(

0 commit comments

Comments
 (0)