Warning: This file is not a C or C++ file. It does not have highlighting.

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

Warning: This file is not a C or C++ file. It does not have highlighting.

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of libc/src/__support/fixed_point/fx_rep.h