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