brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.5 KiB · 5ab22cc Raw
266 lines · cpp
1#include "flang/Evaluate/integer.h"2#include "flang/Testing/testing.h"3#include <cstdio>4#include <string>5 6using Fortran::evaluate::Ordering;7using Fortran::evaluate::value::Integer;8 9template <int BITS, typename INT = Integer<BITS>> void exhaustiveTesting() {10  std::uint64_t maxUnsignedValue{(std::uint64_t{1} << BITS) - 1};11  std::int64_t maxPositiveSignedValue{(std::int64_t{1} << (BITS - 1)) - 1};12  std::int64_t mostNegativeSignedValue{-(std::int64_t{1} << (BITS - 1))};13  char desc[64];14  std::snprintf(desc, sizeof desc,15      "BITS=%d, PARTBITS=%d, sizeof(Part)=%d, LE=%d", BITS, INT::partBits,16      static_cast<int>(sizeof(typename INT::Part)), INT::littleEndian);17 18  MATCH(BITS, INT::bits)(desc);19  MATCH(maxPositiveSignedValue, INT::HUGE().ToUInt64())(desc);20  INT zero;21  TEST(zero.IsZero())(desc);22  MATCH(0, zero.ToUInt64())(desc);23  MATCH(0, zero.ToInt64())(desc);24 25  for (std::uint64_t x{0}; x <= maxUnsignedValue; ++x) {26    unsigned long long ullx = x;27    INT a{x};28    MATCH(x, a.ToUInt64())(desc);29    INT copy{a};30    MATCH(x, copy.ToUInt64())(desc);31    copy = a;32    MATCH(x, copy.ToUInt64())(desc);33    MATCH(x == 0, a.IsZero())("%s, x=0x%llx", desc, x);34    char buffer[64];35    std::snprintf(buffer, sizeof buffer, "   %llu", ullx);36    const char *p{buffer};37    auto readcheck{INT::Read(p)};38    TEST(!readcheck.overflow)("%s, x=0x%llx", desc, x);39    MATCH(x, readcheck.value.ToUInt64())("%s, x=0x%llx", desc, x);40    TEST(!*p)("%s, x=0x%llx", desc, x);41    std::snprintf(buffer, sizeof buffer, "%llx", ullx);42    p = buffer;43    readcheck = INT::Read(p, 16);44    TEST(!readcheck.overflow)("%s, x=0x%llx", desc, x);45    MATCH(x, readcheck.value.ToUInt64())("%s, x=0x%llx", desc, x);46    TEST(!*p)("%s, x=0x%llx", desc, x);47    std::string udec{a.UnsignedDecimal()};48    p = udec.data();49    readcheck = INT::Read(p);50    TEST(!readcheck.overflow)("%s, x=0x%llx", desc, x);51    MATCH(x, readcheck.value.ToUInt64())("%s, x=0x%llx", desc, x);52    TEST(!*p)("%s, x=0x%llx", desc, x);53    std::string hex{a.Hexadecimal()};54    p = hex.data();55    readcheck = INT::Read(p, 16);56    TEST(!readcheck.overflow)("%s, x=0x%llx", desc, x);57    MATCH(x, readcheck.value.ToUInt64())("%s, x=0x%llx", desc, x);58    TEST(!*p)("%s, x=0x%llx", desc, x);59    INT t{a.NOT()};60    MATCH(x ^ maxUnsignedValue, t.ToUInt64())("%s, x=0x%llx", desc, x);61    auto negated{a.Negate()};62    MATCH(x == std::uint64_t{1} << (BITS - 1), negated.overflow)63    ("%s, x=0x%llx", desc, x);64    MATCH(-x & maxUnsignedValue, negated.value.ToUInt64())65    ("%s, x=0x%llx", desc, x);66    auto abs{a.ABS()};67    MATCH(x == std::uint64_t{1} << (BITS - 1), abs.overflow)68    ("%s, x=0x%llx", desc, x);69    MATCH(x >> (BITS - 1) ? -x & maxUnsignedValue : x, abs.value.ToUInt64())70    ("%s, x=0x%llx", desc, x);71    int lzbc{a.LEADZ()};72    COMPARE(lzbc, >=, 0)("%s, x=0x%llx", desc, x);73    COMPARE(lzbc, <=, BITS)("%s, x=0x%llx", desc, x);74    MATCH(x == 0, lzbc == BITS)("%s, x=0x%llx, lzbc=%d", desc, x, lzbc);75    std::uint64_t lzcheck{std::uint64_t{1} << (BITS - lzbc)};76    COMPARE(x, <, lzcheck)("%s, x=0x%llx, lzbc=%d", desc, x, lzbc);77    COMPARE(x + x + !x, >=, lzcheck)("%s, x=0x%llx, lzbc=%d", desc, x, lzbc);78    int popcheck{0};79    for (int j{0}; j < BITS; ++j) {80      popcheck += (x >> j) & 1;81    }82    MATCH(popcheck, a.POPCNT())("%s, x=0x%llx", desc, x);83    MATCH(popcheck & 1, a.POPPAR())("%s, x=0x%llx", desc, x);84    int trailcheck{0};85    for (; trailcheck < BITS; ++trailcheck) {86      if ((x >> trailcheck) & 1) {87        break;88      }89    }90    MATCH(trailcheck, a.TRAILZ())("%s, x=0x%llx", desc, x);91    for (int j{0}; j < BITS; ++j) {92      MATCH((x >> j) & 1, a.BTEST(j))93      ("%s, x=0x%llx, bit %d", desc, x, j);94    }95    // TODO test DIM, MODULO, ISHFTC, DSHIFTL/R96    // TODO test IBCLR, IBSET, IBITS, MAX, MIN, MERGE_BITS, RANGE, SIGN97 98    Ordering ord{Ordering::Equal};99    std::int64_t sx = x;100    if (x + x > maxUnsignedValue) {101      TEST(a.IsNegative())("%s, x=0x%llx", desc, x);102      sx = x | (~std::uint64_t{0} << BITS);103      TEST(sx < 0)("%s, x=0x%llx %lld", desc, x, sx);104      ord = Ordering::Less;105    } else {106      TEST(!a.IsNegative())("%s, x=0x%llx", desc, x);107      TEST(sx >= 0)("%s, x=0x%llx %lld", desc, x, sx);108      if (sx > 0) {109        ord = Ordering::Greater;110      } else {111        ord = Ordering::Equal;112      }113    }114 115    TEST(sx == a.ToInt64())("%s, x=0x%llx %lld", desc, x, sx);116    TEST(a.CompareToZeroSigned() == ord)("%s, x=0x%llx %lld", desc, x, sx);117    for (int count{0}; count <= BITS + 1; ++count) {118      t = a.SHIFTL(count);119      MATCH((x << count) & maxUnsignedValue, t.ToUInt64())120      ("%s, x=0x%llx, count=%d", desc, x, count);121      t = a.ISHFT(count);122      MATCH((x << count) & maxUnsignedValue, t.ToUInt64())123      ("%s, x=0x%llx, count=%d", desc, x, count);124      t = a.SHIFTR(count);125      MATCH(x >> count, t.ToUInt64())126      ("%s, x=0x%llx, count=%d", desc, x, count);127      t = a.ISHFT(-count);128      MATCH(x >> count, t.ToUInt64())("%s, x=0x%llx, count=%d", desc, x, count);129      t = a.SHIFTA(count);130      std::uint64_t fill{-(x >> (BITS - 1))};131      std::uint64_t sra{132          count >= BITS ? fill : (x >> count) | (fill << (BITS - count))};133      MATCH(sra, t.ToInt64())134      ("%s, x=0x%llx, count=%d", desc, x, count);135    }136 137    for (std::uint64_t y{0}; y <= maxUnsignedValue; ++y) {138      std::int64_t sy = y;139      if (y + y > maxUnsignedValue) {140        sy = y | (~std::uint64_t{0} << BITS);141      }142      INT b{y};143      if (x < y) {144        ord = Ordering::Less;145      } else if (x > y) {146        ord = Ordering::Greater;147      } else {148        ord = Ordering::Equal;149      }150      TEST(a.CompareUnsigned(b) == ord)("%s, x=0x%llx, y=0x%llx", desc, x, y);151      MATCH(x >= y, a.BGE(b))("%s, x=0x%llx, y=0x%llx", desc, x, y);152      MATCH(x > y, a.BGT(b))("%s, x=0x%llx, y=0x%llx", desc, x, y);153      MATCH(x <= y, a.BLE(b))("%s, x=0x%llx, y=0x%llx", desc, x, y);154      MATCH(x < y, a.BLT(b))("%s, x=0x%llx, y=0x%llx", desc, x, y);155      if (sx < sy) {156        ord = Ordering::Less;157      } else if (sx > sy) {158        ord = Ordering::Greater;159      } else {160        ord = Ordering::Equal;161      }162      TEST(a.CompareSigned(b) == ord)163      ("%s, x=0x%llx %lld %d, y=0x%llx %lld %d", desc, x, sx, a.IsNegative(), y,164          sy, b.IsNegative());165 166      t = a.IAND(b);167      MATCH(x & y, t.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);168      t = a.IOR(b);169      MATCH(x | y, t.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);170      t = a.IEOR(b);171      MATCH(x ^ y, t.ToUInt64())("%s, x=0x%llx, y=0x%llx", desc, x, y);172      auto sum{a.AddUnsigned(b)};173      COMPARE(174          x + y, ==, sum.value.ToUInt64() + (std::uint64_t{sum.carry} << BITS))175      ("%s, x=0x%llx, y=0x%llx, carry=%d", desc, x, y, sum.carry);176      auto ssum{a.AddSigned(b)};177      MATCH((sx + sy) & maxUnsignedValue, ssum.value.ToUInt64())178      ("%s, x=0x%llx, y=0x%llx", desc, x, y);179      MATCH(180          sx + sy < mostNegativeSignedValue || sx + sy > maxPositiveSignedValue,181          ssum.overflow)182      ("%s, x=0x%llx, y=0x%llx", desc, x, y);183      auto diff{a.SubtractSigned(b)};184      MATCH((sx - sy) & maxUnsignedValue, diff.value.ToUInt64())185      ("%s, x=0x%llx, y=0x%llx", desc, x, y);186      MATCH(187          sx - sy < mostNegativeSignedValue || sx - sy > maxPositiveSignedValue,188          diff.overflow)189      ("%s, x=0x%llx, y=0x%llx", desc, x, y);190      auto product{a.MultiplyUnsigned(b)};191      MATCH(192          x * y, (product.upper.ToUInt64() << BITS) ^ product.lower.ToUInt64())193      ("%s, x=0x%llx, y=0x%llx, lower=0x%llx, upper=0x%llx", desc, x, y,194          product.lower.ToUInt64(), product.upper.ToUInt64());195      product = a.MultiplySigned(b);196      MATCH((sx * sy) & maxUnsignedValue, product.lower.ToUInt64())197      ("%s, x=0x%llx, y=0x%llx", desc, x, y);198      MATCH(((sx * sy) >> BITS) & maxUnsignedValue, product.upper.ToUInt64())199      ("%s, x=0x%llx, y=0x%llx", desc, x, y);200      auto quot{a.DivideUnsigned(b)};201      MATCH(y == 0, quot.divisionByZero)("%s, x=0x%llx, y=0x%llx", desc, x, y);202      if (y == 0) {203        MATCH(maxUnsignedValue, quot.quotient.ToUInt64())204        ("%s, x=0x%llx, y=0x%llx", desc, x, y);205        MATCH(0, quot.remainder.ToUInt64())206        ("%s, x=0x%llx, y=0x%llx", desc, x, y);207      } else {208        MATCH(x / y, quot.quotient.ToUInt64())209        ("%s, x=0x%llx, y=0x%llx", desc, x, y);210        MATCH(x % y, quot.remainder.ToUInt64())211        ("%s, x=0x%llx, y=0x%llx", desc, x, y);212      }213      quot = a.DivideSigned(b);214      bool badCase{sx == mostNegativeSignedValue &&215          ((sy == -1 && sx != sy) || (BITS == 1 && sx == sy))};216      MATCH(y == 0, quot.divisionByZero)("%s, x=0x%llx, y=0x%llx", desc, x, y);217      MATCH(badCase, quot.overflow)("%s, x=0x%llx, y=0x%llx", desc, x, y);218      if (y == 0) {219        if (sx >= 0) {220          MATCH(maxPositiveSignedValue, quot.quotient.ToInt64())221          ("%s, x=0x%llx, y=0x%llx", desc, x, y);222        } else {223          MATCH(mostNegativeSignedValue, quot.quotient.ToInt64())224          ("%s, x=0x%llx, y=0x%llx", desc, x, y);225        }226        MATCH(0, quot.remainder.ToUInt64())227        ("%s, x=0x%llx, y=0x%llx", desc, x, y);228      } else if (badCase) {229        MATCH(x, quot.quotient.ToUInt64())230        ("%s, x=0x%llx, y=0x%llx", desc, x, y);231        MATCH(0, quot.remainder.ToUInt64())232        ("%s, x=0x%llx, y=0x%llx", desc, x, y);233      } else {234        MATCH(sx / sy, quot.quotient.ToInt64())235        ("%s, x=0x%llx %lld, y=0x%llx %lld; unsigned 0x%llx", desc, x, sx, y,236            sy, quot.quotient.ToUInt64());237        MATCH(sx - sy * (sx / sy), quot.remainder.ToInt64())238        ("%s, x=0x%llx, y=0x%llx", desc, x, y);239      }240    }241  }242}243 244int main() {245  TEST(Reverse(Ordering::Less) == Ordering::Greater);246  TEST(Reverse(Ordering::Greater) == Ordering::Less);247  TEST(Reverse(Ordering::Equal) == Ordering::Equal);248  TEST(Integer<128>{123456789}.UnsignedDecimal() == "123456789");249  TEST(Integer<128>{123456789}.SignedDecimal() == "123456789");250  TEST(Integer<128>{-123456789}.SignedDecimal() == "-123456789");251  std::uint64_t big{0x123456789abcdef};252  TEST(Integer<128>{big}.Hexadecimal() == "123456789abcdef");253  exhaustiveTesting<1>();254  exhaustiveTesting<2>();255  exhaustiveTesting<7>();256  exhaustiveTesting<8>();257  exhaustiveTesting<9>();258  exhaustiveTesting<9, Integer<9, true, 1>>();259  exhaustiveTesting<9, Integer<9, true, 1, std::uint8_t, std::uint16_t>>();260  exhaustiveTesting<9, Integer<9, true, 2>>();261  exhaustiveTesting<9, Integer<9, true, 2, std::uint8_t, std::uint16_t>>();262  exhaustiveTesting<9, Integer<9, true, 8, std::uint8_t, std::uint16_t>>();263  exhaustiveTesting<9, Integer<9, false, 8, std::uint8_t, std::uint16_t>>();264  return testing::Complete();265}266