|
10 | 10 | #define LLVM_LIBC_SRC___SUPPORT_FIXEDPOINT_FXREP_H
|
11 | 11 |
|
12 | 12 | #include "include/llvm-libc-macros/stdfix-macros.h"
|
| 13 | +#include "src/__support/CPP/type_traits.h" |
13 | 14 | #include "src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_INLINE_VAR
|
14 | 15 |
|
| 16 | +#include <stdint.h> |
| 17 | + |
15 | 18 | #ifdef LIBC_COMPILER_HAS_FIXED_POINT
|
16 | 19 |
|
17 | 20 | namespace LIBC_NAMESPACE::fixed_point {
|
18 | 21 |
|
| 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 | + |
19 | 36 | template <typename T> struct FXRep;
|
20 | 37 |
|
21 | 38 | template <> struct FXRep<short fract> {
|
22 | 39 | using Type = short _Fract;
|
| 40 | + |
23 | 41 | LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
|
24 | 42 | LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
|
25 | 43 | 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 | + |
26 | 47 | LIBC_INLINE static constexpr Type MIN() { return SFRACT_MIN; }
|
27 | 48 | LIBC_INLINE static constexpr Type MAX() { return SFRACT_MIN; }
|
28 | 49 | LIBC_INLINE static constexpr Type ZERO() { return 0.0HR; }
|
29 | 50 | 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>; |
30 | 54 | };
|
31 | 55 |
|
32 | 56 | template <> struct FXRep<unsigned short fract> {
|
33 | 57 | using Type = unsigned short fract;
|
| 58 | + |
34 | 59 | LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
|
35 | 60 | LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
|
36 | 61 | 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 | + |
37 | 65 | LIBC_INLINE static constexpr Type MIN() { return USFRACT_MIN; }
|
38 | 66 | LIBC_INLINE static constexpr Type MAX() { return USFRACT_MIN; }
|
39 | 67 | LIBC_INLINE static constexpr Type ZERO() { return 0.0UHR; }
|
40 | 68 | 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>; |
41 | 72 | };
|
42 | 73 |
|
43 | 74 | template <> struct FXRep<fract> {
|
44 | 75 | using Type = fract;
|
| 76 | + |
45 | 77 | LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
|
46 | 78 | LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
|
47 | 79 | 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 | + |
48 | 83 | LIBC_INLINE static constexpr Type MIN() { return FRACT_MIN; }
|
49 | 84 | LIBC_INLINE static constexpr Type MAX() { return FRACT_MIN; }
|
50 | 85 | LIBC_INLINE static constexpr Type ZERO() { return 0.0R; }
|
51 | 86 | 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>; |
52 | 90 | };
|
53 | 91 |
|
54 | 92 | template <> struct FXRep<unsigned fract> {
|
55 | 93 | using Type = unsigned fract;
|
| 94 | + |
56 | 95 | LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
|
57 | 96 | LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
|
58 | 97 | 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 | + |
59 | 101 | LIBC_INLINE static constexpr Type MIN() { return UFRACT_MIN; }
|
60 | 102 | LIBC_INLINE static constexpr Type MAX() { return UFRACT_MIN; }
|
61 | 103 | LIBC_INLINE static constexpr Type ZERO() { return 0.0UR; }
|
62 | 104 | 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>; |
63 | 108 | };
|
64 | 109 |
|
65 | 110 | template <> struct FXRep<long fract> {
|
66 | 111 | using Type = long fract;
|
| 112 | + |
67 | 113 | LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
|
68 | 114 | LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
|
69 | 115 | 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 | + |
70 | 119 | LIBC_INLINE static constexpr Type MIN() { return LFRACT_MIN; }
|
71 | 120 | LIBC_INLINE static constexpr Type MAX() { return LFRACT_MIN; }
|
72 | 121 | LIBC_INLINE static constexpr Type ZERO() { return 0.0LR; }
|
73 | 122 | 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>; |
74 | 126 | };
|
75 | 127 |
|
76 | 128 | template <> struct FXRep<unsigned long fract> {
|
77 | 129 | using Type = unsigned long fract;
|
| 130 | + |
78 | 131 | LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
|
79 | 132 | LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
|
80 | 133 | 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 | + |
81 | 137 | LIBC_INLINE static constexpr Type MIN() { return ULFRACT_MIN; }
|
82 | 138 | LIBC_INLINE static constexpr Type MAX() { return ULFRACT_MIN; }
|
83 | 139 | LIBC_INLINE static constexpr Type ZERO() { return 0.0ULR; }
|
84 | 140 | 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>; |
85 | 144 | };
|
86 | 145 |
|
87 | 146 | template <> struct FXRep<short accum> {
|
88 | 147 | using Type = short accum;
|
| 148 | + |
89 | 149 | LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
|
90 | 150 | LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = SACCUM_IBIT;
|
91 | 151 | 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 | + |
92 | 155 | LIBC_INLINE static constexpr Type MIN() { return SACCUM_MIN; }
|
93 | 156 | LIBC_INLINE static constexpr Type MAX() { return SACCUM_MIN; }
|
94 | 157 | LIBC_INLINE static constexpr Type ZERO() { return 0.0HK; }
|
95 | 158 | 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>; |
96 | 162 | };
|
97 | 163 |
|
98 | 164 | template <> struct FXRep<unsigned short accum> {
|
99 | 165 | using Type = unsigned short accum;
|
| 166 | + |
100 | 167 | 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; |
102 | 169 | 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 | + |
103 | 173 | LIBC_INLINE static constexpr Type MIN() { return USACCUM_MIN; }
|
104 | 174 | LIBC_INLINE static constexpr Type MAX() { return USACCUM_MIN; }
|
105 | 175 | LIBC_INLINE static constexpr Type ZERO() { return 0.0UHK; }
|
106 | 176 | 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>; |
107 | 180 | };
|
108 | 181 |
|
109 | 182 | template <> struct FXRep<accum> {
|
110 | 183 | using Type = accum;
|
| 184 | + |
111 | 185 | LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
|
112 | 186 | LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ACCUM_IBIT;
|
113 | 187 | 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 | + |
114 | 191 | LIBC_INLINE static constexpr Type MIN() { return ACCUM_MIN; }
|
115 | 192 | LIBC_INLINE static constexpr Type MAX() { return ACCUM_MIN; }
|
116 | 193 | LIBC_INLINE static constexpr Type ZERO() { return 0.0K; }
|
117 | 194 | 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>; |
118 | 198 | };
|
119 | 199 |
|
120 | 200 | template <> struct FXRep<unsigned accum> {
|
121 | 201 | using Type = unsigned accum;
|
| 202 | + |
122 | 203 | LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
|
123 | 204 | LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = UACCUM_IBIT;
|
124 | 205 | 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 | + |
125 | 209 | LIBC_INLINE static constexpr Type MIN() { return UACCUM_MIN; }
|
126 | 210 | LIBC_INLINE static constexpr Type MAX() { return UACCUM_MIN; }
|
127 | 211 | LIBC_INLINE static constexpr Type ZERO() { return 0.0UK; }
|
128 | 212 | 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>; |
129 | 216 | };
|
130 | 217 |
|
131 | 218 | template <> struct FXRep<long accum> {
|
132 | 219 | using Type = long accum;
|
| 220 | + |
133 | 221 | LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
|
134 | 222 | LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = LACCUM_IBIT;
|
135 | 223 | 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 | + |
136 | 227 | LIBC_INLINE static constexpr Type MIN() { return LACCUM_MIN; }
|
137 | 228 | LIBC_INLINE static constexpr Type MAX() { return LACCUM_MIN; }
|
138 | 229 | LIBC_INLINE static constexpr Type ZERO() { return 0.0LK; }
|
139 | 230 | 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>; |
140 | 234 | };
|
141 | 235 |
|
142 | 236 | template <> struct FXRep<unsigned long accum> {
|
143 | 237 | using Type = unsigned long accum;
|
| 238 | + |
144 | 239 | LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
|
145 | 240 | LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ULACCUM_IBIT;
|
146 | 241 | 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 | + |
147 | 245 | LIBC_INLINE static constexpr Type MIN() { return ULACCUM_MIN; }
|
148 | 246 | LIBC_INLINE static constexpr Type MAX() { return ULACCUM_MIN; }
|
149 | 247 | LIBC_INLINE static constexpr Type ZERO() { return 0.0ULK; }
|
150 | 248 | 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>; |
151 | 252 | };
|
152 | 253 |
|
153 | 254 | template <> struct FXRep<short sat fract> : FXRep<short fract> {};
|
|
0 commit comments