Skip to content

Commit

Permalink
[libc][stdfix] Add integer square root with fixed point output functi…
Browse files Browse the repository at this point in the history
…ons. (#83959)

Fix #83924.
  • Loading branch information
lntue authored Mar 6, 2024
1 parent ee1bcf7 commit ad33fe1
Show file tree
Hide file tree
Showing 20 changed files with 491 additions and 60 deletions.
1 change: 1 addition & 0 deletions libc/config/baremetal/api.td
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ include "config/public_api.td"

include "spec/stdc.td"
include "spec/stdc_ext.td"
include "spec/llvm_libc_ext.td"

def AssertMacro : MacroDef<"assert"> {
let Defn = [{
Expand Down
2 changes: 2 additions & 0 deletions libc/config/baremetal/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,8 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.sqrtur
# libc.src.stdfix.sqrtulk
libc.src.stdfix.sqrtulr
libc.src.stdfix.uhksqrtus
libc.src.stdfix.uksqrtui
)
endif()

Expand Down
2 changes: 2 additions & 0 deletions libc/config/baremetal/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,8 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.sqrtur
# libc.src.stdfix.sqrtulk
libc.src.stdfix.sqrtulr
libc.src.stdfix.uhksqrtus
libc.src.stdfix.uksqrtui
)
endif()

Expand Down
2 changes: 1 addition & 1 deletion libc/config/linux/api.td
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ include "spec/posix.td"
include "spec/linux.td"
include "spec/gnu_ext.td"
include "spec/bsd_ext.td"
include "spec/llvm_libc_ext.td"
include "spec/stdc_ext.td"
include "spec/llvm_libc_ext.td"

def AssertMacro : MacroDef<"assert"> {
let Defn = [{
Expand Down
2 changes: 2 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,8 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.sqrtur
# libc.src.stdfix.sqrtulk
libc.src.stdfix.sqrtulr
libc.src.stdfix.uhksqrtus
libc.src.stdfix.uksqrtui
)
endif()

Expand Down
21 changes: 17 additions & 4 deletions libc/docs/math/stdfix.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@ StdFix Functions

.. include:: ../check.rst

Standards
---------
Standards and Goals
-------------------

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

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

- Our goal is to implement a complete set of math functions for fixed point
types, most of them are currently not included in the ISO/IEC TR
18037:2008 standard. Our math functions for fixed point types are modeled
after the C99/C23 math functions for floating point types.

---------------
Source location
---------------
Expand Down Expand Up @@ -53,6 +58,8 @@ Predefined Macros
Fixed-point Arithmetics
=======================

The following functions are included in the ISO/IEC TR 18037:2008 standard.

+---------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+
| Function Name | _Fract (r) | _Accum (k) |
| +------------------------------+----------------------------+------------------------------+------------------------------+----------------------------+------------------------------+
Expand All @@ -78,8 +85,6 @@ Fixed-point Arithmetics
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| round | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| sqrt | |check| | | |check| | | |check| | | |check| | | |check| | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+

================== =========
Type Generic Macro Available
Expand All @@ -93,6 +98,9 @@ roundfx
Higher math functions
=====================

The following math functions are modeled after C99/C23 math functions for
floating point types, but are not part of the ISO/IEC TR 18037:2008 spec.

+---------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+
| Function Name | _Fract (r) | _Accum (k) |
| +------------------------------+----------------------------+------------------------------+------------------------------+----------------------------+------------------------------+
Expand All @@ -108,13 +116,18 @@ Higher math functions
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| sin | | | | | | | | | | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| sqrt | |check| | | |check| | | |check| | | |check| | | |check| | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| tan | | | | | | | | | | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+


Conversion Functions
====================

The following conversion functions are included in the ISO/IEC TR 18037:2008
standard.

+---------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+
| Function Name | _Fract (r) | _Accum (k) |
| +------------------------------+----------------------------+------------------------------+------------------------------+----------------------------+------------------------------+
Expand Down
24 changes: 22 additions & 2 deletions libc/spec/llvm_libc_ext.td
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,29 @@ def LLVMLibcExt : StandardSpec<"llvm_libc_ext"> {
]
>;

HeaderSpec StdFix = HeaderSpec<
"stdfix.h",
[], // macros
[], // types
[], // enums
[ // functions
GuardedFunctionSpec<"sqrtuhr", RetValSpec<UnsignedShortFractType>, [ArgSpec<UnsignedShortFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"sqrtur", RetValSpec<UnsignedFractType>, [ArgSpec<UnsignedFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"sqrtulr", RetValSpec<UnsignedLongFractType>, [ArgSpec<UnsignedLongFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,

GuardedFunctionSpec<"sqrtuhk", RetValSpec<UnsignedShortAccumType>, [ArgSpec<UnsignedShortAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"sqrtuk", RetValSpec<UnsignedAccumType>, [ArgSpec<UnsignedAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"sqrtulk", RetValSpec<UnsignedLongAccumType>, [ArgSpec<UnsignedLongAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,

GuardedFunctionSpec<"uhksqrtus", RetValSpec<UnsignedShortAccumType>, [ArgSpec<UnsignedShortType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"uksqrtui", RetValSpec<UnsignedAccumType>, [ArgSpec<UnsignedIntType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
]
>;

let Headers = [
Strings,
Sched,
Assert,
Sched,
Stdfix,
Strings,
];
}
8 changes: 0 additions & 8 deletions libc/spec/stdc_ext.td
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,6 @@ def StdcExt : StandardSpec<"stdc_ext"> {
GuardedFunctionSpec<"rounduhk", RetValSpec<UnsignedShortAccumType>, [ArgSpec<UnsignedShortAccumType>, ArgSpec<IntType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"rounduk", RetValSpec<UnsignedAccumType>, [ArgSpec<UnsignedAccumType>, ArgSpec<IntType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"roundulk", RetValSpec<UnsignedLongAccumType>, [ArgSpec<UnsignedLongAccumType>, ArgSpec<IntType>], "LIBC_COMPILER_HAS_FIXED_POINT">,

GuardedFunctionSpec<"sqrtuhr", RetValSpec<UnsignedShortFractType>, [ArgSpec<UnsignedShortFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"sqrtur", RetValSpec<UnsignedFractType>, [ArgSpec<UnsignedFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"sqrtulr", RetValSpec<UnsignedLongFractType>, [ArgSpec<UnsignedLongFractType>], "LIBC_COMPILER_HAS_FIXED_POINT">,

GuardedFunctionSpec<"sqrtuhk", RetValSpec<UnsignedShortAccumType>, [ArgSpec<UnsignedShortAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"sqrtuk", RetValSpec<UnsignedAccumType>, [ArgSpec<UnsignedAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"sqrtulk", RetValSpec<UnsignedLongAccumType>, [ArgSpec<UnsignedLongAccumType>], "LIBC_COMPILER_HAS_FIXED_POINT">,
]
>;

Expand Down
1 change: 1 addition & 0 deletions libc/src/__support/fixed_point/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ add_header_library(
libc.src.__support.macros.attributes
libc.src.__support.macros.optimization
libc.src.__support.CPP.bit
libc.src.__support.CPP.limits
libc.src.__support.CPP.type_traits
)
24 changes: 24 additions & 0 deletions libc/src/__support/fixed_point/fx_rep.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ template <> struct FXRep<short fract> {
LIBC_INLINE static constexpr Type MAX() { return SFRACT_MIN; }
LIBC_INLINE static constexpr Type ZERO() { return 0.0HR; }
LIBC_INLINE static constexpr Type EPS() { return SFRACT_EPSILON; }
LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5HR; }
LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25HR; }

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

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

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

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

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

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

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

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

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

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

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

using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
using CompType = cpp::make_unsigned_t<StorageType>;
Expand Down
Loading

0 comments on commit ad33fe1

Please sign in to comment.