FixedPointTest.cpp 28 KB

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