brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.1 KiB · e68be57 Raw
303 lines · c
1//===-- Utility class to manipulate fixed point numbers. --*- 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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIBC_SRC___SUPPORT_FIXED_POINT_FX_REP_H10#define LLVM_LIBC_SRC___SUPPORT_FIXED_POINT_FX_REP_H11 12#include "hdr/stdint_proxy.h"13#include "include/llvm-libc-macros/stdfix-macros.h"14#include "src/__support/CPP/type_traits.h"15#include "src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_INLINE_VAR16#include "src/__support/macros/config.h"17 18#ifdef LIBC_COMPILER_HAS_FIXED_POINT19 20namespace LIBC_NAMESPACE_DECL {21namespace fixed_point {22 23namespace internal {24 25template <int Bits> struct Storage {26  static_assert(Bits > 0 && Bits <= 64, "Bits has to be between 1 and 64.");27  using Type = typename cpp::conditional_t<28      (Bits <= 8), uint8_t,29      typename cpp::conditional_t<30          (Bits <= 16 && Bits > 8), uint16_t,31          typename cpp::conditional_t<(Bits <= 32 && Bits > 16), uint32_t,32                                      uint64_t>>>;33};34 35} // namespace internal36 37template <typename T> struct FXRep;38 39template <> struct FXRep<short fract> {40  using Type = short _Fract;41 42  LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;43  LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;44  LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SFRACT_FBIT;45  LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;46  LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;47 48  LIBC_INLINE static constexpr Type MIN() { return SFRACT_MIN; }49  LIBC_INLINE static constexpr Type MAX() { return SFRACT_MAX; }50  LIBC_INLINE static constexpr Type ZERO() { return 0.0HR; }51  LIBC_INLINE static constexpr Type EPS() { return SFRACT_EPSILON; }52  LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5HR; }53  LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25HR; }54 55  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;56  using CompType = cpp::make_signed_t<StorageType>;57};58 59template <> struct FXRep<unsigned short fract> {60  using Type = unsigned short fract;61 62  LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;63  LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;64  LIBC_INLINE_VAR static constexpr int FRACTION_LEN = USFRACT_FBIT;65  LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;66  LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;67 68  LIBC_INLINE static constexpr Type MIN() { return USFRACT_MIN; }69  LIBC_INLINE static constexpr Type MAX() { return USFRACT_MAX; }70  LIBC_INLINE static constexpr Type ZERO() { return 0.0UHR; }71  LIBC_INLINE static constexpr Type EPS() { return USFRACT_EPSILON; }72  LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5UHR; }73  LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25UHR; }74 75  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;76  using CompType = cpp::make_unsigned_t<StorageType>;77};78 79template <> struct FXRep<fract> {80  using Type = fract;81 82  LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;83  LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;84  LIBC_INLINE_VAR static constexpr int FRACTION_LEN = FRACT_FBIT;85  LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;86  LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;87 88  LIBC_INLINE static constexpr Type MIN() { return FRACT_MIN; }89  LIBC_INLINE static constexpr Type MAX() { return FRACT_MAX; }90  LIBC_INLINE static constexpr Type ZERO() { return 0.0R; }91  LIBC_INLINE static constexpr Type EPS() { return FRACT_EPSILON; }92  LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5R; }93  LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25R; }94 95  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;96  using CompType = cpp::make_signed_t<StorageType>;97};98 99template <> struct FXRep<unsigned fract> {100  using Type = unsigned fract;101 102  LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;103  LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;104  LIBC_INLINE_VAR static constexpr int FRACTION_LEN = UFRACT_FBIT;105  LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;106  LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;107 108  LIBC_INLINE static constexpr Type MIN() { return UFRACT_MIN; }109  LIBC_INLINE static constexpr Type MAX() { return UFRACT_MAX; }110  LIBC_INLINE static constexpr Type ZERO() { return 0.0UR; }111  LIBC_INLINE static constexpr Type EPS() { return UFRACT_EPSILON; }112  LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5UR; }113  LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25UR; }114 115  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;116  using CompType = cpp::make_unsigned_t<StorageType>;117};118 119template <> struct FXRep<long fract> {120  using Type = long fract;121 122  LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;123  LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;124  LIBC_INLINE_VAR static constexpr int FRACTION_LEN = LFRACT_FBIT;125  LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;126  LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;127 128  LIBC_INLINE static constexpr Type MIN() { return LFRACT_MIN; }129  LIBC_INLINE static constexpr Type MAX() { return LFRACT_MAX; }130  LIBC_INLINE static constexpr Type ZERO() { return 0.0LR; }131  LIBC_INLINE static constexpr Type EPS() { return LFRACT_EPSILON; }132  LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5LR; }133  LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25LR; }134 135  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;136  using CompType = cpp::make_signed_t<StorageType>;137};138 139template <> struct FXRep<unsigned long fract> {140  using Type = unsigned long fract;141 142  LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;143  LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;144  LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ULFRACT_FBIT;145  LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;146  LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;147 148  LIBC_INLINE static constexpr Type MIN() { return ULFRACT_MIN; }149  LIBC_INLINE static constexpr Type MAX() { return ULFRACT_MAX; }150  LIBC_INLINE static constexpr Type ZERO() { return 0.0ULR; }151  LIBC_INLINE static constexpr Type EPS() { return ULFRACT_EPSILON; }152  LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5ULR; }153  LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25ULR; }154 155  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;156  using CompType = cpp::make_unsigned_t<StorageType>;157};158 159template <> struct FXRep<short accum> {160  using Type = short accum;161 162  LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;163  LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = SACCUM_IBIT;164  LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SACCUM_FBIT;165  LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;166  LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;167 168  LIBC_INLINE static constexpr Type MIN() { return SACCUM_MIN; }169  LIBC_INLINE static constexpr Type MAX() { return SACCUM_MAX; }170  LIBC_INLINE static constexpr Type ZERO() { return 0.0HK; }171  LIBC_INLINE static constexpr Type EPS() { return SACCUM_EPSILON; }172  LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5HK; }173  LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25HK; }174 175  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;176  using CompType = cpp::make_signed_t<StorageType>;177};178 179template <> struct FXRep<unsigned short accum> {180  using Type = unsigned short accum;181 182  LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;183  LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = USACCUM_IBIT;184  LIBC_INLINE_VAR static constexpr int FRACTION_LEN = USACCUM_FBIT;185  LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;186  LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;187 188  LIBC_INLINE static constexpr Type MIN() { return USACCUM_MIN; }189  LIBC_INLINE static constexpr Type MAX() { return USACCUM_MAX; }190  LIBC_INLINE static constexpr Type ZERO() { return 0.0UHK; }191  LIBC_INLINE static constexpr Type EPS() { return USACCUM_EPSILON; }192  LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5UHK; }193  LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25UHK; }194 195  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;196  using CompType = cpp::make_unsigned_t<StorageType>;197};198 199template <> struct FXRep<accum> {200  using Type = accum;201 202  LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;203  LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ACCUM_IBIT;204  LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ACCUM_FBIT;205  LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;206  LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;207 208  LIBC_INLINE static constexpr Type MIN() { return ACCUM_MIN; }209  LIBC_INLINE static constexpr Type MAX() { return ACCUM_MAX; }210  LIBC_INLINE static constexpr Type ZERO() { return 0.0K; }211  LIBC_INLINE static constexpr Type EPS() { return ACCUM_EPSILON; }212  LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5K; }213  LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25K; }214 215  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;216  using CompType = cpp::make_signed_t<StorageType>;217};218 219template <> struct FXRep<unsigned accum> {220  using Type = unsigned accum;221 222  LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;223  LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = UACCUM_IBIT;224  LIBC_INLINE_VAR static constexpr int FRACTION_LEN = UACCUM_FBIT;225  LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;226  LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;227 228  LIBC_INLINE static constexpr Type MIN() { return UACCUM_MIN; }229  LIBC_INLINE static constexpr Type MAX() { return UACCUM_MAX; }230  LIBC_INLINE static constexpr Type ZERO() { return 0.0UK; }231  LIBC_INLINE static constexpr Type EPS() { return UACCUM_EPSILON; }232  LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5UK; }233  LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25UK; }234 235  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;236  using CompType = cpp::make_unsigned_t<StorageType>;237};238 239template <> struct FXRep<long accum> {240  using Type = long accum;241 242  LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;243  LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = LACCUM_IBIT;244  LIBC_INLINE_VAR static constexpr int FRACTION_LEN = LACCUM_FBIT;245  LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;246  LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;247 248  LIBC_INLINE static constexpr Type MIN() { return LACCUM_MIN; }249  LIBC_INLINE static constexpr Type MAX() { return LACCUM_MAX; }250  LIBC_INLINE static constexpr Type ZERO() { return 0.0LK; }251  LIBC_INLINE static constexpr Type EPS() { return LACCUM_EPSILON; }252  LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5LK; }253  LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25LK; }254 255  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;256  using CompType = cpp::make_signed_t<StorageType>;257};258 259template <> struct FXRep<unsigned long accum> {260  using Type = unsigned long accum;261 262  LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;263  LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ULACCUM_IBIT;264  LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ULACCUM_FBIT;265  LIBC_INLINE_VAR static constexpr int VALUE_LEN = INTEGRAL_LEN + FRACTION_LEN;266  LIBC_INLINE_VAR static constexpr int TOTAL_LEN = SIGN_LEN + VALUE_LEN;267 268  LIBC_INLINE static constexpr Type MIN() { return ULACCUM_MIN; }269  LIBC_INLINE static constexpr Type MAX() { return ULACCUM_MAX; }270  LIBC_INLINE static constexpr Type ZERO() { return 0.0ULK; }271  LIBC_INLINE static constexpr Type EPS() { return ULACCUM_EPSILON; }272  LIBC_INLINE static constexpr Type ONE_HALF() { return 0.5ULK; }273  LIBC_INLINE static constexpr Type ONE_FOURTH() { return 0.25ULK; }274 275  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;276  using CompType = cpp::make_unsigned_t<StorageType>;277};278 279template <> struct FXRep<short sat fract> : FXRep<short fract> {};280template <> struct FXRep<sat fract> : FXRep<fract> {};281template <> struct FXRep<long sat fract> : FXRep<long fract> {};282template <>283struct FXRep<unsigned short sat fract> : FXRep<unsigned short fract> {};284template <> struct FXRep<unsigned sat fract> : FXRep<unsigned fract> {};285template <>286struct FXRep<unsigned long sat fract> : FXRep<unsigned long fract> {};287 288template <> struct FXRep<short sat accum> : FXRep<short accum> {};289template <> struct FXRep<sat accum> : FXRep<accum> {};290template <> struct FXRep<long sat accum> : FXRep<long accum> {};291template <>292struct FXRep<unsigned short sat accum> : FXRep<unsigned short accum> {};293template <> struct FXRep<unsigned sat accum> : FXRep<unsigned accum> {};294template <>295struct FXRep<unsigned long sat accum> : FXRep<unsigned long accum> {};296 297} // namespace fixed_point298} // namespace LIBC_NAMESPACE_DECL299 300#endif // LIBC_COMPILER_HAS_FIXED_POINT301 302#endif // LLVM_LIBC_SRC___SUPPORT_FIXED_POINT_FX_REP_H303