Skip to content

Commit f2a1103

Browse files
authored
[libc][stdfix] Implement fixed point countlsfx functions in llvm-libc (#125356)
fixes #113357
1 parent 2c4dd89 commit f2a1103

Some content is hidden

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

47 files changed

+903
-3
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
@@ -874,6 +874,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
874874
libc.src.stdfix.ukbits
875875
libc.src.stdfix.lkbits
876876
libc.src.stdfix.ulkbits
877+
libc.src.stdfix.countlshr
878+
libc.src.stdfix.countlsr
879+
libc.src.stdfix.countlslr
880+
libc.src.stdfix.countlshk
881+
libc.src.stdfix.countlsk
882+
libc.src.stdfix.countlslk
883+
libc.src.stdfix.countlsuhr
884+
libc.src.stdfix.countlsur
885+
libc.src.stdfix.countlsulr
886+
libc.src.stdfix.countlsuhk
887+
libc.src.stdfix.countlsuk
888+
libc.src.stdfix.countlsulk
877889
)
878890
endif()
879891

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

+35-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,26 @@ 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+
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+
166199
} // namespace fixed_point
167200
} // namespace LIBC_NAMESPACE_DECL
168201

libc/src/stdfix/CMakeLists.txt

+12
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ foreach(suffix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
5353
libc.src.__support.CPP.bit
5454
libc.src.__support.fixed_point.fx_bits
5555
)
56+
57+
add_entrypoint_object(
58+
countls${suffix}
59+
HDRS
60+
countls${suffix}.h
61+
SRCS
62+
countls${suffix}.cpp
63+
COMPILE_OPTIONS
64+
${libc_opt_high_flag}
65+
DEPENDS
66+
libc.src.__support.fixed_point.fx_bits
67+
)
5668
endforeach()
5769

5870
add_entrypoint_object(

libc/src/stdfix/countlshk.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation for countlshk function ----------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "countlshk.h"
10+
#include "src/__support/common.h"
11+
#include "src/__support/fixed_point/fx_bits.h"
12+
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
13+
14+
namespace LIBC_NAMESPACE_DECL {
15+
16+
LLVM_LIBC_FUNCTION(int, countlshk, (short accum f)) {
17+
return fixed_point::countls(f);
18+
}
19+
20+
} // namespace LIBC_NAMESPACE_DECL

libc/src/stdfix/countlshk.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation header for countlshk function ------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_STDFIX_COUNTLSHK_H
10+
#define LLVM_LIBC_SRC_STDFIX_COUNTLSHK_H
11+
12+
#include "include/llvm-libc-macros/stdfix-macros.h"
13+
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
17+
int countlshk(short accum f);
18+
19+
} // namespace LIBC_NAMESPACE_DECL
20+
21+
#endif // LLVM_LIBC_SRC_STDFIX_COUNTLSHK_H

libc/src/stdfix/countlshr.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation for countlshr function ----------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "countlshr.h"
10+
#include "src/__support/common.h"
11+
#include "src/__support/fixed_point/fx_bits.h"
12+
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
13+
14+
namespace LIBC_NAMESPACE_DECL {
15+
16+
LLVM_LIBC_FUNCTION(int, countlshr, (short fract f)) {
17+
return fixed_point::countls(f);
18+
}
19+
20+
} // namespace LIBC_NAMESPACE_DECL

libc/src/stdfix/countlshr.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation header for countlshr function ------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_STDFIX_COUNTLSHR_H
10+
#define LLVM_LIBC_SRC_STDFIX_COUNTLSHR_H
11+
12+
#include "include/llvm-libc-macros/stdfix-macros.h"
13+
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
17+
int countlshr(short fract f);
18+
19+
} // namespace LIBC_NAMESPACE_DECL
20+
21+
#endif // LLVM_LIBC_SRC_STDFIX_COUNTLSHR_H

libc/src/stdfix/countlsk.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===-- Implementation for countlsk function -----------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "countlsk.h"
10+
#include "src/__support/common.h"
11+
#include "src/__support/fixed_point/fx_bits.h"
12+
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
13+
14+
namespace LIBC_NAMESPACE_DECL {
15+
16+
LLVM_LIBC_FUNCTION(int, countlsk, (accum f)) { return fixed_point::countls(f); }
17+
18+
} // namespace LIBC_NAMESPACE_DECL

libc/src/stdfix/countlsk.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation header for countlsk function -------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_STDFIX_COUNTLSK_H
10+
#define LLVM_LIBC_SRC_STDFIX_COUNTLSK_H
11+
12+
#include "include/llvm-libc-macros/stdfix-macros.h"
13+
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
17+
int countlsk(accum f);
18+
19+
} // namespace LIBC_NAMESPACE_DECL
20+
21+
#endif // LLVM_LIBC_SRC_STDFIX_COUNTLSK_H

0 commit comments

Comments
 (0)