diff options
author | lntue <35648136+lntue@users.noreply.github.com> | 2024-02-14 14:26:55 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-14 14:26:55 -0500 |
commit | 0eedc85baad495fa916d1da7b20db93a29b443e1 (patch) | |
tree | 481617ff679c45f6759a684b8016a23e3f37b1f3 | |
parent | 7d28f19f68c82b65cf1180b170f33d6f82422d64 (diff) |
[libc][stdfix] Add FXRep helper class for fixed point types. (#81272)
-rw-r--r-- | libc/src/__support/CMakeLists.txt | 2 | ||||
-rw-r--r-- | libc/src/__support/fixed_point/CMakeLists.txt | 8 | ||||
-rw-r--r-- | libc/src/__support/fixed_point/fx_rep.h | 175 |
3 files changed, 185 insertions, 0 deletions
diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt index 013627788940..1a4b3e9a2145 100644 --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -280,3 +280,5 @@ add_subdirectory(threads) add_subdirectory(File) add_subdirectory(HashTable) + +add_subdirectory(fixed_point) diff --git a/libc/src/__support/fixed_point/CMakeLists.txt b/libc/src/__support/fixed_point/CMakeLists.txt new file mode 100644 index 000000000000..644cbff37aaa --- /dev/null +++ b/libc/src/__support/fixed_point/CMakeLists.txt @@ -0,0 +1,8 @@ +add_header_library( + fx_rep + HDRS + fx_rep.h + DEPENDS + libc.include.llvm-libc-macros.stdfix_macros + libc.src.__support.macros.attributes +) diff --git a/libc/src/__support/fixed_point/fx_rep.h b/libc/src/__support/fixed_point/fx_rep.h new file mode 100644 index 000000000000..88cba3c95c66 --- /dev/null +++ b/libc/src/__support/fixed_point/fx_rep.h @@ -0,0 +1,175 @@ +//===-- Utility class to manipulate fixed point numbers. --*- C++ -*-=========// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_FIXEDPOINT_FXREP_H +#define LLVM_LIBC_SRC___SUPPORT_FIXEDPOINT_FXREP_H + +#include "include/llvm-libc-macros/stdfix-macros.h" +#include "src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_INLINE_VAR + +#ifdef LIBC_COMPILER_HAS_FIXED_POINT + +namespace LIBC_NAMESPACE::fixed_point { + +template <typename T> struct FXRep; + +template <> struct FXRep<short fract> { + using Type = short _Fract; + LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1; + LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0; + LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SFRACT_FBIT; + LIBC_INLINE static constexpr Type MIN() { return SFRACT_MIN; } + 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; } +}; + +template <> struct FXRep<unsigned short fract> { + using Type = unsigned short fract; + LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0; + LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0; + LIBC_INLINE_VAR static constexpr int FRACTION_LEN = USFRACT_FBIT; + LIBC_INLINE static constexpr Type MIN() { return USFRACT_MIN; } + 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; } +}; + +template <> struct FXRep<fract> { + using Type = fract; + LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1; + LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0; + LIBC_INLINE_VAR static constexpr int FRACTION_LEN = FRACT_FBIT; + LIBC_INLINE static constexpr Type MIN() { return FRACT_MIN; } + 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; } +}; + +template <> struct FXRep<unsigned fract> { + using Type = unsigned fract; + LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0; + LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0; + LIBC_INLINE_VAR static constexpr int FRACTION_LEN = UFRACT_FBIT; + LIBC_INLINE static constexpr Type MIN() { return UFRACT_MIN; } + 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; } +}; + +template <> struct FXRep<long fract> { + using Type = long fract; + LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1; + LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0; + LIBC_INLINE_VAR static constexpr int FRACTION_LEN = LFRACT_FBIT; + LIBC_INLINE static constexpr Type MIN() { return LFRACT_MIN; } + 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; } +}; + +template <> struct FXRep<unsigned long fract> { + using Type = unsigned long fract; + LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0; + LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0; + LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ULFRACT_FBIT; + LIBC_INLINE static constexpr Type MIN() { return ULFRACT_MIN; } + 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; } +}; + +template <> struct FXRep<short accum> { + using Type = short accum; + LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1; + LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = SACCUM_IBIT; + LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SACCUM_FBIT; + LIBC_INLINE static constexpr Type MIN() { return SACCUM_MIN; } + 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; } +}; + +template <> struct FXRep<unsigned short accum> { + using Type = unsigned short accum; + LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0; + LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = UACCUM_IBIT; + LIBC_INLINE_VAR static constexpr int FRACTION_LEN = USACCUM_FBIT; + LIBC_INLINE static constexpr Type MIN() { return USACCUM_MIN; } + 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; } +}; + +template <> struct FXRep<accum> { + using Type = accum; + LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1; + LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ACCUM_IBIT; + LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ACCUM_FBIT; + LIBC_INLINE static constexpr Type MIN() { return ACCUM_MIN; } + 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; } +}; + +template <> struct FXRep<unsigned accum> { + using Type = unsigned accum; + LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0; + LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = UACCUM_IBIT; + LIBC_INLINE_VAR static constexpr int FRACTION_LEN = UACCUM_FBIT; + LIBC_INLINE static constexpr Type MIN() { return UACCUM_MIN; } + 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; } +}; + +template <> struct FXRep<long accum> { + using Type = long accum; + LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1; + LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = LACCUM_IBIT; + LIBC_INLINE_VAR static constexpr int FRACTION_LEN = LACCUM_FBIT; + LIBC_INLINE static constexpr Type MIN() { return LACCUM_MIN; } + 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; } +}; + +template <> struct FXRep<unsigned long accum> { + using Type = unsigned long accum; + LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0; + LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ULACCUM_IBIT; + LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ULACCUM_FBIT; + LIBC_INLINE static constexpr Type MIN() { return ULACCUM_MIN; } + 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; } +}; + +template <> struct FXRep<short sat fract> : FXRep<short fract> {}; +template <> struct FXRep<sat fract> : FXRep<fract> {}; +template <> struct FXRep<long sat fract> : FXRep<long fract> {}; +template <> +struct FXRep<unsigned short sat fract> : FXRep<unsigned short fract> {}; +template <> struct FXRep<unsigned sat fract> : FXRep<unsigned fract> {}; +template <> +struct FXRep<unsigned long sat fract> : FXRep<unsigned long fract> {}; + +template <> struct FXRep<short sat accum> : FXRep<short accum> {}; +template <> struct FXRep<sat accum> : FXRep<accum> {}; +template <> struct FXRep<long sat accum> : FXRep<long accum> {}; +template <> +struct FXRep<unsigned short sat accum> : FXRep<unsigned short accum> {}; +template <> struct FXRep<unsigned sat accum> : FXRep<unsigned accum> {}; +template <> +struct FXRep<unsigned long sat accum> : FXRep<unsigned long accum> {}; + +} // namespace LIBC_NAMESPACE::fixed_point + +#endif // LIBC_COMPILER_HAS_FIXED_POINT + +#endif // LLVM_LIBC_SRC___SUPPORT_FIXEDPOINT_FXREP_H |