1 //===- unittests/ADT/FixedPointTest.cpp -- fixed point number tests -----===//
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 "llvm/ADT/APFixedPoint.h"
10 #include "llvm/ADT/APFloat.h"
11 #include "llvm/ADT/APSInt.h"
12 #include "gtest/gtest.h"
13 
14 using llvm::APFixedPoint;
15 using llvm::APFloat;
16 using llvm::APInt;
17 using llvm::APSInt;
18 using llvm::FixedPointSemantics;
19 
20 namespace {
21 
Saturated(FixedPointSemantics Sema)22 FixedPointSemantics Saturated(FixedPointSemantics Sema) {
23   Sema.setSaturated(true);
24   return Sema;
25 }
26 
getSAccumSema()27 FixedPointSemantics getSAccumSema() {
28   return FixedPointSemantics(/*width=*/16, /*scale=*/7, /*isSigned=*/true,
29                              /*isSaturated=*/false,
30                              /*hasUnsignedPadding=*/false);
31 }
32 
getAccumSema()33 FixedPointSemantics getAccumSema() {
34   return FixedPointSemantics(/*width=*/32, /*scale=*/15, /*isSigned=*/true,
35                              /*isSaturated=*/false,
36                              /*hasUnsignedPadding=*/false);
37 }
38 
getLAccumSema()39 FixedPointSemantics getLAccumSema() {
40   return FixedPointSemantics(/*width=*/64, /*scale=*/31, /*isSigned=*/true,
41                              /*isSaturated=*/false,
42                              /*hasUnsignedPadding=*/false);
43 }
44 
getSFractSema()45 FixedPointSemantics getSFractSema() {
46   return FixedPointSemantics(/*width=*/8, /*scale=*/7, /*isSigned=*/true,
47                              /*isSaturated=*/false,
48                              /*hasUnsignedPadding=*/false);
49 }
50 
getFractSema()51 FixedPointSemantics getFractSema() {
52   return FixedPointSemantics(/*width=*/16, /*scale=*/15, /*isSigned=*/true,
53                              /*isSaturated=*/false,
54                              /*hasUnsignedPadding=*/false);
55 }
56 
getLFractSema()57 FixedPointSemantics getLFractSema() {
58   return FixedPointSemantics(/*width=*/32, /*scale=*/31, /*isSigned=*/true,
59                              /*isSaturated=*/false,
60                              /*hasUnsignedPadding=*/false);
61 }
62 
getUSAccumSema()63 FixedPointSemantics getUSAccumSema() {
64   return FixedPointSemantics(/*width=*/16, /*scale=*/8, /*isSigned=*/false,
65                              /*isSaturated=*/false,
66                              /*hasUnsignedPadding=*/false);
67 }
68 
getUAccumSema()69 FixedPointSemantics getUAccumSema() {
70   return FixedPointSemantics(/*width=*/32, /*scale=*/16, /*isSigned=*/false,
71                              /*isSaturated=*/false,
72                              /*hasUnsignedPadding=*/false);
73 }
74 
getULAccumSema()75 FixedPointSemantics getULAccumSema() {
76   return FixedPointSemantics(/*width=*/64, /*scale=*/32, /*isSigned=*/false,
77                              /*isSaturated=*/false,
78                              /*hasUnsignedPadding=*/false);
79 }
80 
getUSFractSema()81 FixedPointSemantics getUSFractSema() {
82   return FixedPointSemantics(/*width=*/8, /*scale=*/8, /*isSigned=*/false,
83                              /*isSaturated=*/false,
84                              /*hasUnsignedPadding=*/false);
85 }
86 
getUFractSema()87 FixedPointSemantics getUFractSema() {
88   return FixedPointSemantics(/*width=*/16, /*scale=*/16, /*isSigned=*/false,
89                              /*isSaturated=*/false,
90                              /*hasUnsignedPadding=*/false);
91 }
92 
getULFractSema()93 FixedPointSemantics getULFractSema() {
94   return FixedPointSemantics(/*width=*/32, /*scale=*/32, /*isSigned=*/false,
95                              /*isSaturated=*/false,
96                              /*hasUnsignedPadding=*/false);
97 }
98 
getPadUSAccumSema()99 FixedPointSemantics getPadUSAccumSema() {
100   return FixedPointSemantics(/*width=*/16, /*scale=*/7, /*isSigned=*/false,
101                              /*isSaturated=*/false,
102                              /*hasUnsignedPadding=*/true);
103 }
104 
getPadUAccumSema()105 FixedPointSemantics getPadUAccumSema() {
106   return FixedPointSemantics(/*width=*/32, /*scale=*/15, /*isSigned=*/false,
107                              /*isSaturated=*/false,
108                              /*hasUnsignedPadding=*/true);
109 }
110 
getPadULAccumSema()111 FixedPointSemantics getPadULAccumSema() {
112   return FixedPointSemantics(/*width=*/64, /*scale=*/31, /*isSigned=*/false,
113                              /*isSaturated=*/false,
114                              /*hasUnsignedPadding=*/true);
115 }
116 
getPadUSFractSema()117 FixedPointSemantics getPadUSFractSema() {
118   return FixedPointSemantics(/*width=*/8, /*scale=*/7, /*isSigned=*/false,
119                              /*isSaturated=*/false,
120                              /*hasUnsignedPadding=*/true);
121 }
122 
getPadUFractSema()123 FixedPointSemantics getPadUFractSema() {
124   return FixedPointSemantics(/*width=*/16, /*scale=*/15, /*isSigned=*/false,
125                              /*isSaturated=*/false,
126                              /*hasUnsignedPadding=*/true);
127 }
128 
getPadULFractSema()129 FixedPointSemantics getPadULFractSema() {
130   return FixedPointSemantics(/*width=*/32, /*scale=*/31, /*isSigned=*/false,
131                              /*isSaturated=*/false,
132                              /*hasUnsignedPadding=*/true);
133 }
134 
CheckUnpaddedMax(const FixedPointSemantics & Sema)135 void CheckUnpaddedMax(const FixedPointSemantics &Sema) {
136   ASSERT_EQ(APFixedPoint::getMax(Sema).getValue(),
137             APSInt::getMaxValue(Sema.getWidth(), !Sema.isSigned()));
138 }
139 
CheckPaddedMax(const FixedPointSemantics & Sema)140 void CheckPaddedMax(const FixedPointSemantics &Sema) {
141   ASSERT_EQ(APFixedPoint::getMax(Sema).getValue(),
142             APSInt::getMaxValue(Sema.getWidth(), !Sema.isSigned()) >> 1);
143 }
144 
CheckMin(const FixedPointSemantics & Sema)145 void CheckMin(const FixedPointSemantics &Sema) {
146   ASSERT_EQ(APFixedPoint::getMin(Sema).getValue(),
147             APSInt::getMinValue(Sema.getWidth(), !Sema.isSigned()));
148 }
149 
TEST(FixedPointTest,getMax)150 TEST(FixedPointTest, getMax) {
151   CheckUnpaddedMax(getSAccumSema());
152   CheckUnpaddedMax(getAccumSema());
153   CheckUnpaddedMax(getLAccumSema());
154   CheckUnpaddedMax(getUSAccumSema());
155   CheckUnpaddedMax(getUAccumSema());
156   CheckUnpaddedMax(getULAccumSema());
157   CheckUnpaddedMax(getSFractSema());
158   CheckUnpaddedMax(getFractSema());
159   CheckUnpaddedMax(getLFractSema());
160   CheckUnpaddedMax(getUSFractSema());
161   CheckUnpaddedMax(getUFractSema());
162   CheckUnpaddedMax(getULFractSema());
163 
164   CheckPaddedMax(getPadUSAccumSema());
165   CheckPaddedMax(getPadUAccumSema());
166   CheckPaddedMax(getPadULAccumSema());
167   CheckPaddedMax(getPadUSFractSema());
168   CheckPaddedMax(getPadUFractSema());
169   CheckPaddedMax(getPadULFractSema());
170 }
171 
TEST(FixedPointTest,getMin)172 TEST(FixedPointTest, getMin) {
173   CheckMin(getSAccumSema());
174   CheckMin(getAccumSema());
175   CheckMin(getLAccumSema());
176   CheckMin(getUSAccumSema());
177   CheckMin(getUAccumSema());
178   CheckMin(getULAccumSema());
179   CheckMin(getSFractSema());
180   CheckMin(getFractSema());
181   CheckMin(getLFractSema());
182   CheckMin(getUSFractSema());
183   CheckMin(getUFractSema());
184   CheckMin(getULFractSema());
185 
186   CheckMin(getPadUSAccumSema());
187   CheckMin(getPadUAccumSema());
188   CheckMin(getPadULAccumSema());
189   CheckMin(getPadUSFractSema());
190   CheckMin(getPadUFractSema());
191   CheckMin(getPadULFractSema());
192 }
193 
CheckIntPart(const FixedPointSemantics & Sema,int64_t IntPart)194 void CheckIntPart(const FixedPointSemantics &Sema, int64_t IntPart) {
195   unsigned Scale = Sema.getScale();
196 
197   // Value with a fraction
198   APFixedPoint ValWithFract(APInt(Sema.getWidth(),
199                                   (IntPart << Scale) + (1ULL << (Scale - 1)),
200                                   Sema.isSigned()),
201                             Sema);
202   ASSERT_EQ(ValWithFract.getIntPart(), IntPart);
203 
204   // Just fraction
205   APFixedPoint JustFract(
206       APInt(Sema.getWidth(), (1ULL << (Scale - 1)), Sema.isSigned()), Sema);
207   ASSERT_EQ(JustFract.getIntPart(), 0);
208 
209   // Whole number
210   APFixedPoint WholeNum(
211       APInt(Sema.getWidth(), (IntPart << Scale), Sema.isSigned()), Sema);
212   ASSERT_EQ(WholeNum.getIntPart(), IntPart);
213 
214   // Negative
215   if (Sema.isSigned()) {
216     APFixedPoint Negative(
217         APInt(Sema.getWidth(), (IntPart << Scale), Sema.isSigned()), Sema);
218     ASSERT_EQ(Negative.getIntPart(), IntPart);
219   }
220 }
221 
CheckIntPartMin(const FixedPointSemantics & Sema,int64_t Expected)222 void CheckIntPartMin(const FixedPointSemantics &Sema, int64_t Expected) {
223   EXPECT_TRUE(APSInt::compareValues(APFixedPoint::getMin(Sema).getIntPart(),
224                                     APSInt::get(Expected)) == 0);
225 }
226 
CheckIntPartMax(const FixedPointSemantics & Sema,uint64_t Expected)227 void CheckIntPartMax(const FixedPointSemantics &Sema, uint64_t Expected) {
228   EXPECT_TRUE(APSInt::compareValues(APFixedPoint::getMax(Sema).getIntPart(),
229                                     APSInt::getUnsigned(Expected)) == 0);
230 }
231 
TEST(FixedPoint,getIntPart)232 TEST(FixedPoint, getIntPart) {
233   // Normal values
234   CheckIntPart(getSAccumSema(), 2);
235   CheckIntPart(getAccumSema(), 2);
236   CheckIntPart(getLAccumSema(), 2);
237   CheckIntPart(getUSAccumSema(), 2);
238   CheckIntPart(getUAccumSema(), 2);
239   CheckIntPart(getULAccumSema(), 2);
240 
241   // Zero
242   CheckIntPart(getSAccumSema(), 0);
243   CheckIntPart(getAccumSema(), 0);
244   CheckIntPart(getLAccumSema(), 0);
245   CheckIntPart(getUSAccumSema(), 0);
246   CheckIntPart(getUAccumSema(), 0);
247   CheckIntPart(getULAccumSema(), 0);
248 
249   CheckIntPart(getSFractSema(), 0);
250   CheckIntPart(getFractSema(), 0);
251   CheckIntPart(getLFractSema(), 0);
252   CheckIntPart(getUSFractSema(), 0);
253   CheckIntPart(getUFractSema(), 0);
254   CheckIntPart(getULFractSema(), 0);
255 
256   // Min
257   CheckIntPartMin(getSAccumSema(), -256);
258   CheckIntPartMin(getAccumSema(), -65536);
259   CheckIntPartMin(getLAccumSema(), -4294967296);
260 
261   CheckIntPartMin(getSFractSema(), -1);
262   CheckIntPartMin(getFractSema(), -1);
263   CheckIntPartMin(getLFractSema(), -1);
264 
265   // Max
266   CheckIntPartMax(getSAccumSema(), 255);
267   CheckIntPartMax(getAccumSema(), 65535);
268   CheckIntPartMax(getLAccumSema(), 4294967295);
269   CheckIntPartMax(getUSAccumSema(), 255);
270   CheckIntPartMax(getUAccumSema(), 65535);
271   CheckIntPartMax(getULAccumSema(), 4294967295);
272 
273   CheckIntPartMax(getSFractSema(), 0);
274   CheckIntPartMax(getFractSema(), 0);
275   CheckIntPartMax(getLFractSema(), 0);
276   CheckIntPartMax(getUSFractSema(), 0);
277   CheckIntPartMax(getUFractSema(), 0);
278   CheckIntPartMax(getULFractSema(), 0);
279 
280   // Padded
281   // Normal Values
282   CheckIntPart(getPadUSAccumSema(), 2);
283   CheckIntPart(getPadUAccumSema(), 2);
284   CheckIntPart(getPadULAccumSema(), 2);
285 
286   // Zero
287   CheckIntPart(getPadUSAccumSema(), 0);
288   CheckIntPart(getPadUAccumSema(), 0);
289   CheckIntPart(getPadULAccumSema(), 0);
290 
291   CheckIntPart(getPadUSFractSema(), 0);
292   CheckIntPart(getPadUFractSema(), 0);
293   CheckIntPart(getPadULFractSema(), 0);
294 
295   // Max
296   CheckIntPartMax(getPadUSAccumSema(), 255);
297   CheckIntPartMax(getPadUAccumSema(), 65535);
298   CheckIntPartMax(getPadULAccumSema(), 4294967295);
299 
300   CheckIntPartMax(getPadUSFractSema(), 0);
301   CheckIntPartMax(getPadUFractSema(), 0);
302   CheckIntPartMax(getPadULFractSema(), 0);
303 }
304 
TEST(FixedPoint,compare)305 TEST(FixedPoint, compare) {
306   // Equality
307   // With fractional part (2.5)
308   // Across sizes
309   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
310             APFixedPoint(81920, getAccumSema()));
311   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
312             APFixedPoint(5368709120, getLAccumSema()));
313   ASSERT_EQ(APFixedPoint(0, getSAccumSema()), APFixedPoint(0, getLAccumSema()));
314 
315   // Across types (0.5)
316   ASSERT_EQ(APFixedPoint(64, getSAccumSema()),
317             APFixedPoint(64, getSFractSema()));
318   ASSERT_EQ(APFixedPoint(16384, getAccumSema()),
319             APFixedPoint(16384, getFractSema()));
320   ASSERT_EQ(APFixedPoint(1073741824, getLAccumSema()),
321             APFixedPoint(1073741824, getLFractSema()));
322 
323   // Across widths and types (0.5)
324   ASSERT_EQ(APFixedPoint(64, getSAccumSema()),
325             APFixedPoint(16384, getFractSema()));
326   ASSERT_EQ(APFixedPoint(64, getSAccumSema()),
327             APFixedPoint(1073741824, getLFractSema()));
328 
329   // Across saturation
330   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
331             APFixedPoint(81920, Saturated(getAccumSema())));
332 
333   // Across signs
334   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
335             APFixedPoint(640, getUSAccumSema()));
336   ASSERT_EQ(APFixedPoint(-320, getSAccumSema()),
337             APFixedPoint(-81920, getAccumSema()));
338 
339   // Across padding
340   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
341             APFixedPoint(320, getPadUSAccumSema()));
342   ASSERT_EQ(APFixedPoint(640, getUSAccumSema()),
343             APFixedPoint(320, getPadUSAccumSema()));
344 
345   // Less than
346   ASSERT_LT(APFixedPoint(-1, getSAccumSema()), APFixedPoint(0, getAccumSema()));
347   ASSERT_LT(APFixedPoint(-1, getSAccumSema()),
348             APFixedPoint(0, getUAccumSema()));
349   ASSERT_LT(APFixedPoint(0, getSAccumSema()), APFixedPoint(1, getAccumSema()));
350   ASSERT_LT(APFixedPoint(0, getSAccumSema()), APFixedPoint(1, getUAccumSema()));
351   ASSERT_LT(APFixedPoint(0, getUSAccumSema()), APFixedPoint(1, getAccumSema()));
352   ASSERT_LT(APFixedPoint(0, getUSAccumSema()),
353             APFixedPoint(1, getUAccumSema()));
354 
355   // Greater than
356   ASSERT_GT(APFixedPoint(0, getAccumSema()), APFixedPoint(-1, getSAccumSema()));
357   ASSERT_GT(APFixedPoint(0, getUAccumSema()),
358             APFixedPoint(-1, getSAccumSema()));
359   ASSERT_GT(APFixedPoint(1, getAccumSema()), APFixedPoint(0, getSAccumSema()));
360   ASSERT_GT(APFixedPoint(1, getUAccumSema()), APFixedPoint(0, getSAccumSema()));
361   ASSERT_GT(APFixedPoint(1, getAccumSema()), APFixedPoint(0, getUSAccumSema()));
362   ASSERT_GT(APFixedPoint(1, getUAccumSema()),
363             APFixedPoint(0, getUSAccumSema()));
364 }
365 
366 // Check that a fixed point value in one sema is the same in another sema
CheckUnsaturatedConversion(FixedPointSemantics Src,FixedPointSemantics Dst,int64_t TestVal)367 void CheckUnsaturatedConversion(FixedPointSemantics Src,
368                                 FixedPointSemantics Dst, int64_t TestVal) {
369   int64_t ScaledVal = TestVal;
370   bool IsNegative = ScaledVal < 0;
371   if (IsNegative)
372     ScaledVal = -ScaledVal;
373 
374   if (Dst.getScale() > Src.getScale()) {
375     ScaledVal <<= (Dst.getScale() - Src.getScale());
376   } else {
377     ScaledVal >>= (Src.getScale() - Dst.getScale());
378   }
379 
380   if (IsNegative)
381     ScaledVal = -ScaledVal;
382 
383   APFixedPoint Fixed(TestVal, Src);
384   APFixedPoint Expected(ScaledVal, Dst);
385   ASSERT_EQ(Fixed.convert(Dst), Expected);
386 }
387 
388 // Check the value in a given fixed point sema overflows to the saturated min
389 // for another sema
CheckSaturatedConversionMin(FixedPointSemantics Src,FixedPointSemantics Dst,int64_t TestVal)390 void CheckSaturatedConversionMin(FixedPointSemantics Src,
391                                  FixedPointSemantics Dst, int64_t TestVal) {
392   APFixedPoint Fixed(TestVal, Src);
393   ASSERT_EQ(Fixed.convert(Dst), APFixedPoint::getMin(Dst));
394 }
395 
396 // Check the value in a given fixed point sema overflows to the saturated max
397 // for another sema
CheckSaturatedConversionMax(FixedPointSemantics Src,FixedPointSemantics Dst,int64_t TestVal)398 void CheckSaturatedConversionMax(FixedPointSemantics Src,
399                                  FixedPointSemantics Dst, int64_t TestVal) {
400   APFixedPoint Fixed(TestVal, Src);
401   ASSERT_EQ(Fixed.convert(Dst), APFixedPoint::getMax(Dst));
402 }
403 
404 // Check one signed _Accum sema converted to other sema for different values.
CheckSignedAccumConversionsAgainstOthers(FixedPointSemantics Src,int64_t OneVal)405 void CheckSignedAccumConversionsAgainstOthers(FixedPointSemantics Src,
406                                               int64_t OneVal) {
407   int64_t NormalVal = (OneVal * 2) + (OneVal / 2); // 2.5
408   int64_t HalfVal = (OneVal / 2);                  // 0.5
409 
410   // +Accums to Accums
411   CheckUnsaturatedConversion(Src, getSAccumSema(), NormalVal);
412   CheckUnsaturatedConversion(Src, getAccumSema(), NormalVal);
413   CheckUnsaturatedConversion(Src, getLAccumSema(), NormalVal);
414   CheckUnsaturatedConversion(Src, getUSAccumSema(), NormalVal);
415   CheckUnsaturatedConversion(Src, getUAccumSema(), NormalVal);
416   CheckUnsaturatedConversion(Src, getULAccumSema(), NormalVal);
417   CheckUnsaturatedConversion(Src, getPadUSAccumSema(), NormalVal);
418   CheckUnsaturatedConversion(Src, getPadUAccumSema(), NormalVal);
419   CheckUnsaturatedConversion(Src, getPadULAccumSema(), NormalVal);
420 
421   // -Accums to Accums
422   CheckUnsaturatedConversion(Src, getSAccumSema(), -NormalVal);
423   CheckUnsaturatedConversion(Src, getAccumSema(), -NormalVal);
424   CheckUnsaturatedConversion(Src, getLAccumSema(), -NormalVal);
425   CheckSaturatedConversionMin(Src, Saturated(getUSAccumSema()), -NormalVal);
426   CheckSaturatedConversionMin(Src, Saturated(getUAccumSema()), -NormalVal);
427   CheckSaturatedConversionMin(Src, Saturated(getULAccumSema()), -NormalVal);
428   CheckSaturatedConversionMin(Src, Saturated(getPadUSAccumSema()), -NormalVal);
429   CheckSaturatedConversionMin(Src, Saturated(getPadUAccumSema()), -NormalVal);
430   CheckSaturatedConversionMin(Src, Saturated(getPadULAccumSema()), -NormalVal);
431 
432   // +Accums to Fracts
433   CheckUnsaturatedConversion(Src, getSFractSema(), HalfVal);
434   CheckUnsaturatedConversion(Src, getFractSema(), HalfVal);
435   CheckUnsaturatedConversion(Src, getLFractSema(), HalfVal);
436   CheckUnsaturatedConversion(Src, getUSFractSema(), HalfVal);
437   CheckUnsaturatedConversion(Src, getUFractSema(), HalfVal);
438   CheckUnsaturatedConversion(Src, getULFractSema(), HalfVal);
439   CheckUnsaturatedConversion(Src, getPadUSFractSema(), HalfVal);
440   CheckUnsaturatedConversion(Src, getPadUFractSema(), HalfVal);
441   CheckUnsaturatedConversion(Src, getPadULFractSema(), HalfVal);
442 
443   // -Accums to Fracts
444   CheckUnsaturatedConversion(Src, getSFractSema(), -HalfVal);
445   CheckUnsaturatedConversion(Src, getFractSema(), -HalfVal);
446   CheckUnsaturatedConversion(Src, getLFractSema(), -HalfVal);
447   CheckSaturatedConversionMin(Src, Saturated(getUSFractSema()), -HalfVal);
448   CheckSaturatedConversionMin(Src, Saturated(getUFractSema()), -HalfVal);
449   CheckSaturatedConversionMin(Src, Saturated(getULFractSema()), -HalfVal);
450   CheckSaturatedConversionMin(Src, Saturated(getPadUSFractSema()), -HalfVal);
451   CheckSaturatedConversionMin(Src, Saturated(getPadUFractSema()), -HalfVal);
452   CheckSaturatedConversionMin(Src, Saturated(getPadULFractSema()), -HalfVal);
453 
454   // 0 to Accums
455   CheckUnsaturatedConversion(Src, getSAccumSema(), 0);
456   CheckUnsaturatedConversion(Src, getAccumSema(), 0);
457   CheckUnsaturatedConversion(Src, getLAccumSema(), 0);
458   CheckUnsaturatedConversion(Src, getUSAccumSema(), 0);
459   CheckUnsaturatedConversion(Src, getUAccumSema(), 0);
460   CheckUnsaturatedConversion(Src, getULAccumSema(), 0);
461   CheckUnsaturatedConversion(Src, getPadUSAccumSema(), 0);
462   CheckUnsaturatedConversion(Src, getPadUAccumSema(), 0);
463   CheckUnsaturatedConversion(Src, getPadULAccumSema(), 0);
464 
465   // 0 to Fracts
466   CheckUnsaturatedConversion(Src, getSFractSema(), 0);
467   CheckUnsaturatedConversion(Src, getFractSema(), 0);
468   CheckUnsaturatedConversion(Src, getLFractSema(), 0);
469   CheckUnsaturatedConversion(Src, getUSFractSema(), 0);
470   CheckUnsaturatedConversion(Src, getUFractSema(), 0);
471   CheckUnsaturatedConversion(Src, getULFractSema(), 0);
472   CheckUnsaturatedConversion(Src, getPadUSFractSema(), 0);
473   CheckUnsaturatedConversion(Src, getPadUFractSema(), 0);
474   CheckUnsaturatedConversion(Src, getPadULFractSema(), 0);
475 }
476 
477 // Check one unsigned _Accum sema converted to other sema for different
478 // values.
CheckUnsignedAccumConversionsAgainstOthers(FixedPointSemantics Src,int64_t OneVal)479 void CheckUnsignedAccumConversionsAgainstOthers(FixedPointSemantics Src,
480                                                 int64_t OneVal) {
481   int64_t NormalVal = (OneVal * 2) + (OneVal / 2); // 2.5
482   int64_t HalfVal = (OneVal / 2);                  // 0.5
483 
484   // +UAccums to Accums
485   CheckUnsaturatedConversion(Src, getSAccumSema(), NormalVal);
486   CheckUnsaturatedConversion(Src, getAccumSema(), NormalVal);
487   CheckUnsaturatedConversion(Src, getLAccumSema(), NormalVal);
488   CheckUnsaturatedConversion(Src, getUSAccumSema(), NormalVal);
489   CheckUnsaturatedConversion(Src, getUAccumSema(), NormalVal);
490   CheckUnsaturatedConversion(Src, getULAccumSema(), NormalVal);
491   CheckUnsaturatedConversion(Src, getPadUSAccumSema(), NormalVal);
492   CheckUnsaturatedConversion(Src, getPadUAccumSema(), NormalVal);
493   CheckUnsaturatedConversion(Src, getPadULAccumSema(), NormalVal);
494 
495   // +UAccums to Fracts
496   CheckUnsaturatedConversion(Src, getSFractSema(), HalfVal);
497   CheckUnsaturatedConversion(Src, getFractSema(), HalfVal);
498   CheckUnsaturatedConversion(Src, getLFractSema(), HalfVal);
499   CheckUnsaturatedConversion(Src, getUSFractSema(), HalfVal);
500   CheckUnsaturatedConversion(Src, getUFractSema(), HalfVal);
501   CheckUnsaturatedConversion(Src, getULFractSema(), HalfVal);
502   CheckUnsaturatedConversion(Src, getPadUSFractSema(), HalfVal);
503   CheckUnsaturatedConversion(Src, getPadUFractSema(), HalfVal);
504   CheckUnsaturatedConversion(Src, getPadULFractSema(), HalfVal);
505 }
506 
TEST(FixedPoint,AccumConversions)507 TEST(FixedPoint, AccumConversions) {
508   // Normal conversions
509   CheckSignedAccumConversionsAgainstOthers(getSAccumSema(), 128);
510   CheckUnsignedAccumConversionsAgainstOthers(getUSAccumSema(), 256);
511   CheckSignedAccumConversionsAgainstOthers(getAccumSema(), 32768);
512   CheckUnsignedAccumConversionsAgainstOthers(getUAccumSema(), 65536);
513   CheckSignedAccumConversionsAgainstOthers(getLAccumSema(), 2147483648);
514   CheckUnsignedAccumConversionsAgainstOthers(getULAccumSema(), 4294967296);
515 
516   CheckUnsignedAccumConversionsAgainstOthers(getPadUSAccumSema(), 128);
517   CheckUnsignedAccumConversionsAgainstOthers(getPadUAccumSema(), 32768);
518   CheckUnsignedAccumConversionsAgainstOthers(getPadULAccumSema(), 2147483648);
519 }
520 
TEST(FixedPoint,AccumConversionOverflow)521 TEST(FixedPoint, AccumConversionOverflow) {
522   // To SAccum max limit (65536)
523   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getAccumSema()),
524                               140737488355328);
525   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getUAccumSema()),
526                               140737488355328);
527   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getPadUAccumSema()),
528                               140737488355328);
529   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getAccumSema()),
530                               281474976710656);
531   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getUAccumSema()),
532                               281474976710656);
533   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getPadUAccumSema()),
534                               281474976710656);
535 
536   CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getAccumSema()),
537                               140737488355328);
538   CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getUAccumSema()),
539                               140737488355328);
540   CheckSaturatedConversionMax(getPadULAccumSema(),
541                               Saturated(getPadUAccumSema()), 140737488355328);
542 
543   // To SAccum min limit (-65536)
544   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getAccumSema()),
545                               -140737488355328);
546   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getUAccumSema()),
547                               -140737488355328);
548   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getPadUAccumSema()),
549                               -140737488355328);
550 }
551 
TEST(FixedPoint,SAccumConversionOverflow)552 TEST(FixedPoint, SAccumConversionOverflow) {
553   // To SAccum max limit (256)
554   CheckSaturatedConversionMax(getAccumSema(), Saturated(getSAccumSema()),
555                               8388608);
556   CheckSaturatedConversionMax(getAccumSema(), Saturated(getUSAccumSema()),
557                               8388608);
558   CheckSaturatedConversionMax(getAccumSema(), Saturated(getPadUSAccumSema()),
559                               8388608);
560   CheckSaturatedConversionMax(getUAccumSema(), Saturated(getSAccumSema()),
561                               16777216);
562   CheckSaturatedConversionMax(getUAccumSema(), Saturated(getUSAccumSema()),
563                               16777216);
564   CheckSaturatedConversionMax(getUAccumSema(), Saturated(getPadUSAccumSema()),
565                               16777216);
566   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getSAccumSema()),
567                               549755813888);
568   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getUSAccumSema()),
569                               549755813888);
570   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getPadUSAccumSema()),
571                               549755813888);
572   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getSAccumSema()),
573                               1099511627776);
574   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getUSAccumSema()),
575                               1099511627776);
576   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getPadUSAccumSema()),
577                               1099511627776);
578 
579   CheckSaturatedConversionMax(getPadUAccumSema(), Saturated(getSAccumSema()),
580                               8388608);
581   CheckSaturatedConversionMax(getPadUAccumSema(), Saturated(getUSAccumSema()),
582                               8388608);
583   CheckSaturatedConversionMax(getPadUAccumSema(),
584                               Saturated(getPadUSAccumSema()), 8388608);
585   CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getSAccumSema()),
586                               549755813888);
587   CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getUSAccumSema()),
588                               549755813888);
589   CheckSaturatedConversionMax(getPadULAccumSema(),
590                               Saturated(getPadUSAccumSema()), 549755813888);
591 
592   // To SAccum min limit (-256)
593   CheckSaturatedConversionMin(getAccumSema(), Saturated(getSAccumSema()),
594                               -8388608);
595   CheckSaturatedConversionMin(getAccumSema(), Saturated(getUSAccumSema()),
596                               -8388608);
597   CheckSaturatedConversionMin(getAccumSema(), Saturated(getPadUSAccumSema()),
598                               -8388608);
599   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getSAccumSema()),
600                               -549755813888);
601   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getUSAccumSema()),
602                               -549755813888);
603   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getPadUSAccumSema()),
604                               -549755813888);
605 }
606 
TEST(FixedPoint,GetValueSignAfterConversion)607 TEST(FixedPoint, GetValueSignAfterConversion) {
608   APFixedPoint Fixed(255 << 7, getSAccumSema());
609   ASSERT_TRUE(Fixed.getValue().isSigned());
610   APFixedPoint UFixed = Fixed.convert(getUSAccumSema());
611   ASSERT_TRUE(UFixed.getValue().isUnsigned());
612   ASSERT_EQ(UFixed.getValue(), APSInt::getUnsigned(255 << 8).extOrTrunc(16));
613 }
614 
TEST(FixedPoint,ModularWrapAround)615 TEST(FixedPoint, ModularWrapAround) {
616   // Positive to negative
617   APFixedPoint Val = APFixedPoint(1ULL << 7, getSAccumSema());
618   ASSERT_EQ(Val.convert(getLFractSema()).getValue(), -(1ULL << 31));
619 
620   Val = APFixedPoint(1ULL << 23, getAccumSema());
621   ASSERT_EQ(Val.convert(getSAccumSema()).getValue(), -(1ULL << 15));
622 
623   Val = APFixedPoint(1ULL << 47, getLAccumSema());
624   ASSERT_EQ(Val.convert(getAccumSema()).getValue(), -(1ULL << 31));
625 
626   // Negative to positive
627   Val = APFixedPoint(/*-1.5*/ -192, getSAccumSema());
628   ASSERT_EQ(Val.convert(getLFractSema()).getValue(), 1ULL << 30);
629 
630   Val = APFixedPoint(-(257 << 15), getAccumSema());
631   ASSERT_EQ(Val.convert(getSAccumSema()).getValue(), 255 << 7);
632 
633   Val = APFixedPoint(-(65537ULL << 31), getLAccumSema());
634   ASSERT_EQ(Val.convert(getAccumSema()).getValue(), 65535 << 15);
635 
636   // Signed to unsigned
637   Val = APFixedPoint(-(1 << 7), getSAccumSema());
638   ASSERT_EQ(Val.convert(getUSAccumSema()).getValue(), 255 << 8);
639 
640   Val = APFixedPoint(-(1 << 15), getAccumSema());
641   ASSERT_EQ(Val.convert(getUAccumSema()).getValue(), 65535ULL << 16);
642 
643   Val = APFixedPoint(-(1ULL << 31), getLAccumSema());
644   ASSERT_EQ(Val.convert(getULAccumSema()).getValue().getZExtValue(),
645             4294967295ULL << 32);
646 }
647 
648 enum OvfKind { MinSat, MaxSat };
649 
CheckFloatToFixedConversion(APFloat & Val,const FixedPointSemantics & Sema,int64_t ExpectedNonSat)650 void CheckFloatToFixedConversion(APFloat &Val, const FixedPointSemantics &Sema,
651                                  int64_t ExpectedNonSat) {
652   bool Ovf;
653   ASSERT_EQ(APFixedPoint::getFromFloatValue(Val, Sema, &Ovf).getValue(),
654             ExpectedNonSat);
655   ASSERT_EQ(Ovf, false);
656   ASSERT_EQ(
657       APFixedPoint::getFromFloatValue(Val, Saturated(Sema), &Ovf).getValue(),
658       ExpectedNonSat);
659   ASSERT_EQ(Ovf, false);
660 }
661 
CheckFloatToFixedConversion(APFloat & Val,const FixedPointSemantics & Sema,OvfKind ExpectedOvf)662 void CheckFloatToFixedConversion(APFloat &Val, const FixedPointSemantics &Sema,
663                                  OvfKind ExpectedOvf) {
664   bool Ovf;
665   (void)APFixedPoint::getFromFloatValue(Val, Sema, &Ovf);
666   ASSERT_EQ(Ovf, true);
667   ASSERT_EQ(
668       APFixedPoint::getFromFloatValue(Val, Saturated(Sema), &Ovf).getValue(),
669       (ExpectedOvf == MinSat ? APFixedPoint::getMin(Sema)
670                              : APFixedPoint::getMax(Sema))
671           .getValue());
672   ASSERT_EQ(Ovf, false);
673 }
674 
TEST(FixedPoint,FloatToFixed)675 TEST(FixedPoint, FloatToFixed) {
676   APFloat Val(0.0f);
677 
678   // Simple exact fraction
679   Val = APFloat(0.75f);
680   CheckFloatToFixedConversion(Val, getSAccumSema(), 3ULL << 5);
681   CheckFloatToFixedConversion(Val, getAccumSema(),  3ULL << 13);
682   CheckFloatToFixedConversion(Val, getLAccumSema(), 3ULL << 29);
683 
684   CheckFloatToFixedConversion(Val, getUSAccumSema(), 3ULL << 6);
685   CheckFloatToFixedConversion(Val, getUAccumSema(),  3ULL << 14);
686   CheckFloatToFixedConversion(Val, getULAccumSema(), 3ULL << 30);
687 
688   CheckFloatToFixedConversion(Val, getSFractSema(), 3ULL << 5);
689   CheckFloatToFixedConversion(Val, getFractSema(),  3ULL << 13);
690   CheckFloatToFixedConversion(Val, getLFractSema(), 3ULL << 29);
691 
692   CheckFloatToFixedConversion(Val, getUSFractSema(), 3ULL << 6);
693   CheckFloatToFixedConversion(Val, getUFractSema(),  3ULL << 14);
694   CheckFloatToFixedConversion(Val, getULFractSema(), 3ULL << 30);
695 
696   // Simple negative exact fraction
697   Val = APFloat(-0.75f);
698   CheckFloatToFixedConversion(Val, getSAccumSema(), -3ULL << 5);
699   CheckFloatToFixedConversion(Val, getAccumSema(),  -3ULL << 13);
700   CheckFloatToFixedConversion(Val, getLAccumSema(), -3ULL << 29);
701 
702   CheckFloatToFixedConversion(Val, getUSAccumSema(), MinSat);
703   CheckFloatToFixedConversion(Val, getUAccumSema(),  MinSat);
704   CheckFloatToFixedConversion(Val, getULAccumSema(), MinSat);
705 
706   CheckFloatToFixedConversion(Val, getSFractSema(), -3ULL << 5);
707   CheckFloatToFixedConversion(Val, getFractSema(),  -3ULL << 13);
708   CheckFloatToFixedConversion(Val, getLFractSema(), -3ULL << 29);
709 
710   CheckFloatToFixedConversion(Val, getUSFractSema(), MinSat);
711   CheckFloatToFixedConversion(Val, getUFractSema(),  MinSat);
712   CheckFloatToFixedConversion(Val, getULFractSema(), MinSat);
713 
714   // Highly precise fraction
715   Val = APFloat(0.999999940395355224609375f);
716   CheckFloatToFixedConversion(Val, getSAccumSema(), 0x7FULL);
717   CheckFloatToFixedConversion(Val, getAccumSema(),  0x7FFFULL);
718   CheckFloatToFixedConversion(Val, getLAccumSema(), 0xFFFFFFULL << 7);
719 
720   CheckFloatToFixedConversion(Val, getUSAccumSema(), 0xFFULL);
721   CheckFloatToFixedConversion(Val, getUAccumSema(),  0xFFFFULL);
722   CheckFloatToFixedConversion(Val, getULAccumSema(), 0xFFFFFFULL << 8);
723 
724   CheckFloatToFixedConversion(Val, getSFractSema(), 0x7FULL);
725   CheckFloatToFixedConversion(Val, getFractSema(),  0x7FFFULL);
726   CheckFloatToFixedConversion(Val, getLFractSema(), 0xFFFFFFULL << 7);
727 
728   CheckFloatToFixedConversion(Val, getUSFractSema(), 0xFFULL);
729   CheckFloatToFixedConversion(Val, getUFractSema(),  0xFFFFULL);
730   CheckFloatToFixedConversion(Val, getULFractSema(), 0xFFFFFFULL << 8);
731 
732   // Integral and fraction
733   Val = APFloat(17.99609375f);
734   CheckFloatToFixedConversion(Val, getSAccumSema(), 0x11FFULL >> 1);
735   CheckFloatToFixedConversion(Val, getAccumSema(),  0x11FFULL << 7);
736   CheckFloatToFixedConversion(Val, getLAccumSema(), 0x11FFULL << 23);
737 
738   CheckFloatToFixedConversion(Val, getUSAccumSema(), 0x11FFULL);
739   CheckFloatToFixedConversion(Val, getUAccumSema(),  0x11FFULL << 8);
740   CheckFloatToFixedConversion(Val, getULAccumSema(), 0x11FFULL << 24);
741 
742   CheckFloatToFixedConversion(Val, getSFractSema(), MaxSat);
743   CheckFloatToFixedConversion(Val, getFractSema(),  MaxSat);
744   CheckFloatToFixedConversion(Val, getLFractSema(), MaxSat);
745 
746   CheckFloatToFixedConversion(Val, getUSFractSema(), MaxSat);
747   CheckFloatToFixedConversion(Val, getUFractSema(),  MaxSat);
748   CheckFloatToFixedConversion(Val, getULFractSema(), MaxSat);
749 
750   // Negative integral and fraction
751   Val = APFloat(-17.99609375f);
752   CheckFloatToFixedConversion(Val, getSAccumSema(), -0x11FELL >> 1);
753   CheckFloatToFixedConversion(Val, getAccumSema(),  -0x11FFULL << 7);
754   CheckFloatToFixedConversion(Val, getLAccumSema(), -0x11FFULL << 23);
755 
756   CheckFloatToFixedConversion(Val, getUSAccumSema(), MinSat);
757   CheckFloatToFixedConversion(Val, getUAccumSema(),  MinSat);
758   CheckFloatToFixedConversion(Val, getULAccumSema(), MinSat);
759 
760   CheckFloatToFixedConversion(Val, getSFractSema(), MinSat);
761   CheckFloatToFixedConversion(Val, getFractSema(),  MinSat);
762   CheckFloatToFixedConversion(Val, getLFractSema(), MinSat);
763 
764   CheckFloatToFixedConversion(Val, getUSFractSema(), MinSat);
765   CheckFloatToFixedConversion(Val, getUFractSema(),  MinSat);
766   CheckFloatToFixedConversion(Val, getULFractSema(), MinSat);
767 
768   // Very large value
769   Val = APFloat(1.0e38f);
770   CheckFloatToFixedConversion(Val, getSAccumSema(), MaxSat);
771   CheckFloatToFixedConversion(Val, getAccumSema(),  MaxSat);
772   CheckFloatToFixedConversion(Val, getLAccumSema(), MaxSat);
773 
774   CheckFloatToFixedConversion(Val, getUSAccumSema(), MaxSat);
775   CheckFloatToFixedConversion(Val, getUAccumSema(),  MaxSat);
776   CheckFloatToFixedConversion(Val, getULAccumSema(), MaxSat);
777 
778   CheckFloatToFixedConversion(Val, getSFractSema(), MaxSat);
779   CheckFloatToFixedConversion(Val, getFractSema(),  MaxSat);
780   CheckFloatToFixedConversion(Val, getLFractSema(), MaxSat);
781 
782   CheckFloatToFixedConversion(Val, getUSFractSema(), MaxSat);
783   CheckFloatToFixedConversion(Val, getUFractSema(),  MaxSat);
784   CheckFloatToFixedConversion(Val, getULFractSema(), MaxSat);
785 
786   // Very small value
787   Val = APFloat(1.0e-38f);
788   CheckFloatToFixedConversion(Val, getSAccumSema(), 0);
789   CheckFloatToFixedConversion(Val, getAccumSema(),  0);
790   CheckFloatToFixedConversion(Val, getLAccumSema(), 0);
791 
792   CheckFloatToFixedConversion(Val, getUSAccumSema(), 0);
793   CheckFloatToFixedConversion(Val, getUAccumSema(),  0);
794   CheckFloatToFixedConversion(Val, getULAccumSema(), 0);
795 
796   CheckFloatToFixedConversion(Val, getSFractSema(), 0);
797   CheckFloatToFixedConversion(Val, getFractSema(),  0);
798   CheckFloatToFixedConversion(Val, getLFractSema(), 0);
799 
800   CheckFloatToFixedConversion(Val, getUSFractSema(), 0);
801   CheckFloatToFixedConversion(Val, getUFractSema(),  0);
802   CheckFloatToFixedConversion(Val, getULFractSema(), 0);
803 
804   // Half conversion
805   Val = APFloat(0.99951171875f);
806   bool Ignored;
807   Val.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
808 
809   CheckFloatToFixedConversion(Val, getSAccumSema(), 0x7FULL);
810   CheckFloatToFixedConversion(Val, getAccumSema(),  0x7FFULL << 4);
811   CheckFloatToFixedConversion(Val, getLAccumSema(), 0x7FFULL << 20);
812 
813   CheckFloatToFixedConversion(Val, getUSAccumSema(), 0xFFULL);
814   CheckFloatToFixedConversion(Val, getUAccumSema(),  0xFFEULL << 4);
815   CheckFloatToFixedConversion(Val, getULAccumSema(), 0xFFEULL << 20);
816 
817   CheckFloatToFixedConversion(Val, getSFractSema(), 0x7FULL);
818   CheckFloatToFixedConversion(Val, getFractSema(),  0x7FFULL << 4);
819   CheckFloatToFixedConversion(Val, getLFractSema(), 0x7FFULL << 20);
820 
821   CheckFloatToFixedConversion(Val, getUSFractSema(), 0xFFULL);
822   CheckFloatToFixedConversion(Val, getUFractSema(),  0xFFEULL << 4);
823   CheckFloatToFixedConversion(Val, getULFractSema(), 0xFFEULL << 20);
824 }
825 
CheckFixedToFloatConversion(int64_t Val,const FixedPointSemantics & Sema,float Result)826 void CheckFixedToFloatConversion(int64_t Val, const FixedPointSemantics &Sema,
827                                  float Result) {
828   APFixedPoint FXVal(Val, Sema);
829   APFloat APRes(Result);
830   ASSERT_EQ(FXVal.convertToFloat(APFloat::IEEEsingle()), APRes);
831 }
832 
CheckFixedToHalfConversion(int64_t Val,const FixedPointSemantics & Sema,float Result)833 void CheckFixedToHalfConversion(int64_t Val, const FixedPointSemantics &Sema,
834                                 float Result) {
835   APFixedPoint FXVal(Val, Sema);
836   APFloat APRes(Result);
837   bool Ignored;
838   APRes.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
839   ASSERT_EQ(FXVal.convertToFloat(APFloat::IEEEhalf()), APRes);
840 }
841 
TEST(FixedPoint,FixedToFloat)842 TEST(FixedPoint, FixedToFloat) {
843   int64_t Val = 0x1ULL;
844   CheckFixedToFloatConversion(Val, getSAccumSema(), 0.0078125f);
845   CheckFixedToFloatConversion(Val, getFractSema(),  0.000030517578125f);
846   CheckFixedToFloatConversion(Val, getAccumSema(),  0.000030517578125f);
847   CheckFixedToFloatConversion(Val, getLFractSema(),
848                               0.0000000004656612873077392578125f);
849 
850   CheckFixedToFloatConversion(Val, getUSAccumSema(), 0.00390625f);
851   CheckFixedToFloatConversion(Val, getUFractSema(),  0.0000152587890625f);
852   CheckFixedToFloatConversion(Val, getUAccumSema(),  0.0000152587890625f);
853   CheckFixedToFloatConversion(Val, getULFractSema(),
854                               0.00000000023283064365386962890625f);
855 
856   Val = 0x7FULL;
857   CheckFixedToFloatConversion(Val, getSAccumSema(), 0.9921875f);
858   CheckFixedToFloatConversion(Val, getFractSema(),  0.003875732421875f);
859   CheckFixedToFloatConversion(Val, getAccumSema(),  0.003875732421875f);
860   CheckFixedToFloatConversion(Val, getLFractSema(),
861                               0.0000000591389834880828857421875f);
862 
863   CheckFixedToFloatConversion(Val, getUSAccumSema(), 0.49609375f);
864   CheckFixedToFloatConversion(Val, getUFractSema(),  0.0019378662109375f);
865   CheckFixedToFloatConversion(Val, getUAccumSema(),  0.0019378662109375f);
866   CheckFixedToFloatConversion(Val, getULFractSema(),
867                               0.00000002956949174404144287109375f);
868 
869   Val = -0x1ULL;
870   CheckFixedToFloatConversion(Val, getSAccumSema(), -0.0078125f);
871   CheckFixedToFloatConversion(Val, getFractSema(),  -0.000030517578125f);
872   CheckFixedToFloatConversion(Val, getAccumSema(),  -0.000030517578125f);
873   CheckFixedToFloatConversion(Val, getLFractSema(),
874                               -0.0000000004656612873077392578125f);
875 
876 
877   CheckFixedToFloatConversion(-0x80ULL,       getSAccumSema(), -1.0f);
878   CheckFixedToFloatConversion(-0x8000ULL,     getFractSema(),  -1.0f);
879   CheckFixedToFloatConversion(-0x8000ULL,     getAccumSema(),  -1.0f);
880   CheckFixedToFloatConversion(-0x80000000ULL, getLFractSema(), -1.0f);
881 
882   Val = 0xAFAULL;
883   CheckFixedToFloatConversion(Val, getSAccumSema(), 21.953125f);
884   CheckFixedToFloatConversion(Val, getFractSema(),  0.08575439453125f);
885   CheckFixedToFloatConversion(Val, getAccumSema(),  0.08575439453125f);
886   CheckFixedToFloatConversion(Val, getLFractSema(),
887                               0.000001308508217334747314453125f);
888 
889   CheckFixedToFloatConversion(Val, getUSAccumSema(), 10.9765625f);
890   CheckFixedToFloatConversion(Val, getUFractSema(),  0.042877197265625f);
891   CheckFixedToFloatConversion(Val, getUAccumSema(),  0.042877197265625f);
892   CheckFixedToFloatConversion(Val, getULFractSema(),
893                               0.0000006542541086673736572265625f);
894 
895   Val = -0xAFAULL;
896   CheckFixedToFloatConversion(Val, getSAccumSema(), -21.953125f);
897   CheckFixedToFloatConversion(Val, getFractSema(),  -0.08575439453125f);
898   CheckFixedToFloatConversion(Val, getAccumSema(),  -0.08575439453125f);
899   CheckFixedToFloatConversion(Val, getLFractSema(),
900                               -0.000001308508217334747314453125f);
901 
902   Val = 0x40000080ULL;
903   CheckFixedToFloatConversion(Val, getAccumSema(),  32768.00390625f);
904   CheckFixedToFloatConversion(Val, getLFractSema(),
905                               0.500000059604644775390625f);
906 
907   CheckFixedToFloatConversion(Val, getUAccumSema(),  16384.001953125f);
908   CheckFixedToFloatConversion(Val, getULFractSema(),
909                               0.2500000298023223876953125f);
910 
911   Val = 0x40000040ULL;
912   CheckFixedToFloatConversion(Val, getAccumSema(),  32768.0f);
913   CheckFixedToFloatConversion(Val, getLFractSema(), 0.5f);
914 
915   CheckFixedToFloatConversion(Val, getUAccumSema(),  16384.0f);
916   CheckFixedToFloatConversion(Val, getULFractSema(), 0.25f);
917 
918   Val = 0x7FF0ULL;
919   CheckFixedToHalfConversion(Val, getAccumSema(), 0.99951171875f);
920   CheckFixedToHalfConversion(Val, getLFractSema(), 0.000015251338481903076171875f);
921 
922   CheckFixedToHalfConversion(Val, getUAccumSema(), 0.499755859375f);
923   CheckFixedToHalfConversion(Val, getULFractSema(), 0.0000076256692409515380859375f);
924 }
925 
926 } // namespace
927