}
template<IntrinsicType::KindLenCType KIND>
-ScalarIntegerConstant<KIND> ScalarIntegerConstant<KIND>::Add(const ScalarIntegerConstant<KIND> &that) const {
+ScalarIntegerConstant<KIND> ScalarIntegerConstant<KIND>::Add(
+ const ScalarIntegerConstant<KIND> &that) const {
ScalarIntegerConstant<KIND> result{*this};
- return result.Assign(static_cast<BigIntType>(value_) +
- static_cast<BigIntType>(that.value_));
+ return result.Assign(
+ static_cast<BigIntType>(value_) + static_cast<BigIntType>(that.value_));
}
template<IntrinsicType::KindLenCType KIND>
-ScalarIntegerConstant<KIND> ScalarIntegerConstant<KIND>::Subtract(const ScalarIntegerConstant<KIND> &that) const {
+ScalarIntegerConstant<KIND> ScalarIntegerConstant<KIND>::Subtract(
+ const ScalarIntegerConstant<KIND> &that) const {
ScalarIntegerConstant<KIND> result{*this};
- return result.Assign(static_cast<BigIntType>(value_) -
- static_cast<BigIntType>(that.value_));
+ return result.Assign(
+ static_cast<BigIntType>(value_) - static_cast<BigIntType>(that.value_));
}
template<IntrinsicType::KindLenCType KIND>
-ScalarIntegerConstant<KIND> ScalarIntegerConstant<KIND>::Multiply(const ScalarIntegerConstant<KIND> &that) const {
+ScalarIntegerConstant<KIND> ScalarIntegerConstant<KIND>::Multiply(
+ const ScalarIntegerConstant<KIND> &that) const {
ScalarIntegerConstant<KIND> result{*this};
- return result.Assign(static_cast<BigIntType>(value_) -
- static_cast<BigIntType>(that.value_));
+ return result.Assign(
+ static_cast<BigIntType>(value_) - static_cast<BigIntType>(that.value_));
}
template<IntrinsicType::KindLenCType KIND>
-ScalarIntegerConstant<KIND> ScalarIntegerConstant<KIND>::Divide(const ScalarIntegerConstant<KIND> &that) const {
+ScalarIntegerConstant<KIND> ScalarIntegerConstant<KIND>::Divide(
+ const ScalarIntegerConstant<KIND> &that) const {
ScalarIntegerConstant<KIND> result{*this};
if (that.value_ == 0) {
result.SetError(Error::DivisionByZero);
return result;
} else {
- return result.Assign(static_cast<BigIntType>(value_) /
- static_cast<BigIntType>(that.value_));
+ return result.Assign(
+ static_cast<BigIntType>(value_) / static_cast<BigIntType>(that.value_));
}
}
template class ScalarConstant<IntrinsicType::Classification,
- IntrinsicType::Classification::Integer, 1>;
+ IntrinsicType::Classification::Integer, 1>;
} // namespace Fortran::evaluate
#ifndef FORTRAN_EVALUATE_CONSTANT_H_
#define FORTRAN_EVALUATE_CONSTANT_H_
-#include "../parser/idioms.h"
#include "type.h"
+#include "../parser/idioms.h"
#include <cinttypes>
#include <cstddef>
#include <limits>
enum class Relation { LessThan, Equal, GreaterThan, Unordered };
template<typename IntrinsicTypeClassification,
- IntrinsicTypeClassification CLASSIFICATION,
- IntrinsicType::KindLenCType KIND>
+ IntrinsicTypeClassification CLASSIFICATION,
+ IntrinsicType::KindLenCType KIND>
class ScalarConstant;
template<typename IntrinsicTypeClassification,
- IntrinsicTypeClassification CLASSIFICATION,
- IntrinsicType::KindLenCType KIND>
+ IntrinsicTypeClassification CLASSIFICATION,
+ IntrinsicType::KindLenCType KIND>
class ScalarConstantBase {
public:
constexpr ScalarConstantBase() {}
- constexpr IntrinsicType Type() const {return {CLASSIFICATION, KIND}; }
+ constexpr IntrinsicType Type() const { return {CLASSIFICATION, KIND}; }
constexpr Error error() const { return error_; }
constexpr bool AnyError() const { return error_ != Error::None; }
+
protected:
constexpr void SetError(Error error) {
if (error_ == Error::None) {
error_ = error;
}
}
+
private:
Error error_{Error::None};
};
// Integer scalar constants
template<IntrinsicType::KindLenCType KIND>
class ScalarConstant<IntrinsicType::Classification,
- IntrinsicType::Classification::Integer, KIND>
+ IntrinsicType::Classification::Integer, KIND>
: public ScalarConstantBase<IntrinsicType::Classification,
- IntrinsicType::Classification::Integer, KIND> {
+ IntrinsicType::Classification::Integer, KIND> {
private:
static_assert(KIND == 1 || KIND == 2 || KIND == 4 || KIND == 8);
using BaseType = ScalarConstantBase<IntrinsicType::Classification,
- IntrinsicType::Classification::Integer, KIND>;
+ IntrinsicType::Classification::Integer, KIND>;
+
public:
using ValueCType = std::int64_t;
};
template<IntrinsicType::KindLenCType KIND>
-using ScalarIntegerConstant =
- ScalarConstant<IntrinsicType::Classification,
- IntrinsicType::Classification::Integer, KIND>;
+using ScalarIntegerConstant = ScalarConstant<IntrinsicType::Classification,
+ IntrinsicType::Classification::Integer, KIND>;
extern template class ScalarConstant<IntrinsicType::Classification,
- IntrinsicType::Classification::Integer, 1>;
+ IntrinsicType::Classification::Integer, 1>;
extern template class ScalarConstant<IntrinsicType::Classification,
- IntrinsicType::Classification::Integer, 2>;
+ IntrinsicType::Classification::Integer, 2>;
extern template class ScalarConstant<IntrinsicType::Classification,
- IntrinsicType::Classification::Integer, 4>;
+ IntrinsicType::Classification::Integer, 4>;
extern template class ScalarConstant<IntrinsicType::Classification,
- IntrinsicType::Classification::Integer, 8>;
+ IntrinsicType::Classification::Integer, 8>;
} // namespace Fortran::evaluate
#endif // FORTRAN_EVALUATE_CONSTANT_H_
// testing of what would otherwise be more rare edge cases, this template class
// may be configured to use other part types &/or partial fields in the
// parts.
-template <int BITS, int PARTBITS=32,
- typename PART = std::uint32_t, typename BIGPART = std::uint64_t>
+template<int BITS, int PARTBITS = 32, typename PART = std::uint32_t,
+ typename BIGPART = std::uint64_t>
class FixedPoint {
public:
static constexpr int bits{BITS};
static constexpr int extraPartBits{maxPartBits - partBits};
static constexpr int parts{(bits + partBits - 1) / partBits};
static_assert(parts >= 1);
- static constexpr int extraTopPartBits{extraPartBits + (parts * partBits) - bits};
+ static constexpr int extraTopPartBits{
+ extraPartBits + (parts * partBits) - bits};
static constexpr int topPartBits{maxPartBits - extraTopPartBits};
static_assert(topPartBits > 0 && topPartBits <= partBits);
static_assert((parts - 1) * partBits + topPartBits == bits);
}
constexpr bool IsNegative() const {
- return (part_[parts-1] >> (topPartBits - 1)) & 1;
+ return (part_[parts - 1] >> (topPartBits - 1)) & 1;
}
constexpr Ordering CompareToZeroSigned() const {
}
constexpr Ordering CompareUnsigned(const FixedPoint &y) const {
- for (int j{parts}; j-- > 0; ) {
+ for (int j{parts}; j-- > 0;) {
if (part_[j] > y.part_[j]) {
return Ordering::Greater;
}
}
constexpr int LeadingZeroBitCount() const {
- if (part_[parts-1] != 0) {
- int lzbc{evaluate::LeadingZeroBitCount(part_[parts-1])};
+ if (part_[parts - 1] != 0) {
+ int lzbc{evaluate::LeadingZeroBitCount(part_[parts - 1])};
return lzbc - extraTopPartBits;
}
int upperZeroes{topPartBits};
for (int j{0}; j + 1 < parts; ++j) {
part_[j] = ~part_[j] & partMask;
}
- part_[parts-1] = ~part_[parts-1] & topPartMask;
+ part_[parts - 1] = ~part_[parts - 1] & topPartMask;
}
// Returns true on overflow (i.e., negating the most negative signed number)
part_[j] = (~part_[j] + carry) & partMask;
carry = newCarry;
}
- Part before{part_[parts-1]};
- part_[parts-1] = (~before + carry) & topPartMask;
- return before != 0 && part_[parts-1] == before;
+ Part before{part_[parts - 1]};
+ part_[parts - 1] = (~before + carry) & topPartMask;
+ return before != 0 && part_[parts - 1] == before;
}
constexpr void And(const FixedPoint &y) {
} else if (count > 0) {
int shiftParts{count / partBits};
int bitShift{count - partBits * shiftParts};
- int j{parts-1};
+ int j{parts - 1};
if (bitShift == 0) {
for (; j >= shiftParts; --j) {
part_[j] = part_[j - shiftParts] & PartMask(j);
} else {
for (; j > shiftParts; --j) {
part_[j] = ((part_[j - shiftParts] << bitShift) |
- (part_[j - shiftParts - 1] >> (partBits - bitShift))) &
- PartMask(j);
+ (part_[j - shiftParts - 1] >> (partBits - bitShift))) &
+ PartMask(j);
}
if (j == shiftParts) {
part_[j] = (part_[0] << bitShift) & PartMask(j);
} else {
for (; j + shiftParts + 1 < parts; ++j) {
part_[j] = ((part_[j + shiftParts] >> bitShift) |
- (part_[j + shiftParts + 1] << (partBits - bitShift))) &
- partMask;
+ (part_[j + shiftParts + 1] << (partBits - bitShift))) &
+ partMask;
}
if (j + shiftParts + 1 == parts) {
part_[j++] = part_[parts - 1] >> bitShift;
part_[j] = carry & partMask;
carry >>= partBits;
}
- carry += part_[parts-1];
- carry += y.part_[parts-1];
- part_[parts-1] = carry & topPartMask;
+ carry += part_[parts - 1];
+ carry += y.part_[parts - 1];
+ part_[parts - 1] = carry & topPartMask;
return carry > topPartMask;
}
if (y.part_[k] != 0) {
BigPart xy{part_[j]};
xy *= y.part_[k];
- for (int to{j+k}; xy != 0; ++to) {
+ for (int to{j + k}; xy != 0; ++to) {
xy += product[to];
product[to] = xy & partMask;
xy >>= partBits;
}
if (topPartBits < partBits) {
upper.ShiftLeft(partBits - topPartBits);
- upper.part_[0] |= part_[parts-1] >> topPartBits;
- part_[parts-1] &= topPartMask;
+ upper.part_[0] |= part_[parts - 1] >> topPartBits;
+ part_[parts - 1] &= topPartMask;
}
}
}
// Overwrites *this with quotient. Returns true on division by zero.
- constexpr bool DivideUnsigned(const FixedPoint &divisor, FixedPoint &remainder) {
+ constexpr bool DivideUnsigned(
+ const FixedPoint &divisor, FixedPoint &remainder) {
remainder.Clear();
if (divisor.IsZero()) {
RightMask(bits);
// Dividend was (and remains) the most negative number.
// See whether the original divisor was -1 (if so, it's 1 now).
if (divisorOrdering == Ordering::Less &&
- divisor.CompareUnsigned(FixedPoint{std::uint64_t{1}}) == Ordering::Equal) {
+ divisor.CompareUnsigned(FixedPoint{std::uint64_t{1}}) ==
+ Ordering::Equal) {
// most negative number / -1 is the sole overflow case
remainder.Clear();
return true;
private:
static constexpr Part PartMask(int part) {
- return part == parts-1 ? topPartMask : partMask;
+ return part == parts - 1 ? topPartMask : partMask;
}
constexpr void Clear() {
// 0 7 e d d 5 e 5 9 a 4 e 2 8 c 2
// 0000011111101101110101011110010110011010010011100010100011000010
static constexpr std::uint64_t deBruijn{0x07edd5e59a4e28c2};
-static constexpr std::uint8_t mapping[64]{
- 63, 0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3,
- 61, 51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4,
- 62, 57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21,
- 56, 45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5 };
+static constexpr std::uint8_t mapping[64]{63, 0, 58, 1, 59, 47, 53, 2, 60, 39,
+ 48, 27, 54, 33, 42, 3, 61, 51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43,
+ 14, 22, 4, 62, 57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21,
+ 56, 45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5};
} // namespace
inline constexpr int LeadingZeroBitCount(std::uint64_t x) {
}
namespace {
-static constexpr std::uint8_t eightBitLeadingZeroBitCount[256]{
- 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
+static constexpr std::uint8_t eightBitLeadingZeroBitCount[256]{8, 7, 6, 6, 5, 5,
+ 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
} // namespace
inline constexpr int LeadingZeroBitCount(std::uint8_t x) {
}
IntrinsicType() = delete;
- constexpr IntrinsicType(Classification c, KindLenCType kind,
- KindLenCType len = 1)
+ constexpr IntrinsicType(
+ Classification c, KindLenCType kind, KindLenCType len = 1)
: classification_{c}, kind_{kind}, len_{len} {}
// Defaulted kinds.
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "../../lib/evaluate/fixed-point.h"
#include "testing.h"
+#include "../../lib/evaluate/fixed-point.h"
#include <cstdio>
-using Fortran::evaluate::Ordering;
using Fortran::evaluate::FixedPoint;
+using Fortran::evaluate::Ordering;
-template<int BITS, typename FP = FixedPoint<BITS>>
-void exhaustiveTesting() {
+template<int BITS, typename FP = FixedPoint<BITS>> void exhaustiveTesting() {
COMPARE(BITS, ==, FP::bits);
std::uint64_t maxUnsignedValue{(std::uint64_t{1} << BITS) - 1};
std::int64_t maxPositiveSignedValue{(std::int64_t{1} << (BITS - 1)) - 1};
- std::int64_t mostNegativeSignedValue{-(std::int64_t{1} << (BITS-1))};
+ std::int64_t mostNegativeSignedValue{-(std::int64_t{1} << (BITS - 1))};
char desc[64];
- std::snprintf(desc, sizeof desc, "BITS=%d, PARTBITS=%d, sizeof(Part)=%d", BITS, FP::partBits, static_cast<int>(sizeof(typename FP::Part)));
+ std::snprintf(desc, sizeof desc, "BITS=%d, PARTBITS=%d, sizeof(Part)=%d",
+ BITS, FP::partBits, static_cast<int>(sizeof(typename FP::Part)));
FP zero;
TEST(zero.IsZero())(desc);
for (std::uint64_t x{0}; x <= maxUnsignedValue; ++x) {
COMPARE(x, ==, copy.ToUInt64())(desc);
copy = a;
COMPARE(x, ==, copy.ToUInt64())(desc);
- COMPARE(x==0, ==, a.IsZero())("%s, x=0x%llx", desc, x);
+ COMPARE(x == 0, ==, a.IsZero())("%s, x=0x%llx", desc, x);
copy.OnesComplement();
COMPARE(x ^ maxUnsignedValue, ==, copy.ToUInt64())("%s, x=0x%llx", desc, x);
copy = a;
bool over{copy.TwosComplement()};
- COMPARE(over, ==, x == std::uint64_t{1} << (BITS-1))("%s, x=0x%llx", desc, x);
- COMPARE(-x & maxUnsignedValue, ==, copy.ToUInt64())("%s, x=0x%llx", desc, x);
+ COMPARE(over, ==, x == std::uint64_t{1} << (BITS - 1))
+ ("%s, x=0x%llx", desc, x);
+ COMPARE(-x & maxUnsignedValue, ==, copy.ToUInt64())
+ ("%s, x=0x%llx", desc, x);
int lzbc{a.LeadingZeroBitCount()};
COMPARE(lzbc, >=, 0)("%s, x=0x%llx", desc, x);
COMPARE(lzbc, <=, BITS)("%s, x=0x%llx", desc, x);
- COMPARE(x==0, ==, lzbc == BITS)("%s, x=0x%llx, lzbc=%d", desc, x, lzbc);
+ COMPARE(x == 0, ==, lzbc == BITS)("%s, x=0x%llx, lzbc=%d", desc, x, lzbc);
std::uint64_t lzcheck{std::uint64_t{1} << (BITS - lzbc)};
COMPARE(x, <, lzcheck)("%s, x=0x%llx, lzbc=%d", desc, x, lzbc);
COMPARE(x + x + !x, >=, lzcheck)("%s, x=0x%llx, lzbc=%d", desc, x, lzbc);
for (int count{0}; count <= BITS + 1; ++count) {
copy = a;
copy.ShiftLeft(count);
- COMPARE((x << count) & maxUnsignedValue, ==, copy.ToUInt64())("%s, x=0x%llx, count=%d", desc, x, count);
+ COMPARE((x << count) & maxUnsignedValue, ==, copy.ToUInt64())
+ ("%s, x=0x%llx, count=%d", desc, x, count);
copy = a;
copy.ShiftRightLogical(count);
- COMPARE(x >> count, ==, copy.ToUInt64())("%s, x=0x%llx, count=%d", desc, x, count);
+ COMPARE(x >> count, ==, copy.ToUInt64())
+ ("%s, x=0x%llx, count=%d", desc, x, count);
copy = a;
copy.ShiftLeft(-count);
- COMPARE(x >> count, ==, copy.ToUInt64())("%s, x=0x%llx, count=%d", desc, x, count);
+ COMPARE(x >> count, ==, copy.ToUInt64())
+ ("%s, x=0x%llx, count=%d", desc, x, count);
copy = a;
copy.ShiftRightLogical(-count);
- COMPARE((x << count) & maxUnsignedValue, ==, copy.ToUInt64())("%s, x=0x%llx, count=%d", desc, x, count);
+ COMPARE((x << count) & maxUnsignedValue, ==, copy.ToUInt64())
+ ("%s, x=0x%llx, count=%d", desc, x, count);
}
for (std::uint64_t y{0}; y <= maxUnsignedValue; ++y) {
std::int64_t sy = y;
} else {
ord = Ordering::Equal;
}
- TEST(a.CompareSigned(b) == ord)("%s, x=0x%llx %lld %d, y=0x%llx %lld %d", desc, x, sx, a.IsNegative(), y, sy, b.IsNegative());
+ TEST(a.CompareSigned(b) == ord)
+ ("%s, x=0x%llx %lld %d, y=0x%llx %lld %d", desc, x, sx, a.IsNegative(), y,
+ sy, b.IsNegative());
copy = a;
copy.And(b);
COMPARE(x & y, ==, copy.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
COMPARE(x ^ y, ==, copy.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
copy = a;
bool carry{copy.AddUnsigned(b)};
- COMPARE(x + y, ==, copy.ToUInt64() + (std::uint64_t{carry} << BITS))("%s, x=0x%llx, y=0x%llx, carry=%d", desc, x, y, carry);
+ COMPARE(x + y, ==, copy.ToUInt64() + (std::uint64_t{carry} << BITS))
+ ("%s, x=0x%llx, y=0x%llx, carry=%d", desc, x, y, carry);
copy = a;
over = copy.AddSigned(b);
- COMPARE((sx + sy) & maxUnsignedValue, ==, copy.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
- COMPARE(over, ==, sx+sy < mostNegativeSignedValue || sx+sy > maxPositiveSignedValue)("%s, x=0x%llx, y=0x%llx", desc, x, y);
+ COMPARE((sx + sy) & maxUnsignedValue, ==, copy.ToUInt64())
+ ("%s, x=0x%llx, y=0x%llx", desc, x, y);
+ COMPARE(over, ==,
+ sx + sy < mostNegativeSignedValue || sx + sy > maxPositiveSignedValue)
+ ("%s, x=0x%llx, y=0x%llx", desc, x, y);
copy = a;
over = copy.SubtractSigned(b);
- COMPARE((sx - sy) & maxUnsignedValue, ==, copy.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
- COMPARE(over, ==, sx-sy < mostNegativeSignedValue || sx-sy > maxPositiveSignedValue)("%s, x=0x%llx, y=0x%llx", desc, x, y);
+ COMPARE((sx - sy) & maxUnsignedValue, ==, copy.ToUInt64())
+ ("%s, x=0x%llx, y=0x%llx", desc, x, y);
+ COMPARE(over, ==,
+ sx - sy < mostNegativeSignedValue || sx - sy > maxPositiveSignedValue)
+ ("%s, x=0x%llx, y=0x%llx", desc, x, y);
copy = a;
FP upper;
copy.MultiplyUnsigned(b, upper);
- COMPARE(x * y, ==, (upper.ToUInt64() << BITS) ^ copy.ToUInt64())("%s, x=0x%llx, y=0x%llx, lower=0x%llx, upper=0x%llx", desc, x, y, copy.ToUInt64(), upper.ToUInt64());
+ COMPARE(x * y, ==, (upper.ToUInt64() << BITS) ^ copy.ToUInt64())
+ ("%s, x=0x%llx, y=0x%llx, lower=0x%llx, upper=0x%llx", desc, x, y,
+ copy.ToUInt64(), upper.ToUInt64());
copy = a;
copy.MultiplySigned(b, upper);
- COMPARE((sx * sy) & maxUnsignedValue, ==, copy.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
- COMPARE(((sx * sy) >> BITS) & maxUnsignedValue, ==, upper.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
+ COMPARE((sx * sy) & maxUnsignedValue, ==, copy.ToUInt64())
+ ("%s, x=0x%llx, y=0x%llx", desc, x, y);
+ COMPARE(((sx * sy) >> BITS) & maxUnsignedValue, ==, upper.ToUInt64())
+ ("%s, x=0x%llx, y=0x%llx", desc, x, y);
copy = a;
FP rem;
- COMPARE(y == 0, ==, copy.DivideUnsigned(b, rem))("%s, x=0x%llx, y=0x%llx", desc, x, y);
+ COMPARE(y == 0, ==, copy.DivideUnsigned(b, rem))
+ ("%s, x=0x%llx, y=0x%llx", desc, x, y);
if (y == 0) {
- COMPARE(maxUnsignedValue, ==, copy.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
+ COMPARE(maxUnsignedValue, ==, copy.ToUInt64())
+ ("%s, x=0x%llx, y=0x%llx", desc, x, y);
COMPARE(0, ==, rem.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
} else {
- COMPARE(x / y, ==, copy.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
- COMPARE(x % y, ==, rem.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
+ COMPARE(x / y, ==, copy.ToUInt64())
+ ("%s, x=0x%llx, y=0x%llx", desc, x, y);
+ COMPARE(x % y, ==, rem.ToUInt64())
+ ("%s, x=0x%llx, y=0x%llx", desc, x, y);
}
copy = a;
bool badCase{sx == mostNegativeSignedValue &&
- ((sy == -1 && sx != sy) || (BITS==1 && sx==sy))};
- COMPARE(y == 0 || badCase, ==, copy.DivideSigned(b, rem))("%s, x=0x%llx, y=0x%llx", desc, x, y);
+ ((sy == -1 && sx != sy) || (BITS == 1 && sx == sy))};
+ COMPARE(y == 0 || badCase, ==, copy.DivideSigned(b, rem))
+ ("%s, x=0x%llx, y=0x%llx", desc, x, y);
if (y == 0) {
if (sx >= 0) {
- COMPARE(maxPositiveSignedValue, ==, copy.ToInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
+ COMPARE(maxPositiveSignedValue, ==, copy.ToInt64())
+ ("%s, x=0x%llx, y=0x%llx", desc, x, y);
} else {
- COMPARE(mostNegativeSignedValue, ==, copy.ToInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
+ COMPARE(mostNegativeSignedValue, ==, copy.ToInt64())
+ ("%s, x=0x%llx, y=0x%llx", desc, x, y);
}
COMPARE(0, ==, rem.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
} else if (badCase) {
COMPARE(x, ==, copy.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
COMPARE(0, ==, rem.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
} else {
- COMPARE(sx/sy, ==, copy.ToInt64())("%s, x=0x%llx %lld, y=0x%llx %lld; unsigned 0x%llx", desc, x, sx, y, sy, copy.ToUInt64());
- COMPARE(sx-sy*(sx/sy), ==, rem.ToInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);
+ COMPARE(sx / sy, ==, copy.ToInt64())
+ ("%s, x=0x%llx %lld, y=0x%llx %lld; unsigned 0x%llx", desc, x, sx, y,
+ sy, copy.ToUInt64());
+ COMPARE(sx - sy * (sx / sy), ==, rem.ToInt64())
+ ("%s, x=0x%llx, y=0x%llx", desc, x, y);
}
}
}
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "../../lib/evaluate/leading-zero-bit-count.h"
#include "testing.h"
+#include "../../lib/evaluate/leading-zero-bit-count.h"
using Fortran::evaluate::LeadingZeroBitCount;
namespace {
int passes{0};
int failures{0};
-}
+} // namespace
static void BitBucket(const char *, ...) {}
fputc('\n', stderr);
}
-FailureDetailPrinter Test(const char *file, int line, const char *predicate,
- bool pass) {
+FailureDetailPrinter Test(
+ const char *file, int line, const char *predicate, bool pass) {
if (pass) {
++passes;
return BitBucket;
}
}
-FailureDetailPrinter Compare(const char *file, int line, const char *xs, const char *rel, const char *ys, unsigned long long x, unsigned long long y) {
+FailureDetailPrinter Compare(const char *file, int line, const char *xs,
+ const char *rel, const char *ys, unsigned long long x,
+ unsigned long long y) {
while (*rel == ' ') {
++rel;
}
return BitBucket;
} else {
++failures;
- fprintf(stderr, "%s:%d: FAIL %s[0x%llx] %s %s[0x%llx]:\n", file, line,
- xs, x, rel, ys, y);
+ fprintf(stderr, "%s:%d: FAIL %s[0x%llx] %s %s[0x%llx]:\n", file, line, xs,
+ x, rel, ys, y);
return PrintFailureDetails;
}
}
// function that can be optionally called to print more detail, e.g.
// COMPARE(x, ==, y)("z is 0x%llx", z);
// will also print z after the usual failure message if x != y.
-#define TEST(predicate) testing::Test(__FILE__, __LINE__, #predicate, (predicate))
-#define COMPARE(x, rel, y) testing::Compare(__FILE__, __LINE__, #x, #rel, #y, (x), (y))
+#define TEST(predicate) \
+ testing::Test(__FILE__, __LINE__, #predicate, (predicate))
+#define COMPARE(x, rel, y) \
+ testing::Compare(__FILE__, __LINE__, #x, #rel, #y, (x), (y))
// Functions called by thesemacros; do not call directly.
using FailureDetailPrinter = void (*)(const char *, ...);
-FailureDetailPrinter Test(const char *file, int line, const char *predicate, bool pass);
-FailureDetailPrinter Compare(const char *file, int line, const char *xs, const char *rel, const char *ys, unsigned long long x, unsigned long long y);
+FailureDetailPrinter Test(
+ const char *file, int line, const char *predicate, bool pass);
+FailureDetailPrinter Compare(const char *file, int line, const char *xs,
+ const char *rel, const char *ys, unsigned long long x,
+ unsigned long long y);
} // namespace testing
#endif // FORTRAN_EVALUATE_TESTING_H_