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