Skip to content

[libc][stdfix] Add integer square root with fixed point output functions. #83959

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -490,6 +490,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