Skip to content

Commit ad33fe1

Browse files
authored
[libc][stdfix] Add integer square root with fixed point output functions. (#83959)
Fix #83924.
1 parent ee1bcf7 commit ad33fe1

File tree

20 files changed

+491
-60
lines changed

20 files changed

+491
-60
lines changed

libc/config/baremetal/api.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ include "config/public_api.td"
22

33
include "spec/stdc.td"
44
include "spec/stdc_ext.td"
5+
include "spec/llvm_libc_ext.td"
56

67
def AssertMacro : MacroDef<"assert"> {
78
let Defn = [{

libc/config/baremetal/arm/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,8 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
306306
libc.src.stdfix.sqrtur
307307
# libc.src.stdfix.sqrtulk
308308
libc.src.stdfix.sqrtulr
309+
libc.src.stdfix.uhksqrtus
310+
libc.src.stdfix.uksqrtui
309311
)
310312
endif()
311313

libc/config/baremetal/riscv/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,8 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
306306
libc.src.stdfix.sqrtur
307307
# libc.src.stdfix.sqrtulk
308308
libc.src.stdfix.sqrtulr
309+
libc.src.stdfix.uhksqrtus
310+
libc.src.stdfix.uksqrtui
309311
)
310312
endif()
311313

libc/config/linux/api.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ include "spec/posix.td"
55
include "spec/linux.td"
66
include "spec/gnu_ext.td"
77
include "spec/bsd_ext.td"
8-
include "spec/llvm_libc_ext.td"
98
include "spec/stdc_ext.td"
9+
include "spec/llvm_libc_ext.td"
1010

1111
def AssertMacro : MacroDef<"assert"> {
1212
let Defn = [{

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,8 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
495495
libc.src.stdfix.sqrtur
496496
# libc.src.stdfix.sqrtulk
497497
libc.src.stdfix.sqrtulr
498+
libc.src.stdfix.uhksqrtus
499+
libc.src.stdfix.uksqrtui
498500
)
499501
endif()
500502

libc/docs/math/stdfix.rst

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ StdFix Functions
44

55
.. include:: ../check.rst
66

7-
Standards
8-
---------
7+
Standards and Goals
8+
-------------------
99

1010
- stdfix.h is specified in the `ISO/IEC TR 18037:2008 <https://www.iso.org/standard/51126.html>`_,
1111
C extensions to support embedded processors .
1212

1313
- Its `specifications <https://standards.iso.org/ittf/PubliclyAvailableStandards/c051126_ISO_IEC_TR_18037_2008.zip>`_.
1414

15+
- Our goal is to implement a complete set of math functions for fixed point
16+
types, most of them are currently not included in the ISO/IEC TR
17+
18037:2008 standard. Our math functions for fixed point types are modeled
18+
after the C99/C23 math functions for floating point types.
19+
1520
---------------
1621
Source location
1722
---------------
@@ -53,6 +58,8 @@ Predefined Macros
5358
Fixed-point Arithmetics
5459
=======================
5560

61+
The following functions are included in the ISO/IEC TR 18037:2008 standard.
62+
5663
+---------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+
5764
| Function Name | _Fract (r) | _Accum (k) |
5865
| +------------------------------+----------------------------+------------------------------+------------------------------+----------------------------+------------------------------+
@@ -78,8 +85,6 @@ Fixed-point Arithmetics
7885
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
7986
| round | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
8087
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
81-
| sqrt | |check| | | |check| | | |check| | | |check| | | |check| | | | |
82-
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
8388

8489
================== =========
8590
Type Generic Macro Available
@@ -93,6 +98,9 @@ roundfx
9398
Higher math functions
9499
=====================
95100

101+
The following math functions are modeled after C99/C23 math functions for
102+
floating point types, but are not part of the ISO/IEC TR 18037:2008 spec.
103+
96104
+---------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+
97105
| Function Name | _Fract (r) | _Accum (k) |
98106
| +------------------------------+----------------------------+------------------------------+------------------------------+----------------------------+------------------------------+
@@ -108,13 +116,18 @@ Higher math functions
108116
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
109117
| sin | | | | | | | | | | | | |
110118
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
119+
| sqrt | |check| | | |check| | | |check| | | |check| | | |check| | | | |
120+
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
111121
| tan | | | | | | | | | | | | |
112122
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
113123

114124

115125
Conversion Functions
116126
====================
117127

128+
The following conversion functions are included in the ISO/IEC TR 18037:2008
129+
standard.
130+
118131
+---------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+
119132
| Function Name | _Fract (r) | _Accum (k) |
120133
| +------------------------------+----------------------------+------------------------------+------------------------------+----------------------------+------------------------------+

libc/spec/llvm_libc_ext.td

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,29 @@ def LLVMLibcExt : StandardSpec<"llvm_libc_ext"> {
5151
]
5252
>;
5353

54+
HeaderSpec StdFix = HeaderSpec<
55+
"stdfix.h",
56+
[], // macros
57+
[], // types
58+
[], // enums
59+
[ // functions
60+
GuardedFunctionSpec<"sqrtuhr", RetValSpec<UnsignedShortFractType>, [ArgSpec<UnsignedShortFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
61+
GuardedFunctionSpec<"sqrtur", RetValSpec<UnsignedFractType>, [ArgSpec<UnsignedFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
62+
GuardedFunctionSpec<"sqrtulr", RetValSpec<UnsignedLongFractType>, [ArgSpec<UnsignedLongFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
63+
64+
GuardedFunctionSpec<"sqrtuhk", RetValSpec<UnsignedShortAccumType>, [ArgSpec<UnsignedShortAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
65+
GuardedFunctionSpec<"sqrtuk", RetValSpec<UnsignedAccumType>, [ArgSpec<UnsignedAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
66+
GuardedFunctionSpec<"sqrtulk", RetValSpec<UnsignedLongAccumType>, [ArgSpec<UnsignedLongAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
67+
68+
GuardedFunctionSpec<"uhksqrtus", RetValSpec<UnsignedShortAccumType>, [ArgSpec<UnsignedShortType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
69+
GuardedFunctionSpec<"uksqrtui", RetValSpec<UnsignedAccumType>, [ArgSpec<UnsignedIntType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
70+
]
71+
>;
72+
5473
let Headers = [
55-
Strings,
56-
Sched,
5774
Assert,
75+
Sched,
76+
Stdfix,
77+
Strings,
5878
];
5979
}

libc/spec/stdc_ext.td

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,6 @@ def StdcExt : StandardSpec<"stdc_ext"> {
4747
GuardedFunctionSpec<"rounduhk", RetValSpec<UnsignedShortAccumType>, [ArgSpec<UnsignedShortAccumType>, ArgSpec<IntType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
4848
GuardedFunctionSpec<"rounduk", RetValSpec<UnsignedAccumType>, [ArgSpec<UnsignedAccumType>, ArgSpec<IntType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
4949
GuardedFunctionSpec<"roundulk", RetValSpec<UnsignedLongAccumType>, [ArgSpec<UnsignedLongAccumType>, ArgSpec<IntType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
50-
51-
GuardedFunctionSpec<"sqrtuhr", RetValSpec<UnsignedShortFractType>, [ArgSpec<UnsignedShortFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
52-
GuardedFunctionSpec<"sqrtur", RetValSpec<UnsignedFractType>, [ArgSpec<UnsignedFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
53-
GuardedFunctionSpec<"sqrtulr", RetValSpec<UnsignedLongFractType>, [ArgSpec<UnsignedLongFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
54-
55-
GuardedFunctionSpec<"sqrtuhk", RetValSpec<UnsignedShortAccumType>, [ArgSpec<UnsignedShortAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
56-
GuardedFunctionSpec<"sqrtuk", RetValSpec<UnsignedAccumType>, [ArgSpec<UnsignedAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
57-
GuardedFunctionSpec<"sqrtulk", RetValSpec<UnsignedLongAccumType>, [ArgSpec<UnsignedLongAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
5850
]
5951
>;
6052

libc/src/__support/fixed_point/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ add_header_library(
3232
libc.src.__support.macros.attributes
3333
libc.src.__support.macros.optimization
3434
libc.src.__support.CPP.bit
35+
libc.src.__support.CPP.limits
3536
libc.src.__support.CPP.type_traits
3637
)

libc/src/__support/fixed_point/fx_rep.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ template <> struct FXRep<short fract> {
4848
LIBC_INLINE static constexpr Type MAX() { return SFRACT_MIN; }
4949
LIBC_INLINE static constexpr Type ZERO() { return 0.0HR; }
5050
LIBC_INLINE static constexpr Type EPS() { return SFRACT_EPSILON; }
51+
LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5HR; }
52+
LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25HR; }
5153

5254
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
5355
using CompType = cpp::make_signed_t<StorageType>;
@@ -66,6 +68,8 @@ template <> struct FXRep<unsigned short fract> {
6668
LIBC_INLINE static constexpr Type MAX() { return USFRACT_MIN; }
6769
LIBC_INLINE static constexpr Type ZERO() { return 0.0UHR; }
6870
LIBC_INLINE static constexpr Type EPS() { return USFRACT_EPSILON; }
71+
LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5UHR; }
72+
LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25UHR; }
6973

7074
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
7175
using CompType = cpp::make_unsigned_t<StorageType>;
@@ -84,6 +88,8 @@ template <> struct FXRep<fract> {
8488
LIBC_INLINE static constexpr Type MAX() { return FRACT_MIN; }
8589
LIBC_INLINE static constexpr Type ZERO() { return 0.0R; }
8690
LIBC_INLINE static constexpr Type EPS() { return FRACT_EPSILON; }
91+
LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5R; }
92+
LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25R; }
8793

8894
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
8995
using CompType = cpp::make_signed_t<StorageType>;
@@ -102,6 +108,8 @@ template <> struct FXRep<unsigned fract> {
102108
LIBC_INLINE static constexpr Type MAX() { return UFRACT_MIN; }
103109
LIBC_INLINE static constexpr Type ZERO() { return 0.0UR; }
104110
LIBC_INLINE static constexpr Type EPS() { return UFRACT_EPSILON; }
111+
LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5UR; }
112+
LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25UR; }
105113

106114
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
107115
using CompType = cpp::make_unsigned_t<StorageType>;
@@ -120,6 +128,8 @@ template <> struct FXRep<long fract> {
120128
LIBC_INLINE static constexpr Type MAX() { return LFRACT_MIN; }
121129
LIBC_INLINE static constexpr Type ZERO() { return 0.0LR; }
122130
LIBC_INLINE static constexpr Type EPS() { return LFRACT_EPSILON; }
131+
LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5LR; }
132+
LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25LR; }
123133

124134
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
125135
using CompType = cpp::make_signed_t<StorageType>;
@@ -138,6 +148,8 @@ template <> struct FXRep<unsigned long fract> {
138148
LIBC_INLINE static constexpr Type MAX() { return ULFRACT_MIN; }
139149
LIBC_INLINE static constexpr Type ZERO() { return 0.0ULR; }
140150
LIBC_INLINE static constexpr Type EPS() { return ULFRACT_EPSILON; }
151+
LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5ULR; }
152+
LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25ULR; }
141153

142154
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
143155
using CompType = cpp::make_unsigned_t<StorageType>;
@@ -156,6 +168,8 @@ template <> struct FXRep<short accum> {
156168
LIBC_INLINE static constexpr Type MAX() { return SACCUM_MIN; }
157169
LIBC_INLINE static constexpr Type ZERO() { return 0.0HK; }
158170
LIBC_INLINE static constexpr Type EPS() { return SACCUM_EPSILON; }
171+
LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5HK; }
172+
LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25HK; }
159173

160174
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
161175
using CompType = cpp::make_signed_t<StorageType>;
@@ -174,6 +188,8 @@ template <> struct FXRep<unsigned short accum> {
174188
LIBC_INLINE static constexpr Type MAX() { return USACCUM_MIN; }
175189
LIBC_INLINE static constexpr Type ZERO() { return 0.0UHK; }
176190
LIBC_INLINE static constexpr Type EPS() { return USACCUM_EPSILON; }
191+
LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5UHK; }
192+
LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25UHK; }
177193

178194
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
179195
using CompType = cpp::make_unsigned_t<StorageType>;
@@ -192,6 +208,8 @@ template <> struct FXRep<accum> {
192208
LIBC_INLINE static constexpr Type MAX() { return ACCUM_MIN; }
193209
LIBC_INLINE static constexpr Type ZERO() { return 0.0K; }
194210
LIBC_INLINE static constexpr Type EPS() { return ACCUM_EPSILON; }
211+
LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5K; }
212+
LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25K; }
195213

196214
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
197215
using CompType = cpp::make_signed_t<StorageType>;
@@ -210,6 +228,8 @@ template <> struct FXRep<unsigned accum> {
210228
LIBC_INLINE static constexpr Type MAX() { return UACCUM_MIN; }
211229
LIBC_INLINE static constexpr Type ZERO() { return 0.0UK; }
212230
LIBC_INLINE static constexpr Type EPS() { return UACCUM_EPSILON; }
231+
LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5UK; }
232+
LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25UK; }
213233

214234
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
215235
using CompType = cpp::make_unsigned_t<StorageType>;
@@ -228,6 +248,8 @@ template <> struct FXRep<long accum> {
228248
LIBC_INLINE static constexpr Type MAX() { return LACCUM_MIN; }
229249
LIBC_INLINE static constexpr Type ZERO() { return 0.0LK; }
230250
LIBC_INLINE static constexpr Type EPS() { return LACCUM_EPSILON; }
251+
LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5LK; }
252+
LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25LK; }
231253

232254
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
233255
using CompType = cpp::make_signed_t<StorageType>;
@@ -246,6 +268,8 @@ template <> struct FXRep<unsigned long accum> {
246268
LIBC_INLINE static constexpr Type MAX() { return ULACCUM_MIN; }
247269
LIBC_INLINE static constexpr Type ZERO() { return 0.0ULK; }
248270
LIBC_INLINE static constexpr Type EPS() { return ULACCUM_EPSILON; }
271+
LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5ULK; }
272+
LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25ULK; }
249273

250274
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
251275
using CompType = cpp::make_unsigned_t<StorageType>;

0 commit comments

Comments
 (0)