ScaledNumberTest.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. //===- llvm/unittest/Support/ScaledNumberTest.cpp - ScaledPair 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 "llvm/Support/ScaledNumber.h"
  10. #include "llvm/Support/DataTypes.h"
  11. #include "gtest/gtest.h"
  12. using namespace llvm;
  13. using namespace llvm::ScaledNumbers;
  14. namespace {
  15. template <class UIntT> struct ScaledPair {
  16. UIntT D;
  17. int S;
  18. ScaledPair(const std::pair<UIntT, int16_t> &F) : D(F.first), S(F.second) {}
  19. ScaledPair(UIntT D, int S) : D(D), S(S) {}
  20. bool operator==(const ScaledPair<UIntT> &X) const {
  21. return D == X.D && S == X.S;
  22. }
  23. };
  24. template <class UIntT>
  25. bool operator==(const std::pair<UIntT, int16_t> &L,
  26. const ScaledPair<UIntT> &R) {
  27. return ScaledPair<UIntT>(L) == R;
  28. }
  29. template <class UIntT>
  30. void PrintTo(const ScaledPair<UIntT> &F, ::std::ostream *os) {
  31. *os << F.D << "*2^" << F.S;
  32. }
  33. typedef ScaledPair<uint32_t> SP32;
  34. typedef ScaledPair<uint64_t> SP64;
  35. TEST(ScaledNumberHelpersTest, getRounded) {
  36. EXPECT_EQ(getRounded32(0, 0, false), SP32(0, 0));
  37. EXPECT_EQ(getRounded32(0, 0, true), SP32(1, 0));
  38. EXPECT_EQ(getRounded32(20, 21, true), SP32(21, 21));
  39. EXPECT_EQ(getRounded32(UINT32_MAX, 0, false), SP32(UINT32_MAX, 0));
  40. EXPECT_EQ(getRounded32(UINT32_MAX, 0, true), SP32(1 << 31, 1));
  41. EXPECT_EQ(getRounded64(0, 0, false), SP64(0, 0));
  42. EXPECT_EQ(getRounded64(0, 0, true), SP64(1, 0));
  43. EXPECT_EQ(getRounded64(20, 21, true), SP64(21, 21));
  44. EXPECT_EQ(getRounded64(UINT32_MAX, 0, false), SP64(UINT32_MAX, 0));
  45. EXPECT_EQ(getRounded64(UINT32_MAX, 0, true), SP64(UINT64_C(1) << 32, 0));
  46. EXPECT_EQ(getRounded64(UINT64_MAX, 0, false), SP64(UINT64_MAX, 0));
  47. EXPECT_EQ(getRounded64(UINT64_MAX, 0, true), SP64(UINT64_C(1) << 63, 1));
  48. }
  49. TEST(ScaledNumberHelpersTest, getAdjusted) {
  50. const uint64_t Max32In64 = UINT32_MAX;
  51. EXPECT_EQ(getAdjusted32(0), SP32(0, 0));
  52. EXPECT_EQ(getAdjusted32(0, 5), SP32(0, 5));
  53. EXPECT_EQ(getAdjusted32(UINT32_MAX), SP32(UINT32_MAX, 0));
  54. EXPECT_EQ(getAdjusted32(Max32In64 << 1), SP32(UINT32_MAX, 1));
  55. EXPECT_EQ(getAdjusted32(Max32In64 << 1, 1), SP32(UINT32_MAX, 2));
  56. EXPECT_EQ(getAdjusted32(Max32In64 << 31), SP32(UINT32_MAX, 31));
  57. EXPECT_EQ(getAdjusted32(Max32In64 << 32), SP32(UINT32_MAX, 32));
  58. EXPECT_EQ(getAdjusted32(Max32In64 + 1), SP32(1u << 31, 1));
  59. EXPECT_EQ(getAdjusted32(UINT64_MAX), SP32(1u << 31, 33));
  60. EXPECT_EQ(getAdjusted64(0), SP64(0, 0));
  61. EXPECT_EQ(getAdjusted64(0, 5), SP64(0, 5));
  62. EXPECT_EQ(getAdjusted64(UINT32_MAX), SP64(UINT32_MAX, 0));
  63. EXPECT_EQ(getAdjusted64(Max32In64 << 1), SP64(Max32In64 << 1, 0));
  64. EXPECT_EQ(getAdjusted64(Max32In64 << 1, 1), SP64(Max32In64 << 1, 1));
  65. EXPECT_EQ(getAdjusted64(Max32In64 << 31), SP64(Max32In64 << 31, 0));
  66. EXPECT_EQ(getAdjusted64(Max32In64 << 32), SP64(Max32In64 << 32, 0));
  67. EXPECT_EQ(getAdjusted64(Max32In64 + 1), SP64(Max32In64 + 1, 0));
  68. EXPECT_EQ(getAdjusted64(UINT64_MAX), SP64(UINT64_MAX, 0));
  69. }
  70. TEST(ScaledNumberHelpersTest, getProduct) {
  71. // Zero.
  72. EXPECT_EQ(SP32(0, 0), getProduct32(0, 0));
  73. EXPECT_EQ(SP32(0, 0), getProduct32(0, 1));
  74. EXPECT_EQ(SP32(0, 0), getProduct32(0, 33));
  75. // Basic.
  76. EXPECT_EQ(SP32(6, 0), getProduct32(2, 3));
  77. EXPECT_EQ(SP32(UINT16_MAX / 3 * UINT16_MAX / 5 * 2, 0),
  78. getProduct32(UINT16_MAX / 3, UINT16_MAX / 5 * 2));
  79. // Overflow, no loss of precision.
  80. // ==> 0xf00010 * 0x1001
  81. // ==> 0xf00f00000 + 0x10010
  82. // ==> 0xf00f10010
  83. // ==> 0xf00f1001 * 2^4
  84. EXPECT_EQ(SP32(0xf00f1001, 4), getProduct32(0xf00010, 0x1001));
  85. // Overflow, loss of precision, rounds down.
  86. // ==> 0xf000070 * 0x1001
  87. // ==> 0xf00f000000 + 0x70070
  88. // ==> 0xf00f070070
  89. // ==> 0xf00f0700 * 2^8
  90. EXPECT_EQ(SP32(0xf00f0700, 8), getProduct32(0xf000070, 0x1001));
  91. // Overflow, loss of precision, rounds up.
  92. // ==> 0xf000080 * 0x1001
  93. // ==> 0xf00f000000 + 0x80080
  94. // ==> 0xf00f080080
  95. // ==> 0xf00f0801 * 2^8
  96. EXPECT_EQ(SP32(0xf00f0801, 8), getProduct32(0xf000080, 0x1001));
  97. // Reverse operand order.
  98. EXPECT_EQ(SP32(0, 0), getProduct32(1, 0));
  99. EXPECT_EQ(SP32(0, 0), getProduct32(33, 0));
  100. EXPECT_EQ(SP32(6, 0), getProduct32(3, 2));
  101. EXPECT_EQ(SP32(UINT16_MAX / 3 * UINT16_MAX / 5 * 2, 0),
  102. getProduct32(UINT16_MAX / 5 * 2, UINT16_MAX / 3));
  103. EXPECT_EQ(SP32(0xf00f1001, 4), getProduct32(0x1001, 0xf00010));
  104. EXPECT_EQ(SP32(0xf00f0700, 8), getProduct32(0x1001, 0xf000070));
  105. EXPECT_EQ(SP32(0xf00f0801, 8), getProduct32(0x1001, 0xf000080));
  106. // Round to overflow.
  107. EXPECT_EQ(SP64(UINT64_C(1) << 63, 64),
  108. getProduct64(UINT64_C(10376293541461622786),
  109. UINT64_C(16397105843297379211)));
  110. // Big number with rounding.
  111. EXPECT_EQ(SP64(UINT64_C(9223372036854775810), 64),
  112. getProduct64(UINT64_C(18446744073709551556),
  113. UINT64_C(9223372036854775840)));
  114. }
  115. TEST(ScaledNumberHelpersTest, getQuotient) {
  116. // Zero.
  117. EXPECT_EQ(SP32(0, 0), getQuotient32(0, 0));
  118. EXPECT_EQ(SP32(0, 0), getQuotient32(0, 1));
  119. EXPECT_EQ(SP32(0, 0), getQuotient32(0, 73));
  120. EXPECT_EQ(SP32(UINT32_MAX, MaxScale), getQuotient32(1, 0));
  121. EXPECT_EQ(SP32(UINT32_MAX, MaxScale), getQuotient32(6, 0));
  122. // Powers of two.
  123. EXPECT_EQ(SP32(1u << 31, -31), getQuotient32(1, 1));
  124. EXPECT_EQ(SP32(1u << 31, -30), getQuotient32(2, 1));
  125. EXPECT_EQ(SP32(1u << 31, -33), getQuotient32(4, 16));
  126. EXPECT_EQ(SP32(7u << 29, -29), getQuotient32(7, 1));
  127. EXPECT_EQ(SP32(7u << 29, -30), getQuotient32(7, 2));
  128. EXPECT_EQ(SP32(7u << 29, -33), getQuotient32(7, 16));
  129. // Divide evenly.
  130. EXPECT_EQ(SP32(3u << 30, -30), getQuotient32(9, 3));
  131. EXPECT_EQ(SP32(9u << 28, -28), getQuotient32(63, 7));
  132. // Divide unevenly.
  133. EXPECT_EQ(SP32(0xaaaaaaab, -33), getQuotient32(1, 3));
  134. EXPECT_EQ(SP32(0xd5555555, -31), getQuotient32(5, 3));
  135. // 64-bit division is hard to test, since divide64 doesn't canonicalize its
  136. // output. However, this is the algorithm the implementation uses:
  137. //
  138. // - Shift divisor right.
  139. // - If we have 1 (power of 2), return early -- not canonicalized.
  140. // - Shift dividend left.
  141. // - 64-bit integer divide.
  142. // - If there's a remainder, continue with long division.
  143. //
  144. // TODO: require less knowledge about the implementation in the test.
  145. // Zero.
  146. EXPECT_EQ(SP64(0, 0), getQuotient64(0, 0));
  147. EXPECT_EQ(SP64(0, 0), getQuotient64(0, 1));
  148. EXPECT_EQ(SP64(0, 0), getQuotient64(0, 73));
  149. EXPECT_EQ(SP64(UINT64_MAX, MaxScale), getQuotient64(1, 0));
  150. EXPECT_EQ(SP64(UINT64_MAX, MaxScale), getQuotient64(6, 0));
  151. // Powers of two.
  152. EXPECT_EQ(SP64(1, 0), getQuotient64(1, 1));
  153. EXPECT_EQ(SP64(2, 0), getQuotient64(2, 1));
  154. EXPECT_EQ(SP64(4, -4), getQuotient64(4, 16));
  155. EXPECT_EQ(SP64(7, 0), getQuotient64(7, 1));
  156. EXPECT_EQ(SP64(7, -1), getQuotient64(7, 2));
  157. EXPECT_EQ(SP64(7, -4), getQuotient64(7, 16));
  158. // Divide evenly.
  159. EXPECT_EQ(SP64(UINT64_C(3) << 60, -60), getQuotient64(9, 3));
  160. EXPECT_EQ(SP64(UINT64_C(9) << 58, -58), getQuotient64(63, 7));
  161. // Divide unevenly.
  162. EXPECT_EQ(SP64(0xaaaaaaaaaaaaaaab, -65), getQuotient64(1, 3));
  163. EXPECT_EQ(SP64(0xd555555555555555, -63), getQuotient64(5, 3));
  164. }
  165. TEST(ScaledNumberHelpersTest, getLg) {
  166. EXPECT_EQ(0, getLg(UINT32_C(1), 0));
  167. EXPECT_EQ(1, getLg(UINT32_C(1), 1));
  168. EXPECT_EQ(1, getLg(UINT32_C(2), 0));
  169. EXPECT_EQ(3, getLg(UINT32_C(1), 3));
  170. EXPECT_EQ(3, getLg(UINT32_C(7), 0));
  171. EXPECT_EQ(3, getLg(UINT32_C(8), 0));
  172. EXPECT_EQ(3, getLg(UINT32_C(9), 0));
  173. EXPECT_EQ(3, getLg(UINT32_C(64), -3));
  174. EXPECT_EQ(31, getLg((UINT32_MAX >> 1) + 2, 0));
  175. EXPECT_EQ(32, getLg(UINT32_MAX, 0));
  176. EXPECT_EQ(-1, getLg(UINT32_C(1), -1));
  177. EXPECT_EQ(-1, getLg(UINT32_C(2), -2));
  178. EXPECT_EQ(INT32_MIN, getLg(UINT32_C(0), -1));
  179. EXPECT_EQ(INT32_MIN, getLg(UINT32_C(0), 0));
  180. EXPECT_EQ(INT32_MIN, getLg(UINT32_C(0), 1));
  181. EXPECT_EQ(0, getLg(UINT64_C(1), 0));
  182. EXPECT_EQ(1, getLg(UINT64_C(1), 1));
  183. EXPECT_EQ(1, getLg(UINT64_C(2), 0));
  184. EXPECT_EQ(3, getLg(UINT64_C(1), 3));
  185. EXPECT_EQ(3, getLg(UINT64_C(7), 0));
  186. EXPECT_EQ(3, getLg(UINT64_C(8), 0));
  187. EXPECT_EQ(3, getLg(UINT64_C(9), 0));
  188. EXPECT_EQ(3, getLg(UINT64_C(64), -3));
  189. EXPECT_EQ(63, getLg((UINT64_MAX >> 1) + 2, 0));
  190. EXPECT_EQ(64, getLg(UINT64_MAX, 0));
  191. EXPECT_EQ(-1, getLg(UINT64_C(1), -1));
  192. EXPECT_EQ(-1, getLg(UINT64_C(2), -2));
  193. EXPECT_EQ(INT32_MIN, getLg(UINT64_C(0), -1));
  194. EXPECT_EQ(INT32_MIN, getLg(UINT64_C(0), 0));
  195. EXPECT_EQ(INT32_MIN, getLg(UINT64_C(0), 1));
  196. }
  197. TEST(ScaledNumberHelpersTest, getLgFloor) {
  198. EXPECT_EQ(0, getLgFloor(UINT32_C(1), 0));
  199. EXPECT_EQ(1, getLgFloor(UINT32_C(1), 1));
  200. EXPECT_EQ(1, getLgFloor(UINT32_C(2), 0));
  201. EXPECT_EQ(2, getLgFloor(UINT32_C(7), 0));
  202. EXPECT_EQ(3, getLgFloor(UINT32_C(1), 3));
  203. EXPECT_EQ(3, getLgFloor(UINT32_C(8), 0));
  204. EXPECT_EQ(3, getLgFloor(UINT32_C(9), 0));
  205. EXPECT_EQ(3, getLgFloor(UINT32_C(64), -3));
  206. EXPECT_EQ(31, getLgFloor((UINT32_MAX >> 1) + 2, 0));
  207. EXPECT_EQ(31, getLgFloor(UINT32_MAX, 0));
  208. EXPECT_EQ(INT32_MIN, getLgFloor(UINT32_C(0), -1));
  209. EXPECT_EQ(INT32_MIN, getLgFloor(UINT32_C(0), 0));
  210. EXPECT_EQ(INT32_MIN, getLgFloor(UINT32_C(0), 1));
  211. EXPECT_EQ(0, getLgFloor(UINT64_C(1), 0));
  212. EXPECT_EQ(1, getLgFloor(UINT64_C(1), 1));
  213. EXPECT_EQ(1, getLgFloor(UINT64_C(2), 0));
  214. EXPECT_EQ(2, getLgFloor(UINT64_C(7), 0));
  215. EXPECT_EQ(3, getLgFloor(UINT64_C(1), 3));
  216. EXPECT_EQ(3, getLgFloor(UINT64_C(8), 0));
  217. EXPECT_EQ(3, getLgFloor(UINT64_C(9), 0));
  218. EXPECT_EQ(3, getLgFloor(UINT64_C(64), -3));
  219. EXPECT_EQ(63, getLgFloor((UINT64_MAX >> 1) + 2, 0));
  220. EXPECT_EQ(63, getLgFloor(UINT64_MAX, 0));
  221. EXPECT_EQ(INT32_MIN, getLgFloor(UINT64_C(0), -1));
  222. EXPECT_EQ(INT32_MIN, getLgFloor(UINT64_C(0), 0));
  223. EXPECT_EQ(INT32_MIN, getLgFloor(UINT64_C(0), 1));
  224. }
  225. TEST(ScaledNumberHelpersTest, getLgCeiling) {
  226. EXPECT_EQ(0, getLgCeiling(UINT32_C(1), 0));
  227. EXPECT_EQ(1, getLgCeiling(UINT32_C(1), 1));
  228. EXPECT_EQ(1, getLgCeiling(UINT32_C(2), 0));
  229. EXPECT_EQ(3, getLgCeiling(UINT32_C(1), 3));
  230. EXPECT_EQ(3, getLgCeiling(UINT32_C(7), 0));
  231. EXPECT_EQ(3, getLgCeiling(UINT32_C(8), 0));
  232. EXPECT_EQ(3, getLgCeiling(UINT32_C(64), -3));
  233. EXPECT_EQ(4, getLgCeiling(UINT32_C(9), 0));
  234. EXPECT_EQ(32, getLgCeiling(UINT32_MAX, 0));
  235. EXPECT_EQ(32, getLgCeiling((UINT32_MAX >> 1) + 2, 0));
  236. EXPECT_EQ(INT32_MIN, getLgCeiling(UINT32_C(0), -1));
  237. EXPECT_EQ(INT32_MIN, getLgCeiling(UINT32_C(0), 0));
  238. EXPECT_EQ(INT32_MIN, getLgCeiling(UINT32_C(0), 1));
  239. EXPECT_EQ(0, getLgCeiling(UINT64_C(1), 0));
  240. EXPECT_EQ(1, getLgCeiling(UINT64_C(1), 1));
  241. EXPECT_EQ(1, getLgCeiling(UINT64_C(2), 0));
  242. EXPECT_EQ(3, getLgCeiling(UINT64_C(1), 3));
  243. EXPECT_EQ(3, getLgCeiling(UINT64_C(7), 0));
  244. EXPECT_EQ(3, getLgCeiling(UINT64_C(8), 0));
  245. EXPECT_EQ(3, getLgCeiling(UINT64_C(64), -3));
  246. EXPECT_EQ(4, getLgCeiling(UINT64_C(9), 0));
  247. EXPECT_EQ(64, getLgCeiling((UINT64_MAX >> 1) + 2, 0));
  248. EXPECT_EQ(64, getLgCeiling(UINT64_MAX, 0));
  249. EXPECT_EQ(INT32_MIN, getLgCeiling(UINT64_C(0), -1));
  250. EXPECT_EQ(INT32_MIN, getLgCeiling(UINT64_C(0), 0));
  251. EXPECT_EQ(INT32_MIN, getLgCeiling(UINT64_C(0), 1));
  252. }
  253. TEST(ScaledNumberHelpersTest, compare) {
  254. EXPECT_EQ(0, compare(UINT32_C(0), 0, UINT32_C(0), 1));
  255. EXPECT_EQ(0, compare(UINT32_C(0), 0, UINT32_C(0), -10));
  256. EXPECT_EQ(0, compare(UINT32_C(0), 0, UINT32_C(0), 20));
  257. EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(64), -3));
  258. EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(32), -2));
  259. EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(16), -1));
  260. EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(8), 0));
  261. EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(4), 1));
  262. EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(2), 2));
  263. EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(1), 3));
  264. EXPECT_EQ(-1, compare(UINT32_C(0), 0, UINT32_C(1), 3));
  265. EXPECT_EQ(-1, compare(UINT32_C(7), 0, UINT32_C(1), 3));
  266. EXPECT_EQ(-1, compare(UINT32_C(7), 0, UINT32_C(64), -3));
  267. EXPECT_EQ(1, compare(UINT32_C(9), 0, UINT32_C(1), 3));
  268. EXPECT_EQ(1, compare(UINT32_C(9), 0, UINT32_C(64), -3));
  269. EXPECT_EQ(1, compare(UINT32_C(9), 0, UINT32_C(0), 0));
  270. EXPECT_EQ(0, compare(UINT64_C(0), 0, UINT64_C(0), 1));
  271. EXPECT_EQ(0, compare(UINT64_C(0), 0, UINT64_C(0), -10));
  272. EXPECT_EQ(0, compare(UINT64_C(0), 0, UINT64_C(0), 20));
  273. EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(64), -3));
  274. EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(32), -2));
  275. EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(16), -1));
  276. EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(8), 0));
  277. EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(4), 1));
  278. EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(2), 2));
  279. EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(1), 3));
  280. EXPECT_EQ(-1, compare(UINT64_C(0), 0, UINT64_C(1), 3));
  281. EXPECT_EQ(-1, compare(UINT64_C(7), 0, UINT64_C(1), 3));
  282. EXPECT_EQ(-1, compare(UINT64_C(7), 0, UINT64_C(64), -3));
  283. EXPECT_EQ(1, compare(UINT64_C(9), 0, UINT64_C(1), 3));
  284. EXPECT_EQ(1, compare(UINT64_C(9), 0, UINT64_C(64), -3));
  285. EXPECT_EQ(1, compare(UINT64_C(9), 0, UINT64_C(0), 0));
  286. EXPECT_EQ(-1, compare(UINT64_MAX, 0, UINT64_C(1), 64));
  287. }
  288. TEST(ScaledNumberHelpersTest, matchScales) {
  289. #define MATCH_SCALES(T, LDIn, LSIn, RDIn, RSIn, LDOut, RDOut, SOut) \
  290. do { \
  291. T LDx = LDIn; \
  292. T RDx = RDIn; \
  293. T LDy = LDOut; \
  294. T RDy = RDOut; \
  295. int16_t LSx = LSIn; \
  296. int16_t RSx = RSIn; \
  297. int16_t Sy = SOut; \
  298. \
  299. EXPECT_EQ(SOut, matchScales(LDx, LSx, RDx, RSx)); \
  300. EXPECT_EQ(LDy, LDx); \
  301. EXPECT_EQ(RDy, RDx); \
  302. if (LDy) { \
  303. EXPECT_EQ(Sy, LSx); \
  304. } \
  305. if (RDy) { \
  306. EXPECT_EQ(Sy, RSx); \
  307. } \
  308. } while (false)
  309. MATCH_SCALES(uint32_t, 0, 0, 0, 0, 0, 0, 0);
  310. MATCH_SCALES(uint32_t, 0, 50, 7, 1, 0, 7, 1);
  311. MATCH_SCALES(uint32_t, UINT32_C(1) << 31, 1, 9, 0, UINT32_C(1) << 31, 4, 1);
  312. MATCH_SCALES(uint32_t, UINT32_C(1) << 31, 2, 9, 0, UINT32_C(1) << 31, 2, 2);
  313. MATCH_SCALES(uint32_t, UINT32_C(1) << 31, 3, 9, 0, UINT32_C(1) << 31, 1, 3);
  314. MATCH_SCALES(uint32_t, UINT32_C(1) << 31, 4, 9, 0, UINT32_C(1) << 31, 0, 4);
  315. MATCH_SCALES(uint32_t, UINT32_C(1) << 30, 4, 9, 0, UINT32_C(1) << 31, 1, 3);
  316. MATCH_SCALES(uint32_t, UINT32_C(1) << 29, 4, 9, 0, UINT32_C(1) << 31, 2, 2);
  317. MATCH_SCALES(uint32_t, UINT32_C(1) << 28, 4, 9, 0, UINT32_C(1) << 31, 4, 1);
  318. MATCH_SCALES(uint32_t, UINT32_C(1) << 27, 4, 9, 0, UINT32_C(1) << 31, 9, 0);
  319. MATCH_SCALES(uint32_t, 7, 1, 0, 50, 7, 0, 1);
  320. MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 31, 1, 4, UINT32_C(1) << 31, 1);
  321. MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 31, 2, 2, UINT32_C(1) << 31, 2);
  322. MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 31, 3, 1, UINT32_C(1) << 31, 3);
  323. MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 31, 4, 0, UINT32_C(1) << 31, 4);
  324. MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 30, 4, 1, UINT32_C(1) << 31, 3);
  325. MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 29, 4, 2, UINT32_C(1) << 31, 2);
  326. MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 28, 4, 4, UINT32_C(1) << 31, 1);
  327. MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 27, 4, 9, UINT32_C(1) << 31, 0);
  328. MATCH_SCALES(uint64_t, 0, 0, 0, 0, 0, 0, 0);
  329. MATCH_SCALES(uint64_t, 0, 100, 7, 1, 0, 7, 1);
  330. MATCH_SCALES(uint64_t, UINT64_C(1) << 63, 1, 9, 0, UINT64_C(1) << 63, 4, 1);
  331. MATCH_SCALES(uint64_t, UINT64_C(1) << 63, 2, 9, 0, UINT64_C(1) << 63, 2, 2);
  332. MATCH_SCALES(uint64_t, UINT64_C(1) << 63, 3, 9, 0, UINT64_C(1) << 63, 1, 3);
  333. MATCH_SCALES(uint64_t, UINT64_C(1) << 63, 4, 9, 0, UINT64_C(1) << 63, 0, 4);
  334. MATCH_SCALES(uint64_t, UINT64_C(1) << 62, 4, 9, 0, UINT64_C(1) << 63, 1, 3);
  335. MATCH_SCALES(uint64_t, UINT64_C(1) << 61, 4, 9, 0, UINT64_C(1) << 63, 2, 2);
  336. MATCH_SCALES(uint64_t, UINT64_C(1) << 60, 4, 9, 0, UINT64_C(1) << 63, 4, 1);
  337. MATCH_SCALES(uint64_t, UINT64_C(1) << 59, 4, 9, 0, UINT64_C(1) << 63, 9, 0);
  338. MATCH_SCALES(uint64_t, 7, 1, 0, 100, 7, 0, 1);
  339. MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 63, 1, 4, UINT64_C(1) << 63, 1);
  340. MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 63, 2, 2, UINT64_C(1) << 63, 2);
  341. MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 63, 3, 1, UINT64_C(1) << 63, 3);
  342. MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 63, 4, 0, UINT64_C(1) << 63, 4);
  343. MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 62, 4, 1, UINT64_C(1) << 63, 3);
  344. MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 61, 4, 2, UINT64_C(1) << 63, 2);
  345. MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 60, 4, 4, UINT64_C(1) << 63, 1);
  346. MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 59, 4, 9, UINT64_C(1) << 63, 0);
  347. }
  348. TEST(ScaledNumberHelpersTest, getSum) {
  349. // Zero.
  350. EXPECT_EQ(SP32(1, 0), getSum32(0, 0, 1, 0));
  351. EXPECT_EQ(SP32(8, -3), getSum32(0, 0, 8, -3));
  352. EXPECT_EQ(SP32(UINT32_MAX, 0), getSum32(0, 0, UINT32_MAX, 0));
  353. // Basic.
  354. EXPECT_EQ(SP32(2, 0), getSum32(1, 0, 1, 0));
  355. EXPECT_EQ(SP32(3, 0), getSum32(1, 0, 2, 0));
  356. EXPECT_EQ(SP32(67, 0), getSum32(7, 0, 60, 0));
  357. // Different scales.
  358. EXPECT_EQ(SP32(3, 0), getSum32(1, 0, 1, 1));
  359. EXPECT_EQ(SP32(4, 0), getSum32(2, 0, 1, 1));
  360. // Loss of precision.
  361. EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(1, 32, 1, 0));
  362. EXPECT_EQ(SP32(UINT32_C(1) << 31, -31), getSum32(1, -32, 1, 0));
  363. // Not quite loss of precision.
  364. EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, 1), getSum32(1, 32, 1, 1));
  365. EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, -32), getSum32(1, -32, 1, -1));
  366. // Overflow.
  367. EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(1, 0, UINT32_MAX, 0));
  368. // Reverse operand order.
  369. EXPECT_EQ(SP32(1, 0), getSum32(1, 0, 0, 0));
  370. EXPECT_EQ(SP32(8, -3), getSum32(8, -3, 0, 0));
  371. EXPECT_EQ(SP32(UINT32_MAX, 0), getSum32(UINT32_MAX, 0, 0, 0));
  372. EXPECT_EQ(SP32(3, 0), getSum32(2, 0, 1, 0));
  373. EXPECT_EQ(SP32(67, 0), getSum32(60, 0, 7, 0));
  374. EXPECT_EQ(SP32(3, 0), getSum32(1, 1, 1, 0));
  375. EXPECT_EQ(SP32(4, 0), getSum32(1, 1, 2, 0));
  376. EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(1, 0, 1, 32));
  377. EXPECT_EQ(SP32(UINT32_C(1) << 31, -31), getSum32(1, 0, 1, -32));
  378. EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, 1), getSum32(1, 1, 1, 32));
  379. EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, -32), getSum32(1, -1, 1, -32));
  380. EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(UINT32_MAX, 0, 1, 0));
  381. // Zero.
  382. EXPECT_EQ(SP64(1, 0), getSum64(0, 0, 1, 0));
  383. EXPECT_EQ(SP64(8, -3), getSum64(0, 0, 8, -3));
  384. EXPECT_EQ(SP64(UINT64_MAX, 0), getSum64(0, 0, UINT64_MAX, 0));
  385. // Basic.
  386. EXPECT_EQ(SP64(2, 0), getSum64(1, 0, 1, 0));
  387. EXPECT_EQ(SP64(3, 0), getSum64(1, 0, 2, 0));
  388. EXPECT_EQ(SP64(67, 0), getSum64(7, 0, 60, 0));
  389. // Different scales.
  390. EXPECT_EQ(SP64(3, 0), getSum64(1, 0, 1, 1));
  391. EXPECT_EQ(SP64(4, 0), getSum64(2, 0, 1, 1));
  392. // Loss of precision.
  393. EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(1, 64, 1, 0));
  394. EXPECT_EQ(SP64(UINT64_C(1) << 63, -63), getSum64(1, -64, 1, 0));
  395. // Not quite loss of precision.
  396. EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, 1), getSum64(1, 64, 1, 1));
  397. EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, -64), getSum64(1, -64, 1, -1));
  398. // Overflow.
  399. EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(1, 0, UINT64_MAX, 0));
  400. // Reverse operand order.
  401. EXPECT_EQ(SP64(1, 0), getSum64(1, 0, 0, 0));
  402. EXPECT_EQ(SP64(8, -3), getSum64(8, -3, 0, 0));
  403. EXPECT_EQ(SP64(UINT64_MAX, 0), getSum64(UINT64_MAX, 0, 0, 0));
  404. EXPECT_EQ(SP64(3, 0), getSum64(2, 0, 1, 0));
  405. EXPECT_EQ(SP64(67, 0), getSum64(60, 0, 7, 0));
  406. EXPECT_EQ(SP64(3, 0), getSum64(1, 1, 1, 0));
  407. EXPECT_EQ(SP64(4, 0), getSum64(1, 1, 2, 0));
  408. EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(1, 0, 1, 64));
  409. EXPECT_EQ(SP64(UINT64_C(1) << 63, -63), getSum64(1, 0, 1, -64));
  410. EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, 1), getSum64(1, 1, 1, 64));
  411. EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, -64), getSum64(1, -1, 1, -64));
  412. EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(UINT64_MAX, 0, 1, 0));
  413. }
  414. TEST(ScaledNumberHelpersTest, getDifference) {
  415. // Basic.
  416. EXPECT_EQ(SP32(0, 0), getDifference32(1, 0, 1, 0));
  417. EXPECT_EQ(SP32(1, 0), getDifference32(2, 0, 1, 0));
  418. EXPECT_EQ(SP32(53, 0), getDifference32(60, 0, 7, 0));
  419. // Equals "0", different scales.
  420. EXPECT_EQ(SP32(0, 0), getDifference32(2, 0, 1, 1));
  421. // Subtract "0".
  422. EXPECT_EQ(SP32(1, 0), getDifference32(1, 0, 0, 0));
  423. EXPECT_EQ(SP32(8, -3), getDifference32(8, -3, 0, 0));
  424. EXPECT_EQ(SP32(UINT32_MAX, 0), getDifference32(UINT32_MAX, 0, 0, 0));
  425. // Loss of precision.
  426. EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, 1),
  427. getDifference32((UINT32_C(1) << 31) + 1, 1, 1, 0));
  428. EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, -31),
  429. getDifference32((UINT32_C(1) << 31) + 1, -31, 1, -32));
  430. // Not quite loss of precision.
  431. EXPECT_EQ(SP32(UINT32_MAX, 0), getDifference32(1, 32, 1, 0));
  432. EXPECT_EQ(SP32(UINT32_MAX, -32), getDifference32(1, 0, 1, -32));
  433. // Saturate to "0".
  434. EXPECT_EQ(SP32(0, 0), getDifference32(0, 0, 1, 0));
  435. EXPECT_EQ(SP32(0, 0), getDifference32(0, 0, 8, -3));
  436. EXPECT_EQ(SP32(0, 0), getDifference32(0, 0, UINT32_MAX, 0));
  437. EXPECT_EQ(SP32(0, 0), getDifference32(7, 0, 60, 0));
  438. EXPECT_EQ(SP32(0, 0), getDifference32(1, 0, 1, 1));
  439. EXPECT_EQ(SP32(0, 0), getDifference32(1, -32, 1, 0));
  440. EXPECT_EQ(SP32(0, 0), getDifference32(1, -32, 1, -1));
  441. // Regression tests for cases that failed during bringup.
  442. EXPECT_EQ(SP32(UINT32_C(1) << 26, -31),
  443. getDifference32(1, 0, UINT32_C(31) << 27, -32));
  444. // Basic.
  445. EXPECT_EQ(SP64(0, 0), getDifference64(1, 0, 1, 0));
  446. EXPECT_EQ(SP64(1, 0), getDifference64(2, 0, 1, 0));
  447. EXPECT_EQ(SP64(53, 0), getDifference64(60, 0, 7, 0));
  448. // Equals "0", different scales.
  449. EXPECT_EQ(SP64(0, 0), getDifference64(2, 0, 1, 1));
  450. // Subtract "0".
  451. EXPECT_EQ(SP64(1, 0), getDifference64(1, 0, 0, 0));
  452. EXPECT_EQ(SP64(8, -3), getDifference64(8, -3, 0, 0));
  453. EXPECT_EQ(SP64(UINT64_MAX, 0), getDifference64(UINT64_MAX, 0, 0, 0));
  454. // Loss of precision.
  455. EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, 1),
  456. getDifference64((UINT64_C(1) << 63) + 1, 1, 1, 0));
  457. EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, -63),
  458. getDifference64((UINT64_C(1) << 63) + 1, -63, 1, -64));
  459. // Not quite loss of precision.
  460. EXPECT_EQ(SP64(UINT64_MAX, 0), getDifference64(1, 64, 1, 0));
  461. EXPECT_EQ(SP64(UINT64_MAX, -64), getDifference64(1, 0, 1, -64));
  462. // Saturate to "0".
  463. EXPECT_EQ(SP64(0, 0), getDifference64(0, 0, 1, 0));
  464. EXPECT_EQ(SP64(0, 0), getDifference64(0, 0, 8, -3));
  465. EXPECT_EQ(SP64(0, 0), getDifference64(0, 0, UINT64_MAX, 0));
  466. EXPECT_EQ(SP64(0, 0), getDifference64(7, 0, 60, 0));
  467. EXPECT_EQ(SP64(0, 0), getDifference64(1, 0, 1, 1));
  468. EXPECT_EQ(SP64(0, 0), getDifference64(1, -64, 1, 0));
  469. EXPECT_EQ(SP64(0, 0), getDifference64(1, -64, 1, -1));
  470. }
  471. TEST(ScaledNumberHelpersTest, arithmeticOperators) {
  472. EXPECT_EQ(ScaledNumber<uint32_t>(10, 0),
  473. ScaledNumber<uint32_t>(1, 3) + ScaledNumber<uint32_t>(1, 1));
  474. EXPECT_EQ(ScaledNumber<uint32_t>(6, 0),
  475. ScaledNumber<uint32_t>(1, 3) - ScaledNumber<uint32_t>(1, 1));
  476. EXPECT_EQ(ScaledNumber<uint32_t>(2, 3),
  477. ScaledNumber<uint32_t>(1, 3) * ScaledNumber<uint32_t>(1, 1));
  478. EXPECT_EQ(ScaledNumber<uint32_t>(1, 2),
  479. ScaledNumber<uint32_t>(1, 3) / ScaledNumber<uint32_t>(1, 1));
  480. EXPECT_EQ(ScaledNumber<uint32_t>(1, 2), ScaledNumber<uint32_t>(1, 3) >> 1);
  481. EXPECT_EQ(ScaledNumber<uint32_t>(1, 4), ScaledNumber<uint32_t>(1, 3) << 1);
  482. EXPECT_EQ(ScaledNumber<uint64_t>(10, 0),
  483. ScaledNumber<uint64_t>(1, 3) + ScaledNumber<uint64_t>(1, 1));
  484. EXPECT_EQ(ScaledNumber<uint64_t>(6, 0),
  485. ScaledNumber<uint64_t>(1, 3) - ScaledNumber<uint64_t>(1, 1));
  486. EXPECT_EQ(ScaledNumber<uint64_t>(2, 3),
  487. ScaledNumber<uint64_t>(1, 3) * ScaledNumber<uint64_t>(1, 1));
  488. EXPECT_EQ(ScaledNumber<uint64_t>(1, 2),
  489. ScaledNumber<uint64_t>(1, 3) / ScaledNumber<uint64_t>(1, 1));
  490. EXPECT_EQ(ScaledNumber<uint64_t>(1, 2), ScaledNumber<uint64_t>(1, 3) >> 1);
  491. EXPECT_EQ(ScaledNumber<uint64_t>(1, 4), ScaledNumber<uint64_t>(1, 3) << 1);
  492. }
  493. TEST(ScaledNumberHelpersTest, toIntBug) {
  494. ScaledNumber<uint32_t> n(1, 0);
  495. EXPECT_EQ(1u, (n * n).toInt<uint32_t>());
  496. }
  497. } // end namespace