]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - unittests/Basic/FixedPointTest.cpp
Vendor import of clang trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / unittests / Basic / FixedPointTest.cpp
1 //===- unittests/Basic/FixedPointTest.cpp -- fixed point number tests -----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "clang/Basic/FixedPoint.h"
11 #include "llvm/ADT/APSInt.h"
12 #include "gtest/gtest.h"
13
14 using clang::APFixedPoint;
15 using clang::FixedPointSemantics;
16 using llvm::APInt;
17 using llvm::APSInt;
18
19 namespace {
20
21 FixedPointSemantics Saturated(FixedPointSemantics Sema) {
22   Sema.setSaturated(true);
23   return Sema;
24 }
25
26 FixedPointSemantics getSAccumSema() {
27   return FixedPointSemantics(/*width=*/16, /*scale=*/7, /*isSigned=*/true,
28                              /*isSaturated=*/false,
29                              /*hasUnsignedPadding=*/false);
30 }
31
32 FixedPointSemantics getAccumSema() {
33   return FixedPointSemantics(/*width=*/32, /*scale=*/15, /*isSigned=*/true,
34                              /*isSaturated=*/false,
35                              /*hasUnsignedPadding=*/false);
36 }
37
38 FixedPointSemantics getLAccumSema() {
39   return FixedPointSemantics(/*width=*/64, /*scale=*/31, /*isSigned=*/true,
40                              /*isSaturated=*/false,
41                              /*hasUnsignedPadding=*/false);
42 }
43
44 FixedPointSemantics getSFractSema() {
45   return FixedPointSemantics(/*width=*/8, /*scale=*/7, /*isSigned=*/true,
46                              /*isSaturated=*/false,
47                              /*hasUnsignedPadding=*/false);
48 }
49
50 FixedPointSemantics getFractSema() {
51   return FixedPointSemantics(/*width=*/16, /*scale=*/15, /*isSigned=*/true,
52                              /*isSaturated=*/false,
53                              /*hasUnsignedPadding=*/false);
54 }
55
56 FixedPointSemantics getLFractSema() {
57   return FixedPointSemantics(/*width=*/32, /*scale=*/31, /*isSigned=*/true,
58                              /*isSaturated=*/false,
59                              /*hasUnsignedPadding=*/false);
60 }
61
62 FixedPointSemantics getUSAccumSema() {
63   return FixedPointSemantics(/*width=*/16, /*scale=*/8, /*isSigned=*/false,
64                              /*isSaturated=*/false,
65                              /*hasUnsignedPadding=*/false);
66 }
67
68 FixedPointSemantics getUAccumSema() {
69   return FixedPointSemantics(/*width=*/32, /*scale=*/16, /*isSigned=*/false,
70                              /*isSaturated=*/false,
71                              /*hasUnsignedPadding=*/false);
72 }
73
74 FixedPointSemantics getULAccumSema() {
75   return FixedPointSemantics(/*width=*/64, /*scale=*/32, /*isSigned=*/false,
76                              /*isSaturated=*/false,
77                              /*hasUnsignedPadding=*/false);
78 }
79
80 FixedPointSemantics getUSFractSema() {
81   return FixedPointSemantics(/*width=*/8, /*scale=*/8, /*isSigned=*/false,
82                              /*isSaturated=*/false,
83                              /*hasUnsignedPadding=*/false);
84 }
85
86 FixedPointSemantics getUFractSema() {
87   return FixedPointSemantics(/*width=*/16, /*scale=*/16, /*isSigned=*/false,
88                              /*isSaturated=*/false,
89                              /*hasUnsignedPadding=*/false);
90 }
91
92 FixedPointSemantics getULFractSema() {
93   return FixedPointSemantics(/*width=*/32, /*scale=*/32, /*isSigned=*/false,
94                              /*isSaturated=*/false,
95                              /*hasUnsignedPadding=*/false);
96 }
97
98 FixedPointSemantics getPadUSAccumSema() {
99   return FixedPointSemantics(/*width=*/16, /*scale=*/7, /*isSigned=*/false,
100                              /*isSaturated=*/false,
101                              /*hasUnsignedPadding=*/true);
102 }
103
104 FixedPointSemantics getPadUAccumSema() {
105   return FixedPointSemantics(/*width=*/32, /*scale=*/15, /*isSigned=*/false,
106                              /*isSaturated=*/false,
107                              /*hasUnsignedPadding=*/true);
108 }
109
110 FixedPointSemantics getPadULAccumSema() {
111   return FixedPointSemantics(/*width=*/64, /*scale=*/31, /*isSigned=*/false,
112                              /*isSaturated=*/false,
113                              /*hasUnsignedPadding=*/true);
114 }
115
116 FixedPointSemantics getPadUSFractSema() {
117   return FixedPointSemantics(/*width=*/8, /*scale=*/7, /*isSigned=*/false,
118                              /*isSaturated=*/false,
119                              /*hasUnsignedPadding=*/true);
120 }
121
122 FixedPointSemantics getPadUFractSema() {
123   return FixedPointSemantics(/*width=*/16, /*scale=*/15, /*isSigned=*/false,
124                              /*isSaturated=*/false,
125                              /*hasUnsignedPadding=*/true);
126 }
127
128 FixedPointSemantics getPadULFractSema() {
129   return FixedPointSemantics(/*width=*/32, /*scale=*/31, /*isSigned=*/false,
130                              /*isSaturated=*/false,
131                              /*hasUnsignedPadding=*/true);
132 }
133
134 void CheckUnpaddedMax(const FixedPointSemantics &Sema) {
135   ASSERT_EQ(APFixedPoint::getMax(Sema).getValue(),
136             APSInt::getMaxValue(Sema.getWidth(), !Sema.isSigned()));
137 }
138
139 void CheckPaddedMax(const FixedPointSemantics &Sema) {
140   ASSERT_EQ(APFixedPoint::getMax(Sema).getValue(),
141             APSInt::getMaxValue(Sema.getWidth(), !Sema.isSigned()) >> 1);
142 }
143
144 void CheckMin(const FixedPointSemantics &Sema) {
145   ASSERT_EQ(APFixedPoint::getMin(Sema).getValue(),
146             APSInt::getMinValue(Sema.getWidth(), !Sema.isSigned()));
147 }
148
149 TEST(FixedPointTest, getMax) {
150   CheckUnpaddedMax(getSAccumSema());
151   CheckUnpaddedMax(getAccumSema());
152   CheckUnpaddedMax(getLAccumSema());
153   CheckUnpaddedMax(getUSAccumSema());
154   CheckUnpaddedMax(getUAccumSema());
155   CheckUnpaddedMax(getULAccumSema());
156   CheckUnpaddedMax(getSFractSema());
157   CheckUnpaddedMax(getFractSema());
158   CheckUnpaddedMax(getLFractSema());
159   CheckUnpaddedMax(getUSFractSema());
160   CheckUnpaddedMax(getUFractSema());
161   CheckUnpaddedMax(getULFractSema());
162
163   CheckPaddedMax(getPadUSAccumSema());
164   CheckPaddedMax(getPadUAccumSema());
165   CheckPaddedMax(getPadULAccumSema());
166   CheckPaddedMax(getPadUSFractSema());
167   CheckPaddedMax(getPadUFractSema());
168   CheckPaddedMax(getPadULFractSema());
169 }
170
171 TEST(FixedPointTest, getMin) {
172   CheckMin(getSAccumSema());
173   CheckMin(getAccumSema());
174   CheckMin(getLAccumSema());
175   CheckMin(getUSAccumSema());
176   CheckMin(getUAccumSema());
177   CheckMin(getULAccumSema());
178   CheckMin(getSFractSema());
179   CheckMin(getFractSema());
180   CheckMin(getLFractSema());
181   CheckMin(getUSFractSema());
182   CheckMin(getUFractSema());
183   CheckMin(getULFractSema());
184
185   CheckMin(getPadUSAccumSema());
186   CheckMin(getPadUAccumSema());
187   CheckMin(getPadULAccumSema());
188   CheckMin(getPadUSFractSema());
189   CheckMin(getPadUFractSema());
190   CheckMin(getPadULFractSema());
191 }
192
193 void CheckIntPart(const FixedPointSemantics &Sema, int64_t IntPart) {
194   unsigned Scale = Sema.getScale();
195
196   // Value with a fraction
197   APFixedPoint ValWithFract(APInt(Sema.getWidth(),
198                                   (IntPart << Scale) + (1ULL << (Scale - 1)),
199                                   Sema.isSigned()),
200                             Sema);
201   ASSERT_EQ(ValWithFract.getIntPart(), IntPart);
202
203   // Just fraction
204   APFixedPoint JustFract(
205       APInt(Sema.getWidth(), (1ULL << (Scale - 1)), Sema.isSigned()), Sema);
206   ASSERT_EQ(JustFract.getIntPart(), 0);
207
208   // Whole number
209   APFixedPoint WholeNum(
210       APInt(Sema.getWidth(), (IntPart << Scale), Sema.isSigned()), Sema);
211   ASSERT_EQ(WholeNum.getIntPart(), IntPart);
212
213   // Negative
214   if (Sema.isSigned()) {
215     APFixedPoint Negative(
216         APInt(Sema.getWidth(), (IntPart << Scale), Sema.isSigned()), Sema);
217     ASSERT_EQ(Negative.getIntPart(), IntPart);
218   }
219 }
220
221 void CheckIntPartMin(const FixedPointSemantics &Sema, int64_t Expected) {
222   ASSERT_EQ(APFixedPoint::getMin(Sema).getIntPart(), Expected);
223 }
224
225 void CheckIntPartMax(const FixedPointSemantics &Sema, uint64_t Expected) {
226   ASSERT_EQ(APFixedPoint::getMax(Sema).getIntPart(), Expected);
227 }
228
229 TEST(FixedPoint, getIntPart) {
230   // Normal values
231   CheckIntPart(getSAccumSema(), 2);
232   CheckIntPart(getAccumSema(), 2);
233   CheckIntPart(getLAccumSema(), 2);
234   CheckIntPart(getUSAccumSema(), 2);
235   CheckIntPart(getUAccumSema(), 2);
236   CheckIntPart(getULAccumSema(), 2);
237
238   // Zero
239   CheckIntPart(getSAccumSema(), 0);
240   CheckIntPart(getAccumSema(), 0);
241   CheckIntPart(getLAccumSema(), 0);
242   CheckIntPart(getUSAccumSema(), 0);
243   CheckIntPart(getUAccumSema(), 0);
244   CheckIntPart(getULAccumSema(), 0);
245
246   CheckIntPart(getSFractSema(), 0);
247   CheckIntPart(getFractSema(), 0);
248   CheckIntPart(getLFractSema(), 0);
249   CheckIntPart(getUSFractSema(), 0);
250   CheckIntPart(getUFractSema(), 0);
251   CheckIntPart(getULFractSema(), 0);
252
253   // Min
254   CheckIntPartMin(getSAccumSema(), -256);
255   CheckIntPartMin(getAccumSema(), -65536);
256   CheckIntPartMin(getLAccumSema(), -4294967296);
257
258   CheckIntPartMin(getSFractSema(), -1);
259   CheckIntPartMin(getFractSema(), -1);
260   CheckIntPartMin(getLFractSema(), -1);
261
262   // Max
263   CheckIntPartMax(getSAccumSema(), 255);
264   CheckIntPartMax(getAccumSema(), 65535);
265   CheckIntPartMax(getLAccumSema(), 4294967295);
266   CheckIntPartMax(getUSAccumSema(), 255);
267   CheckIntPartMax(getUAccumSema(), 65535);
268   CheckIntPartMax(getULAccumSema(), 4294967295);
269
270   CheckIntPartMax(getSFractSema(), 0);
271   CheckIntPartMax(getFractSema(), 0);
272   CheckIntPartMax(getLFractSema(), 0);
273   CheckIntPartMax(getUSFractSema(), 0);
274   CheckIntPartMax(getUFractSema(), 0);
275   CheckIntPartMax(getULFractSema(), 0);
276
277   // Padded
278   // Normal Values
279   CheckIntPart(getPadUSAccumSema(), 2);
280   CheckIntPart(getPadUAccumSema(), 2);
281   CheckIntPart(getPadULAccumSema(), 2);
282
283   // Zero
284   CheckIntPart(getPadUSAccumSema(), 0);
285   CheckIntPart(getPadUAccumSema(), 0);
286   CheckIntPart(getPadULAccumSema(), 0);
287
288   CheckIntPart(getPadUSFractSema(), 0);
289   CheckIntPart(getPadUFractSema(), 0);
290   CheckIntPart(getPadULFractSema(), 0);
291
292   // Max
293   CheckIntPartMax(getPadUSAccumSema(), 255);
294   CheckIntPartMax(getPadUAccumSema(), 65535);
295   CheckIntPartMax(getPadULAccumSema(), 4294967295);
296
297   CheckIntPartMax(getPadUSFractSema(), 0);
298   CheckIntPartMax(getPadUFractSema(), 0);
299   CheckIntPartMax(getPadULFractSema(), 0);
300 }
301
302 TEST(FixedPoint, compare) {
303   // Equality
304   // With fractional part (2.5)
305   // Across sizes
306   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
307             APFixedPoint(81920, getAccumSema()));
308   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
309             APFixedPoint(5368709120, getLAccumSema()));
310   ASSERT_EQ(APFixedPoint(0, getSAccumSema()), APFixedPoint(0, getLAccumSema()));
311
312   // Across types (0.5)
313   ASSERT_EQ(APFixedPoint(64, getSAccumSema()),
314             APFixedPoint(64, getSFractSema()));
315   ASSERT_EQ(APFixedPoint(16384, getAccumSema()),
316             APFixedPoint(16384, getFractSema()));
317   ASSERT_EQ(APFixedPoint(1073741824, getLAccumSema()),
318             APFixedPoint(1073741824, getLFractSema()));
319
320   // Across widths and types (0.5)
321   ASSERT_EQ(APFixedPoint(64, getSAccumSema()),
322             APFixedPoint(16384, getFractSema()));
323   ASSERT_EQ(APFixedPoint(64, getSAccumSema()),
324             APFixedPoint(1073741824, getLFractSema()));
325
326   // Across saturation
327   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
328             APFixedPoint(81920, Saturated(getAccumSema())));
329
330   // Across signs
331   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
332             APFixedPoint(640, getUSAccumSema()));
333   ASSERT_EQ(APFixedPoint(-320, getSAccumSema()),
334             APFixedPoint(-81920, getAccumSema()));
335
336   // Across padding
337   ASSERT_EQ(APFixedPoint(320, getSAccumSema()),
338             APFixedPoint(320, getPadUSAccumSema()));
339   ASSERT_EQ(APFixedPoint(640, getUSAccumSema()),
340             APFixedPoint(320, getPadUSAccumSema()));
341
342   // Less than
343   ASSERT_LT(APFixedPoint(-1, getSAccumSema()), APFixedPoint(0, getAccumSema()));
344   ASSERT_LT(APFixedPoint(-1, getSAccumSema()),
345             APFixedPoint(0, getUAccumSema()));
346   ASSERT_LT(APFixedPoint(0, getSAccumSema()), APFixedPoint(1, getAccumSema()));
347   ASSERT_LT(APFixedPoint(0, getSAccumSema()), APFixedPoint(1, getUAccumSema()));
348   ASSERT_LT(APFixedPoint(0, getUSAccumSema()), APFixedPoint(1, getAccumSema()));
349   ASSERT_LT(APFixedPoint(0, getUSAccumSema()),
350             APFixedPoint(1, getUAccumSema()));
351
352   // Greater than
353   ASSERT_GT(APFixedPoint(0, getAccumSema()), APFixedPoint(-1, getSAccumSema()));
354   ASSERT_GT(APFixedPoint(0, getUAccumSema()),
355             APFixedPoint(-1, getSAccumSema()));
356   ASSERT_GT(APFixedPoint(1, getAccumSema()), APFixedPoint(0, getSAccumSema()));
357   ASSERT_GT(APFixedPoint(1, getUAccumSema()), APFixedPoint(0, getSAccumSema()));
358   ASSERT_GT(APFixedPoint(1, getAccumSema()), APFixedPoint(0, getUSAccumSema()));
359   ASSERT_GT(APFixedPoint(1, getUAccumSema()),
360             APFixedPoint(0, getUSAccumSema()));
361 }
362
363 // Check that a fixed point value in one sema is the same in another sema
364 void CheckUnsaturatedConversion(FixedPointSemantics Src,
365                                 FixedPointSemantics Dst, int64_t TestVal) {
366   int64_t ScaledVal = TestVal;
367   bool IsNegative = ScaledVal < 0;
368   if (IsNegative)
369     ScaledVal = -ScaledVal;
370
371   if (Dst.getScale() > Src.getScale()) {
372     ScaledVal <<= (Dst.getScale() - Src.getScale());
373   } else {
374     ScaledVal >>= (Src.getScale() - Dst.getScale());
375   }
376
377   if (IsNegative)
378     ScaledVal = -ScaledVal;
379
380   APFixedPoint Fixed(TestVal, Src);
381   APFixedPoint Expected(ScaledVal, Dst);
382   ASSERT_EQ(Fixed.convert(Dst), Expected);
383 }
384
385 // Check the value in a given fixed point sema overflows to the saturated min
386 // for another sema
387 void CheckSaturatedConversionMin(FixedPointSemantics Src,
388                                  FixedPointSemantics Dst, int64_t TestVal) {
389   APFixedPoint Fixed(TestVal, Src);
390   ASSERT_EQ(Fixed.convert(Dst), APFixedPoint::getMin(Dst));
391 }
392
393 // Check the value in a given fixed point sema overflows to the saturated max
394 // for another sema
395 void CheckSaturatedConversionMax(FixedPointSemantics Src,
396                                  FixedPointSemantics Dst, int64_t TestVal) {
397   APFixedPoint Fixed(TestVal, Src);
398   ASSERT_EQ(Fixed.convert(Dst), APFixedPoint::getMax(Dst));
399 }
400
401 // Check one signed _Accum sema converted to other sema for different values.
402 void CheckSignedAccumConversionsAgainstOthers(FixedPointSemantics Src,
403                                               int64_t OneVal) {
404   int64_t NormalVal = (OneVal * 2) + (OneVal / 2); // 2.5
405   int64_t HalfVal = (OneVal / 2);                  // 0.5
406
407   // +Accums to Accums
408   CheckUnsaturatedConversion(Src, getSAccumSema(), NormalVal);
409   CheckUnsaturatedConversion(Src, getAccumSema(), NormalVal);
410   CheckUnsaturatedConversion(Src, getLAccumSema(), NormalVal);
411   CheckUnsaturatedConversion(Src, getUSAccumSema(), NormalVal);
412   CheckUnsaturatedConversion(Src, getUAccumSema(), NormalVal);
413   CheckUnsaturatedConversion(Src, getULAccumSema(), NormalVal);
414   CheckUnsaturatedConversion(Src, getPadUSAccumSema(), NormalVal);
415   CheckUnsaturatedConversion(Src, getPadUAccumSema(), NormalVal);
416   CheckUnsaturatedConversion(Src, getPadULAccumSema(), NormalVal);
417
418   // -Accums to Accums
419   CheckUnsaturatedConversion(Src, getSAccumSema(), -NormalVal);
420   CheckUnsaturatedConversion(Src, getAccumSema(), -NormalVal);
421   CheckUnsaturatedConversion(Src, getLAccumSema(), -NormalVal);
422   CheckSaturatedConversionMin(Src, Saturated(getUSAccumSema()), -NormalVal);
423   CheckSaturatedConversionMin(Src, Saturated(getUAccumSema()), -NormalVal);
424   CheckSaturatedConversionMin(Src, Saturated(getULAccumSema()), -NormalVal);
425   CheckSaturatedConversionMin(Src, Saturated(getPadUSAccumSema()), -NormalVal);
426   CheckSaturatedConversionMin(Src, Saturated(getPadUAccumSema()), -NormalVal);
427   CheckSaturatedConversionMin(Src, Saturated(getPadULAccumSema()), -NormalVal);
428
429   // +Accums to Fracts
430   CheckUnsaturatedConversion(Src, getSFractSema(), HalfVal);
431   CheckUnsaturatedConversion(Src, getFractSema(), HalfVal);
432   CheckUnsaturatedConversion(Src, getLFractSema(), HalfVal);
433   CheckUnsaturatedConversion(Src, getUSFractSema(), HalfVal);
434   CheckUnsaturatedConversion(Src, getUFractSema(), HalfVal);
435   CheckUnsaturatedConversion(Src, getULFractSema(), HalfVal);
436   CheckUnsaturatedConversion(Src, getPadUSFractSema(), HalfVal);
437   CheckUnsaturatedConversion(Src, getPadUFractSema(), HalfVal);
438   CheckUnsaturatedConversion(Src, getPadULFractSema(), HalfVal);
439
440   // -Accums to Fracts
441   CheckUnsaturatedConversion(Src, getSFractSema(), -HalfVal);
442   CheckUnsaturatedConversion(Src, getFractSema(), -HalfVal);
443   CheckUnsaturatedConversion(Src, getLFractSema(), -HalfVal);
444   CheckSaturatedConversionMin(Src, Saturated(getUSFractSema()), -HalfVal);
445   CheckSaturatedConversionMin(Src, Saturated(getUFractSema()), -HalfVal);
446   CheckSaturatedConversionMin(Src, Saturated(getULFractSema()), -HalfVal);
447   CheckSaturatedConversionMin(Src, Saturated(getPadUSFractSema()), -HalfVal);
448   CheckSaturatedConversionMin(Src, Saturated(getPadUFractSema()), -HalfVal);
449   CheckSaturatedConversionMin(Src, Saturated(getPadULFractSema()), -HalfVal);
450
451   // 0 to Accums
452   CheckUnsaturatedConversion(Src, getSAccumSema(), 0);
453   CheckUnsaturatedConversion(Src, getAccumSema(), 0);
454   CheckUnsaturatedConversion(Src, getLAccumSema(), 0);
455   CheckUnsaturatedConversion(Src, getUSAccumSema(), 0);
456   CheckUnsaturatedConversion(Src, getUAccumSema(), 0);
457   CheckUnsaturatedConversion(Src, getULAccumSema(), 0);
458   CheckUnsaturatedConversion(Src, getPadUSAccumSema(), 0);
459   CheckUnsaturatedConversion(Src, getPadUAccumSema(), 0);
460   CheckUnsaturatedConversion(Src, getPadULAccumSema(), 0);
461
462   // 0 to Fracts
463   CheckUnsaturatedConversion(Src, getSFractSema(), 0);
464   CheckUnsaturatedConversion(Src, getFractSema(), 0);
465   CheckUnsaturatedConversion(Src, getLFractSema(), 0);
466   CheckUnsaturatedConversion(Src, getUSFractSema(), 0);
467   CheckUnsaturatedConversion(Src, getUFractSema(), 0);
468   CheckUnsaturatedConversion(Src, getULFractSema(), 0);
469   CheckUnsaturatedConversion(Src, getPadUSFractSema(), 0);
470   CheckUnsaturatedConversion(Src, getPadUFractSema(), 0);
471   CheckUnsaturatedConversion(Src, getPadULFractSema(), 0);
472 }
473
474 // Check one unsigned _Accum sema converted to other sema for different
475 // values.
476 void CheckUnsignedAccumConversionsAgainstOthers(FixedPointSemantics Src,
477                                                 int64_t OneVal) {
478   int64_t NormalVal = (OneVal * 2) + (OneVal / 2); // 2.5
479   int64_t HalfVal = (OneVal / 2);                  // 0.5
480
481   // +UAccums to Accums
482   CheckUnsaturatedConversion(Src, getSAccumSema(), NormalVal);
483   CheckUnsaturatedConversion(Src, getAccumSema(), NormalVal);
484   CheckUnsaturatedConversion(Src, getLAccumSema(), NormalVal);
485   CheckUnsaturatedConversion(Src, getUSAccumSema(), NormalVal);
486   CheckUnsaturatedConversion(Src, getUAccumSema(), NormalVal);
487   CheckUnsaturatedConversion(Src, getULAccumSema(), NormalVal);
488   CheckUnsaturatedConversion(Src, getPadUSAccumSema(), NormalVal);
489   CheckUnsaturatedConversion(Src, getPadUAccumSema(), NormalVal);
490   CheckUnsaturatedConversion(Src, getPadULAccumSema(), NormalVal);
491
492   // +UAccums to Fracts
493   CheckUnsaturatedConversion(Src, getSFractSema(), HalfVal);
494   CheckUnsaturatedConversion(Src, getFractSema(), HalfVal);
495   CheckUnsaturatedConversion(Src, getLFractSema(), HalfVal);
496   CheckUnsaturatedConversion(Src, getUSFractSema(), HalfVal);
497   CheckUnsaturatedConversion(Src, getUFractSema(), HalfVal);
498   CheckUnsaturatedConversion(Src, getULFractSema(), HalfVal);
499   CheckUnsaturatedConversion(Src, getPadUSFractSema(), HalfVal);
500   CheckUnsaturatedConversion(Src, getPadUFractSema(), HalfVal);
501   CheckUnsaturatedConversion(Src, getPadULFractSema(), HalfVal);
502 }
503
504 TEST(FixedPoint, AccumConversions) {
505   // Normal conversions
506   CheckSignedAccumConversionsAgainstOthers(getSAccumSema(), 128);
507   CheckUnsignedAccumConversionsAgainstOthers(getUSAccumSema(), 256);
508   CheckSignedAccumConversionsAgainstOthers(getAccumSema(), 32768);
509   CheckUnsignedAccumConversionsAgainstOthers(getUAccumSema(), 65536);
510   CheckSignedAccumConversionsAgainstOthers(getLAccumSema(), 2147483648);
511   CheckUnsignedAccumConversionsAgainstOthers(getULAccumSema(), 4294967296);
512
513   CheckUnsignedAccumConversionsAgainstOthers(getPadUSAccumSema(), 128);
514   CheckUnsignedAccumConversionsAgainstOthers(getPadUAccumSema(), 32768);
515   CheckUnsignedAccumConversionsAgainstOthers(getPadULAccumSema(), 2147483648);
516 }
517
518 TEST(FixedPoint, AccumConversionOverflow) {
519   // To SAccum max limit (65536)
520   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getAccumSema()),
521                               140737488355328);
522   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getUAccumSema()),
523                               140737488355328);
524   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getPadUAccumSema()),
525                               140737488355328);
526   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getAccumSema()),
527                               281474976710656);
528   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getUAccumSema()),
529                               281474976710656);
530   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getPadUAccumSema()),
531                               281474976710656);
532
533   CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getAccumSema()),
534                               140737488355328);
535   CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getUAccumSema()),
536                               140737488355328);
537   CheckSaturatedConversionMax(getPadULAccumSema(),
538                               Saturated(getPadUAccumSema()), 140737488355328);
539
540   // To SAccum min limit (-65536)
541   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getAccumSema()),
542                               -140737488355328);
543   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getUAccumSema()),
544                               -140737488355328);
545   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getPadUAccumSema()),
546                               -140737488355328);
547 }
548
549 TEST(FixedPoint, SAccumConversionOverflow) {
550   // To SAccum max limit (256)
551   CheckSaturatedConversionMax(getAccumSema(), Saturated(getSAccumSema()),
552                               8388608);
553   CheckSaturatedConversionMax(getAccumSema(), Saturated(getUSAccumSema()),
554                               8388608);
555   CheckSaturatedConversionMax(getAccumSema(), Saturated(getPadUSAccumSema()),
556                               8388608);
557   CheckSaturatedConversionMax(getUAccumSema(), Saturated(getSAccumSema()),
558                               16777216);
559   CheckSaturatedConversionMax(getUAccumSema(), Saturated(getUSAccumSema()),
560                               16777216);
561   CheckSaturatedConversionMax(getUAccumSema(), Saturated(getPadUSAccumSema()),
562                               16777216);
563   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getSAccumSema()),
564                               549755813888);
565   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getUSAccumSema()),
566                               549755813888);
567   CheckSaturatedConversionMax(getLAccumSema(), Saturated(getPadUSAccumSema()),
568                               549755813888);
569   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getSAccumSema()),
570                               1099511627776);
571   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getUSAccumSema()),
572                               1099511627776);
573   CheckSaturatedConversionMax(getULAccumSema(), Saturated(getPadUSAccumSema()),
574                               1099511627776);
575
576   CheckSaturatedConversionMax(getPadUAccumSema(), Saturated(getSAccumSema()),
577                               8388608);
578   CheckSaturatedConversionMax(getPadUAccumSema(), Saturated(getUSAccumSema()),
579                               8388608);
580   CheckSaturatedConversionMax(getPadUAccumSema(),
581                               Saturated(getPadUSAccumSema()), 8388608);
582   CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getSAccumSema()),
583                               549755813888);
584   CheckSaturatedConversionMax(getPadULAccumSema(), Saturated(getUSAccumSema()),
585                               549755813888);
586   CheckSaturatedConversionMax(getPadULAccumSema(),
587                               Saturated(getPadUSAccumSema()), 549755813888);
588
589   // To SAccum min limit (-256)
590   CheckSaturatedConversionMin(getAccumSema(), Saturated(getSAccumSema()),
591                               -8388608);
592   CheckSaturatedConversionMin(getAccumSema(), Saturated(getUSAccumSema()),
593                               -8388608);
594   CheckSaturatedConversionMin(getAccumSema(), Saturated(getPadUSAccumSema()),
595                               -8388608);
596   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getSAccumSema()),
597                               -549755813888);
598   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getUSAccumSema()),
599                               -549755813888);
600   CheckSaturatedConversionMin(getLAccumSema(), Saturated(getPadUSAccumSema()),
601                               -549755813888);
602 }
603
604 TEST(FixedPoint, GetValueSignAfterConversion) {
605   APFixedPoint Fixed(255 << 7, getSAccumSema());
606   ASSERT_TRUE(Fixed.getValue().isSigned());
607   APFixedPoint UFixed = Fixed.convert(getUSAccumSema());
608   ASSERT_TRUE(UFixed.getValue().isUnsigned());
609   ASSERT_EQ(UFixed.getValue(), APSInt::getUnsigned(255 << 8).extOrTrunc(16));
610 }
611
612 TEST(FixedPoint, ModularWrapAround) {
613   // Positive to negative
614   APFixedPoint Val = APFixedPoint(1ULL << 7, getSAccumSema());
615   ASSERT_EQ(Val.convert(getLFractSema()).getValue(), -(1ULL << 31));
616
617   Val = APFixedPoint(1ULL << 23, getAccumSema());
618   ASSERT_EQ(Val.convert(getSAccumSema()).getValue(), -(1ULL << 15));
619
620   Val = APFixedPoint(1ULL << 47, getLAccumSema());
621   ASSERT_EQ(Val.convert(getAccumSema()).getValue(), -(1ULL << 31));
622
623   // Negative to positive
624   Val = APFixedPoint(/*-1.5*/ -192, getSAccumSema());
625   ASSERT_EQ(Val.convert(getLFractSema()).getValue(), 1ULL << 30);
626
627   Val = APFixedPoint(-(257 << 15), getAccumSema());
628   ASSERT_EQ(Val.convert(getSAccumSema()).getValue(), 255 << 7);
629
630   Val = APFixedPoint(-(65537ULL << 31), getLAccumSema());
631   ASSERT_EQ(Val.convert(getAccumSema()).getValue(), 65535 << 15);
632
633   // Signed to unsigned
634   Val = APFixedPoint(-(1 << 7), getSAccumSema());
635   ASSERT_EQ(Val.convert(getUSAccumSema()).getValue(), 255 << 8);
636
637   Val = APFixedPoint(-(1 << 15), getAccumSema());
638   ASSERT_EQ(Val.convert(getUAccumSema()).getValue(), 65535ULL << 16);
639
640   Val = APFixedPoint(-(1ULL << 31), getLAccumSema());
641   ASSERT_EQ(Val.convert(getULAccumSema()).getValue().getZExtValue(),
642             4294967295ULL << 32);
643 }
644
645 } // namespace