Skip to content

Commit 82a4a41

Browse files
authored
[libc][stdfix] Add support for fixed point types in the testing infrastructure. (#81819)
1 parent 65c25a4 commit 82a4a41

File tree

5 files changed

+161
-84
lines changed

5 files changed

+161
-84
lines changed

libc/src/__support/fixed_point/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ add_header_library(
55
DEPENDS
66
libc.include.llvm-libc-macros.stdfix_macros
77
libc.src.__support.macros.attributes
8+
libc.src.__support.CPP.type_traits
89
)

libc/src/__support/fixed_point/fx_rep.h

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,144 +10,245 @@
1010
#define LLVM_LIBC_SRC___SUPPORT_FIXEDPOINT_FXREP_H
1111

1212
#include "include/llvm-libc-macros/stdfix-macros.h"
13+
#include "src/__support/CPP/type_traits.h"
1314
#include "src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_INLINE_VAR
1415

16+
#include <stdint.h>
17+
1518
#ifdef LIBC_COMPILER_HAS_FIXED_POINT
1619

1720
namespace LIBC_NAMESPACE::fixed_point {
1821

22+
namespace internal {
23+
24+
template <int Bits> struct Storage {
25+
static_assert(Bits > 0 && Bits <= 64, "Bits has to be between 1 and 64.");
26+
using Type = typename cpp::conditional_t<
27+
(Bits <= 8), uint8_t,
28+
typename cpp::conditional_t<
29+
(Bits <= 16 && Bits > 8), uint16_t,
30+
typename cpp::conditional_t<(Bits <= 32 && Bits > 16), uint32_t,
31+
uint64_t>>>;
32+
};
33+
34+
} // namespace internal
35+
1936
template <typename T> struct FXRep;
2037

2138
template <> struct FXRep<short fract> {
2239
using Type = short _Fract;
40+
2341
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
2442
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
2543
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SFRACT_FBIT;
44+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
45+
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
46+
2647
LIBC_INLINE static constexpr Type MIN() { return SFRACT_MIN; }
2748
LIBC_INLINE static constexpr Type MAX() { return SFRACT_MIN; }
2849
LIBC_INLINE static constexpr Type ZERO() { return 0.0HR; }
2950
LIBC_INLINE static constexpr Type EPS() { return SFRACT_EPSILON; }
51+
52+
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
53+
using CompType = cpp::make_signed_t<StorageType>;
3054
};
3155

3256
template <> struct FXRep<unsigned short fract> {
3357
using Type = unsigned short fract;
58+
3459
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
3560
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
3661
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = USFRACT_FBIT;
62+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
63+
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
64+
3765
LIBC_INLINE static constexpr Type MIN() { return USFRACT_MIN; }
3866
LIBC_INLINE static constexpr Type MAX() { return USFRACT_MIN; }
3967
LIBC_INLINE static constexpr Type ZERO() { return 0.0UHR; }
4068
LIBC_INLINE static constexpr Type EPS() { return USFRACT_EPSILON; }
69+
70+
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
71+
using CompType = cpp::make_unsigned_t<StorageType>;
4172
};
4273

4374
template <> struct FXRep<fract> {
4475
using Type = fract;
76+
4577
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
4678
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
4779
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = FRACT_FBIT;
80+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
81+
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
82+
4883
LIBC_INLINE static constexpr Type MIN() { return FRACT_MIN; }
4984
LIBC_INLINE static constexpr Type MAX() { return FRACT_MIN; }
5085
LIBC_INLINE static constexpr Type ZERO() { return 0.0R; }
5186
LIBC_INLINE static constexpr Type EPS() { return FRACT_EPSILON; }
87+
88+
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
89+
using CompType = cpp::make_signed_t<StorageType>;
5290
};
5391

5492
template <> struct FXRep<unsigned fract> {
5593
using Type = unsigned fract;
94+
5695
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
5796
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
5897
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = UFRACT_FBIT;
98+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
99+
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
100+
59101
LIBC_INLINE static constexpr Type MIN() { return UFRACT_MIN; }
60102
LIBC_INLINE static constexpr Type MAX() { return UFRACT_MIN; }
61103
LIBC_INLINE static constexpr Type ZERO() { return 0.0UR; }
62104
LIBC_INLINE static constexpr Type EPS() { return UFRACT_EPSILON; }
105+
106+
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
107+
using CompType = cpp::make_unsigned_t<StorageType>;
63108
};
64109

65110
template <> struct FXRep<long fract> {
66111
using Type = long fract;
112+
67113
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
68114
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
69115
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = LFRACT_FBIT;
116+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
117+
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
118+
70119
LIBC_INLINE static constexpr Type MIN() { return LFRACT_MIN; }
71120
LIBC_INLINE static constexpr Type MAX() { return LFRACT_MIN; }
72121
LIBC_INLINE static constexpr Type ZERO() { return 0.0LR; }
73122
LIBC_INLINE static constexpr Type EPS() { return LFRACT_EPSILON; }
123+
124+
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
125+
using CompType = cpp::make_signed_t<StorageType>;
74126
};
75127

76128
template <> struct FXRep<unsigned long fract> {
77129
using Type = unsigned long fract;
130+
78131
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
79132
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
80133
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ULFRACT_FBIT;
134+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
135+
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
136+
81137
LIBC_INLINE static constexpr Type MIN() { return ULFRACT_MIN; }
82138
LIBC_INLINE static constexpr Type MAX() { return ULFRACT_MIN; }
83139
LIBC_INLINE static constexpr Type ZERO() { return 0.0ULR; }
84140
LIBC_INLINE static constexpr Type EPS() { return ULFRACT_EPSILON; }
141+
142+
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
143+
using CompType = cpp::make_unsigned_t<StorageType>;
85144
};
86145

87146
template <> struct FXRep<short accum> {
88147
using Type = short accum;
148+
89149
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
90150
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = SACCUM_IBIT;
91151
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SACCUM_FBIT;
152+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
153+
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
154+
92155
LIBC_INLINE static constexpr Type MIN() { return SACCUM_MIN; }
93156
LIBC_INLINE static constexpr Type MAX() { return SACCUM_MIN; }
94157
LIBC_INLINE static constexpr Type ZERO() { return 0.0HK; }
95158
LIBC_INLINE static constexpr Type EPS() { return SACCUM_EPSILON; }
159+
160+
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
161+
using CompType = cpp::make_signed_t<StorageType>;
96162
};
97163

98164
template <> struct FXRep<unsigned short accum> {
99165
using Type = unsigned short accum;
166+
100167
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
101-
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = UACCUM_IBIT;
168+
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = USACCUM_IBIT;
102169
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = USACCUM_FBIT;
170+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
171+
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
172+
103173
LIBC_INLINE static constexpr Type MIN() { return USACCUM_MIN; }
104174
LIBC_INLINE static constexpr Type MAX() { return USACCUM_MIN; }
105175
LIBC_INLINE static constexpr Type ZERO() { return 0.0UHK; }
106176
LIBC_INLINE static constexpr Type EPS() { return USACCUM_EPSILON; }
177+
178+
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
179+
using CompType = cpp::make_unsigned_t<StorageType>;
107180
};
108181

109182
template <> struct FXRep<accum> {
110183
using Type = accum;
184+
111185
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
112186
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ACCUM_IBIT;
113187
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ACCUM_FBIT;
188+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
189+
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
190+
114191
LIBC_INLINE static constexpr Type MIN() { return ACCUM_MIN; }
115192
LIBC_INLINE static constexpr Type MAX() { return ACCUM_MIN; }
116193
LIBC_INLINE static constexpr Type ZERO() { return 0.0K; }
117194
LIBC_INLINE static constexpr Type EPS() { return ACCUM_EPSILON; }
195+
196+
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
197+
using CompType = cpp::make_signed_t<StorageType>;
118198
};
119199

120200
template <> struct FXRep<unsigned accum> {
121201
using Type = unsigned accum;
202+
122203
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
123204
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = UACCUM_IBIT;
124205
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = UACCUM_FBIT;
206+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
207+
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
208+
125209
LIBC_INLINE static constexpr Type MIN() { return UACCUM_MIN; }
126210
LIBC_INLINE static constexpr Type MAX() { return UACCUM_MIN; }
127211
LIBC_INLINE static constexpr Type ZERO() { return 0.0UK; }
128212
LIBC_INLINE static constexpr Type EPS() { return UACCUM_EPSILON; }
213+
214+
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
215+
using CompType = cpp::make_unsigned_t<StorageType>;
129216
};
130217

131218
template <> struct FXRep<long accum> {
132219
using Type = long accum;
220+
133221
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
134222
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = LACCUM_IBIT;
135223
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = LACCUM_FBIT;
224+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
225+
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
226+
136227
LIBC_INLINE static constexpr Type MIN() { return LACCUM_MIN; }
137228
LIBC_INLINE static constexpr Type MAX() { return LACCUM_MIN; }
138229
LIBC_INLINE static constexpr Type ZERO() { return 0.0LK; }
139230
LIBC_INLINE static constexpr Type EPS() { return LACCUM_EPSILON; }
231+
232+
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
233+
using CompType = cpp::make_signed_t<StorageType>;
140234
};
141235

142236
template <> struct FXRep<unsigned long accum> {
143237
using Type = unsigned long accum;
238+
144239
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
145240
LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ULACCUM_IBIT;
146241
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ULACCUM_FBIT;
242+
LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
243+
SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
244+
147245
LIBC_INLINE static constexpr Type MIN() { return ULACCUM_MIN; }
148246
LIBC_INLINE static constexpr Type MAX() { return ULACCUM_MIN; }
149247
LIBC_INLINE static constexpr Type ZERO() { return 0.0ULK; }
150248
LIBC_INLINE static constexpr Type EPS() { return ULACCUM_EPSILON; }
249+
250+
using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
251+
using CompType = cpp::make_unsigned_t<StorageType>;
151252
};
152253

153254
template <> struct FXRep<short sat fract> : FXRep<short fract> {};

libc/test/UnitTest/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ add_unittest_framework_library(
7171
libc.src.__support.CPP.string
7272
libc.src.__support.CPP.string_view
7373
libc.src.__support.CPP.type_traits
74+
libc.src.__support.fixed_point.fx_rep
7475
libc.src.__support.OSUtil.osutil
7576
libc.src.__support.uint128
7677
)

0 commit comments

Comments
 (0)