1 | //===-- Unittests for the FXBits class ------------------------------------===// |
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 | #include "include/llvm-libc-macros/stdfix-macros.h" |
10 | |
11 | #include "src/__support/fixed_point/fx_bits.h" |
12 | #include "src/__support/integer_literals.h" |
13 | #include "test/UnitTest/Test.h" |
14 | |
15 | using LIBC_NAMESPACE::fixed_point::FXBits; |
16 | using LIBC_NAMESPACE::fixed_point::FXRep; |
17 | |
18 | using LIBC_NAMESPACE::operator""_u8 ; |
19 | using LIBC_NAMESPACE::operator""_u16 ; |
20 | using LIBC_NAMESPACE::operator""_u32 ; |
21 | using LIBC_NAMESPACE::operator""_u64 ; |
22 | |
23 | class LlvmLibcFxBitsTest : public LIBC_NAMESPACE::testing::Test { |
24 | public: |
25 | template <typename T> void testBitwiseOps() { |
26 | EXPECT_EQ(LIBC_NAMESPACE::fixed_point::bit_and(T(0.75), T(0.375)), T(0.25)); |
27 | EXPECT_EQ(LIBC_NAMESPACE::fixed_point::bit_or(T(0.75), T(0.375)), T(0.875)); |
28 | using StorageType = typename FXRep<T>::StorageType; |
29 | StorageType a = LIBC_NAMESPACE::cpp::bit_cast<StorageType>(T(0.75)); |
30 | a = ~a; |
31 | EXPECT_EQ(LIBC_NAMESPACE::fixed_point::bit_not(T(0.75)), |
32 | FXBits<T>(a).get_val()); |
33 | } |
34 | }; |
35 | |
36 | // -------------------------------- SHORT TESTS -------------------------------- |
37 | |
38 | TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedShortFract) { |
39 | auto bits_var = FXBits<unsigned short fract>(0b00000000_u8); |
40 | |
41 | EXPECT_EQ(bits_var.get_sign(), false); |
42 | EXPECT_EQ(bits_var.get_integral(), 0x00_u8); |
43 | EXPECT_EQ(bits_var.get_fraction(), 0x00_u8); |
44 | |
45 | // Since an unsigned fract has no sign or integral components, setting either |
46 | // should have no effect. |
47 | |
48 | bits_var.set_sign(true); |
49 | |
50 | EXPECT_EQ(bits_var.get_sign(), false); |
51 | EXPECT_EQ(bits_var.get_integral(), 0x00_u8); |
52 | EXPECT_EQ(bits_var.get_fraction(), 0x00_u8); |
53 | |
54 | bits_var.set_integral(0xab); |
55 | |
56 | EXPECT_EQ(bits_var.get_sign(), false); |
57 | EXPECT_EQ(bits_var.get_integral(), 0x00_u8); |
58 | EXPECT_EQ(bits_var.get_fraction(), 0x00_u8); |
59 | |
60 | // but setting the fraction should work |
61 | |
62 | bits_var.set_fraction(0xcd); |
63 | |
64 | EXPECT_EQ(bits_var.get_sign(), false); |
65 | EXPECT_EQ(bits_var.get_integral(), 0x00_u8); |
66 | EXPECT_EQ(bits_var.get_fraction(), 0xcd_u8); |
67 | |
68 | // Bitwise ops |
69 | testBitwiseOps<unsigned short fract>(); |
70 | } |
71 | |
72 | TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedShortAccum) { |
73 | auto bits_var = FXBits<unsigned short accum>(0b00000000'00000000_u16); |
74 | |
75 | EXPECT_EQ(bits_var.get_sign(), false); |
76 | EXPECT_EQ(bits_var.get_integral(), 0x0000_u16); |
77 | EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16); |
78 | |
79 | bits_var.set_sign(true); // 0 sign bits used |
80 | |
81 | EXPECT_EQ(bits_var.get_sign(), false); |
82 | EXPECT_EQ(bits_var.get_integral(), 0x0000_u16); |
83 | EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16); |
84 | |
85 | bits_var.set_integral(0xabcd); // 8 integral bits used |
86 | |
87 | EXPECT_EQ(bits_var.get_sign(), false); |
88 | EXPECT_EQ(bits_var.get_integral(), 0x00cd_u16); |
89 | EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16); |
90 | |
91 | bits_var.set_fraction(0x21fe); // 8 fractional bits used |
92 | |
93 | EXPECT_EQ(bits_var.get_sign(), false); |
94 | EXPECT_EQ(bits_var.get_integral(), 0x00cd_u16); |
95 | EXPECT_EQ(bits_var.get_fraction(), 0x00fe_u16); |
96 | |
97 | // Bitwise ops |
98 | testBitwiseOps<unsigned short accum>(); |
99 | } |
100 | |
101 | TEST_F(LlvmLibcFxBitsTest, FXBits_ShortFract) { |
102 | auto bits_var = FXBits<short fract>(0b0'0000000_u8); |
103 | |
104 | EXPECT_EQ(bits_var.get_sign(), false); |
105 | EXPECT_EQ(bits_var.get_integral(), 0x00_u8); |
106 | EXPECT_EQ(bits_var.get_fraction(), 0x00_u8); |
107 | |
108 | bits_var.set_sign(true); // 1 sign bit used |
109 | |
110 | EXPECT_EQ(bits_var.get_sign(), true); |
111 | EXPECT_EQ(bits_var.get_integral(), 0x00_u8); |
112 | EXPECT_EQ(bits_var.get_fraction(), 0x00_u8); |
113 | |
114 | bits_var.set_integral(0xab); // 0 integral bits used |
115 | |
116 | EXPECT_EQ(bits_var.get_sign(), true); |
117 | EXPECT_EQ(bits_var.get_integral(), 0x00_u8); |
118 | EXPECT_EQ(bits_var.get_fraction(), 0x00_u8); |
119 | |
120 | bits_var.set_fraction(0xcd); // 7 fractional bits used |
121 | |
122 | EXPECT_EQ(bits_var.get_sign(), true); |
123 | EXPECT_EQ(bits_var.get_integral(), 0x00_u8); |
124 | EXPECT_EQ(bits_var.get_fraction(), 0x4d_u8); |
125 | |
126 | // Bitwise ops |
127 | testBitwiseOps<short fract>(); |
128 | } |
129 | |
130 | TEST_F(LlvmLibcFxBitsTest, FXBits_ShortAccum) { |
131 | auto bits_var = FXBits<short accum>(0b0'00000000'0000000_u16); |
132 | |
133 | EXPECT_EQ(bits_var.get_sign(), false); |
134 | EXPECT_EQ(bits_var.get_integral(), 0x0000_u16); |
135 | EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16); |
136 | |
137 | bits_var.set_sign(true); // 1 sign bit used |
138 | |
139 | EXPECT_EQ(bits_var.get_sign(), true); |
140 | EXPECT_EQ(bits_var.get_integral(), 0x0000_u16); |
141 | EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16); |
142 | |
143 | bits_var.set_integral(0xabcd); // 8 integral bits used |
144 | |
145 | EXPECT_EQ(bits_var.get_sign(), true); |
146 | EXPECT_EQ(bits_var.get_integral(), 0x00cd_u16); |
147 | EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16); |
148 | |
149 | bits_var.set_fraction(0x21fe); // 7 fractional bits used |
150 | |
151 | EXPECT_EQ(bits_var.get_sign(), true); |
152 | EXPECT_EQ(bits_var.get_integral(), 0x00cd_u16); |
153 | EXPECT_EQ(bits_var.get_fraction(), 0x007e_u16); |
154 | |
155 | // Bitwise ops |
156 | testBitwiseOps<short accum>(); |
157 | } |
158 | |
159 | // -------------------------------- NORMAL TESTS ------------------------------- |
160 | |
161 | TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedFract) { |
162 | auto bits_var = FXBits<unsigned fract>(0b0000000000000000_u16); |
163 | |
164 | EXPECT_EQ(bits_var.get_sign(), false); |
165 | EXPECT_EQ(bits_var.get_integral(), 0x0000_u16); |
166 | EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16); |
167 | |
168 | bits_var.set_sign(true); // 0 sign bits used |
169 | |
170 | EXPECT_EQ(bits_var.get_sign(), false); |
171 | EXPECT_EQ(bits_var.get_integral(), 0x0000_u16); |
172 | EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16); |
173 | |
174 | bits_var.set_integral(0xabcd); // 0 integral bits used |
175 | |
176 | EXPECT_EQ(bits_var.get_sign(), false); |
177 | EXPECT_EQ(bits_var.get_integral(), 0x0000_u16); |
178 | EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16); |
179 | |
180 | bits_var.set_fraction(0xef12); // 16 fractional bits used |
181 | |
182 | EXPECT_EQ(bits_var.get_sign(), false); |
183 | EXPECT_EQ(bits_var.get_integral(), 0x0000_u16); |
184 | EXPECT_EQ(bits_var.get_fraction(), 0xef12_u16); |
185 | |
186 | // Bitwise ops |
187 | testBitwiseOps<unsigned fract>(); |
188 | } |
189 | |
190 | TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedAccum) { |
191 | auto bits_var = |
192 | FXBits<unsigned accum>(0b0000000000000000'0000000000000000_u32); |
193 | |
194 | EXPECT_EQ(bits_var.get_sign(), false); |
195 | EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32); |
196 | EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32); |
197 | |
198 | bits_var.set_sign(true); // 0 sign bits used |
199 | |
200 | EXPECT_EQ(bits_var.get_sign(), false); |
201 | EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32); |
202 | EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32); |
203 | |
204 | bits_var.set_integral(0xabcd); // 16 integral bits used |
205 | |
206 | EXPECT_EQ(bits_var.get_sign(), false); |
207 | EXPECT_EQ(bits_var.get_integral(), 0x0000abcd_u32); |
208 | EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32); |
209 | |
210 | bits_var.set_fraction(0xef12); // 16 fractional bits used |
211 | |
212 | EXPECT_EQ(bits_var.get_sign(), false); |
213 | EXPECT_EQ(bits_var.get_integral(), 0x0000abcd_u32); |
214 | EXPECT_EQ(bits_var.get_fraction(), 0x0000ef12_u32); |
215 | |
216 | // Bitwise ops |
217 | testBitwiseOps<unsigned accum>(); |
218 | } |
219 | |
220 | TEST_F(LlvmLibcFxBitsTest, FXBits_Fract) { |
221 | auto bits_var = FXBits<fract>(0b0'000000000000000_u16); |
222 | |
223 | EXPECT_EQ(bits_var.get_sign(), false); |
224 | EXPECT_EQ(bits_var.get_integral(), 0x0000_u16); |
225 | EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16); |
226 | |
227 | bits_var.set_sign(true); // 1 sign bit used |
228 | |
229 | EXPECT_EQ(bits_var.get_sign(), true); |
230 | EXPECT_EQ(bits_var.get_integral(), 0x0000_u16); |
231 | EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16); |
232 | |
233 | bits_var.set_integral(0xabcd); // 0 integral bits used |
234 | |
235 | EXPECT_EQ(bits_var.get_sign(), true); |
236 | EXPECT_EQ(bits_var.get_integral(), 0x0000_u16); |
237 | EXPECT_EQ(bits_var.get_fraction(), 0x0000_u16); |
238 | |
239 | bits_var.set_fraction(0xef12); // 15 fractional bits used |
240 | |
241 | EXPECT_EQ(bits_var.get_sign(), true); |
242 | EXPECT_EQ(bits_var.get_integral(), 0x0000_u16); |
243 | EXPECT_EQ(bits_var.get_fraction(), 0x6f12_u16); |
244 | |
245 | // Bitwise ops |
246 | testBitwiseOps<fract>(); |
247 | } |
248 | |
249 | TEST_F(LlvmLibcFxBitsTest, FXBits_Accum) { |
250 | auto bits_var = FXBits<accum>(0b0'0000000000000000'000000000000000_u32); |
251 | |
252 | EXPECT_EQ(bits_var.get_sign(), false); |
253 | EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32); |
254 | EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32); |
255 | |
256 | bits_var.set_sign(true); // 1 sign bit used |
257 | |
258 | EXPECT_EQ(bits_var.get_sign(), true); |
259 | EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32); |
260 | EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32); |
261 | |
262 | bits_var.set_integral(0xabcd); // 16 integral bits used |
263 | |
264 | EXPECT_EQ(bits_var.get_sign(), true); |
265 | EXPECT_EQ(bits_var.get_integral(), 0x0000abcd_u32); |
266 | EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32); |
267 | |
268 | bits_var.set_fraction(0xef12); // 15 fractional bits used |
269 | |
270 | EXPECT_EQ(bits_var.get_sign(), true); |
271 | EXPECT_EQ(bits_var.get_integral(), 0x0000abcd_u32); |
272 | EXPECT_EQ(bits_var.get_fraction(), 0x00006f12_u32); |
273 | |
274 | // Bitwise ops |
275 | testBitwiseOps<accum>(); |
276 | } |
277 | |
278 | // --------------------------------- LONG TESTS -------------------------------- |
279 | |
280 | TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedLongFract) { |
281 | auto bits_var = |
282 | FXBits<unsigned long fract>(0b00000000000000000000000000000000_u32); |
283 | |
284 | EXPECT_EQ(bits_var.get_sign(), false); |
285 | EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32); |
286 | EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32); |
287 | |
288 | bits_var.set_sign(true); // 0 sign bits used |
289 | |
290 | EXPECT_EQ(bits_var.get_sign(), false); |
291 | EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32); |
292 | EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32); |
293 | |
294 | bits_var.set_integral(0xabcdef12); // 0 integral bits used |
295 | |
296 | EXPECT_EQ(bits_var.get_sign(), false); |
297 | EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32); |
298 | EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32); |
299 | |
300 | bits_var.set_fraction(0xfedcba98); // 32 integral bits used |
301 | |
302 | EXPECT_EQ(bits_var.get_sign(), false); |
303 | EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32); |
304 | EXPECT_EQ(bits_var.get_fraction(), 0xfedcba98_u32); |
305 | |
306 | // Bitwise ops |
307 | testBitwiseOps<unsigned long fract>(); |
308 | } |
309 | |
310 | TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedLongAccum) { |
311 | auto bits_var = FXBits<unsigned long accum>( |
312 | 0b00000000000000000000000000000000'00000000000000000000000000000000_u64); |
313 | |
314 | EXPECT_EQ(bits_var.get_sign(), false); |
315 | EXPECT_EQ(bits_var.get_integral(), 0x0000000000000000_u64); |
316 | EXPECT_EQ(bits_var.get_fraction(), 0x0000000000000000_u64); |
317 | |
318 | bits_var.set_sign(true); // 0 sign bits used |
319 | |
320 | EXPECT_EQ(bits_var.get_sign(), false); |
321 | EXPECT_EQ(bits_var.get_integral(), 0x0000000000000000_u64); |
322 | EXPECT_EQ(bits_var.get_fraction(), 0x0000000000000000_u64); |
323 | |
324 | bits_var.set_integral(0xabcdef12); // 32 integral bits used |
325 | |
326 | EXPECT_EQ(bits_var.get_sign(), false); |
327 | EXPECT_EQ(bits_var.get_integral(), 0x00000000abcdef12_u64); |
328 | EXPECT_EQ(bits_var.get_fraction(), 0x0000000000000000_u64); |
329 | |
330 | bits_var.set_fraction(0xfedcba98); // 32 fractional bits used |
331 | |
332 | EXPECT_EQ(bits_var.get_sign(), false); |
333 | EXPECT_EQ(bits_var.get_integral(), 0x00000000abcdef12_u64); |
334 | EXPECT_EQ(bits_var.get_fraction(), 0x00000000fedcba98_u64); |
335 | |
336 | // Bitwise ops |
337 | testBitwiseOps<unsigned long accum>(); |
338 | } |
339 | |
340 | TEST_F(LlvmLibcFxBitsTest, FXBits_LongFract) { |
341 | auto bits_var = FXBits<long fract>(0b0'0000000000000000000000000000000_u32); |
342 | |
343 | EXPECT_EQ(bits_var.get_sign(), false); |
344 | EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32); |
345 | EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32); |
346 | |
347 | bits_var.set_sign(true); // 1 sign bit used |
348 | |
349 | EXPECT_EQ(bits_var.get_sign(), true); |
350 | EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32); |
351 | EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32); |
352 | |
353 | bits_var.set_integral(0xabcdef12); // 0 integral bits used |
354 | |
355 | EXPECT_EQ(bits_var.get_sign(), true); |
356 | EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32); |
357 | EXPECT_EQ(bits_var.get_fraction(), 0x00000000_u32); |
358 | |
359 | bits_var.set_fraction(0xfedcba98); // 31 fractional bits used |
360 | |
361 | EXPECT_EQ(bits_var.get_sign(), true); |
362 | EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32); |
363 | EXPECT_EQ(bits_var.get_fraction(), 0x7edcba98_u32); |
364 | |
365 | // Bitwise ops |
366 | testBitwiseOps<long fract>(); |
367 | } |
368 | |
369 | TEST_F(LlvmLibcFxBitsTest, FXBits_LongAccum) { |
370 | auto bits_var = FXBits<long accum>( |
371 | 0b0'00000000000000000000000000000000'0000000000000000000000000000000_u64); |
372 | |
373 | EXPECT_EQ(bits_var.get_sign(), false); |
374 | EXPECT_EQ(bits_var.get_integral(), 0x0000000000000000_u64); |
375 | EXPECT_EQ(bits_var.get_fraction(), 0x0000000000000000_u64); |
376 | |
377 | bits_var.set_sign(true); // 1 sign bit used |
378 | |
379 | EXPECT_EQ(bits_var.get_sign(), true); |
380 | EXPECT_EQ(bits_var.get_integral(), 0x0000000000000000_u64); |
381 | EXPECT_EQ(bits_var.get_fraction(), 0x0000000000000000_u64); |
382 | |
383 | bits_var.set_integral(0xabcdef12); // 32 integral bits used |
384 | |
385 | EXPECT_EQ(bits_var.get_sign(), true); |
386 | EXPECT_EQ(bits_var.get_integral(), 0x00000000abcdef12_u64); |
387 | EXPECT_EQ(bits_var.get_fraction(), 0x0000000000000000_u64); |
388 | |
389 | bits_var.set_fraction(0xfedcba98); // 31 fractional bits used |
390 | |
391 | EXPECT_EQ(bits_var.get_sign(), true); |
392 | EXPECT_EQ(bits_var.get_integral(), 0x00000000abcdef12_u64); |
393 | EXPECT_EQ(bits_var.get_fraction(), 0x000000007edcba98_u64); |
394 | |
395 | // Bitwise ops |
396 | testBitwiseOps<long accum>(); |
397 | } |
398 | |