21#ifndef LLVM_SUPPORT_SCALEDNUMBER_H 
   22#define LLVM_SUPPORT_SCALEDNUMBER_H 
   43template <
class DigitsT> 
inline int getWidth() { 
return sizeof(DigitsT) * 8; }
 
   52template <
class DigitsT>
 
   53inline std::pair<DigitsT, int16_t> 
getRounded(DigitsT Digits, int16_t Scale,
 
   55  static_assert(!std::numeric_limits<DigitsT>::is_signed, 
"expected unsigned");
 
   61  return {Digits, Scale};
 
 
   79template <
class DigitsT>
 
   82  static_assert(!std::numeric_limits<DigitsT>::is_signed, 
"expected unsigned");
 
   85  if (Width == 64 || Digits <= std::numeric_limits<DigitsT>::max())
 
   86    return {Digits, Scale};
 
   91                             Digits & (UINT64_C(1) << (Shift - 1)));
 
 
  114template <
class DigitsT>
 
  116  static_assert(!std::numeric_limits<DigitsT>::is_signed, 
"expected unsigned");
 
 
  155template <
class DigitsT>
 
  156std::pair<DigitsT, int16_t> 
getQuotient(DigitsT Dividend, DigitsT Divisor) {
 
  157  static_assert(!std::numeric_limits<DigitsT>::is_signed, 
"expected unsigned");
 
  158  static_assert(
sizeof(DigitsT) == 4 || 
sizeof(DigitsT) == 8,
 
  159                "expected 32-bit or 64-bit digits");
 
  165    return {std::numeric_limits<DigitsT>::max(), 
MaxScale};
 
 
  190template <
class DigitsT>
 
  191inline std::pair<int32_t, int> 
getLgImpl(DigitsT Digits, int16_t Scale) {
 
  192  static_assert(!std::numeric_limits<DigitsT>::is_signed, 
"expected unsigned");
 
  195    return {INT32_MIN, 0};
 
  198  static_assert(
sizeof(Digits) <= 
sizeof(
uint64_t));
 
  202  int32_t Floor = Scale + LocalFloor;
 
  203  if (Digits == UINT64_C(1) << LocalFloor)
 
  208  bool Round = Digits & UINT64_C(1) << (LocalFloor - 1);
 
  209  return {Floor + Round, Round ? 1 : -1};
 
 
  217template <
class DigitsT> int32_t 
getLg(DigitsT Digits, int16_t Scale) {
 
 
  226template <
class DigitsT> int32_t 
getLgFloor(DigitsT Digits, int16_t Scale) {
 
  228  return Lg.first - (Lg.second > 0);
 
 
  236template <
class DigitsT> int32_t 
getLgCeiling(DigitsT Digits, int16_t Scale) {
 
  238  return Lg.first + (Lg.second < 0);
 
 
  254template <
class DigitsT>
 
  255int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale) {
 
  256  static_assert(!std::numeric_limits<DigitsT>::is_signed, 
"expected unsigned");
 
  260    return RDigits ? -1 : 0;
 
  268    return lgL < lgR ? -1 : 1;
 
  272    return compareImpl(LDigits, RDigits, RScale - LScale);
 
  274  return -
compareImpl(RDigits, LDigits, LScale - RScale);
 
 
  289template <
class DigitsT>
 
  290int16_t 
matchScales(DigitsT &LDigits, int16_t &LScale, DigitsT &RDigits,
 
  292  static_assert(!std::numeric_limits<DigitsT>::is_signed, 
"expected unsigned");
 
  296    return matchScales(RDigits, RScale, LDigits, LScale);
 
  299  if (!RDigits || LScale == RScale)
 
  303  int32_t ScaleDiff = int32_t(LScale) - RScale;
 
  314  int32_t ShiftR = ScaleDiff - ShiftL;
 
  326  assert(LScale == RScale && 
"scales should match");
 
 
  335template <
class DigitsT>
 
  336std::pair<DigitsT, int16_t> 
getSum(DigitsT LDigits, int16_t LScale,
 
  337                                   DigitsT RDigits, int16_t RScale) {
 
  338  static_assert(!std::numeric_limits<DigitsT>::is_signed, 
"expected unsigned");
 
  342  assert(LScale < INT16_MAX && 
"scale too large");
 
  343  assert(RScale < INT16_MAX && 
"scale too large");
 
  346  int16_t Scale = 
matchScales(LDigits, LScale, RDigits, RScale);
 
  349  DigitsT Sum = LDigits + RDigits;
 
  355  return {HighBit | Sum >> 1, Scale + 1};
 
 
  361  return getSum(LDigits, LScale, RDigits, RScale);
 
 
  367  return getSum(LDigits, LScale, RDigits, RScale);
 
 
  375template <
class DigitsT>
 
  377                                          DigitsT RDigits, int16_t RScale) {
 
  378  static_assert(!std::numeric_limits<DigitsT>::is_signed, 
"expected unsigned");
 
  381  const DigitsT SavedRDigits = RDigits;
 
  382  const int16_t SavedRScale = RScale;
 
  386  if (LDigits <= RDigits)
 
  388  if (RDigits || !SavedRDigits)
 
  389    return {LDigits - RDigits, LScale};
 
  394  const auto RLgFloor = 
getLgFloor(SavedRDigits, SavedRScale);
 
  396    return {std::numeric_limits<DigitsT>::max(), RLgFloor};
 
  398  return {LDigits, LScale};
 
 
 
  429                                     int Width, 
unsigned Precision);
 
  445    return IsNeg ? -int64_t(U) : int64_t(U);
 
 
 
  498  static_assert(!std::numeric_limits<DigitsT>::is_signed,
 
  499                "only unsigned floats supported");
 
  504  using DigitsLimits = std::numeric_limits<DigitsType>;
 
  506  static constexpr int Width = 
sizeof(
DigitsType) * 8;
 
  507  static_assert(Width <= 64, 
"invalid integer width for digits");
 
  517      : Digits(Digits), Scale(Scale) {}
 
 
  521      : Digits(
X.first), Scale(
X.second) {}
 
  534    return getQuotient(
N, 
D);
 
 
  544  template <
class IntT> IntT 
toInt() 
const;
 
  549    if (Scale > 0 || Scale <= -Width)
 
 
  613    std::tie(Digits, Scale) =
 
 
  621    std::tie(Digits, Scale) =
 
 
  637  void shiftLeft(int32_t Shift);
 
  691  static int countLeadingZerosWidth(
DigitsType Digits) {
 
  704  static ScaledNumber adjustToWidth(uint64_t 
N, int32_t Shift) {
 
  707           "Shift should be close to 0");
 
 
  721#define SCALED_NUMBER_BOP(op, base)                                            \ 
  722  template <class DigitsT>                                                     \ 
  723  ScaledNumber<DigitsT> operator op(const ScaledNumber<DigitsT> &L,            \ 
  724                                    const ScaledNumber<DigitsT> &R) {          \ 
  725    return ScaledNumber<DigitsT>(L) base R;                                    \ 
 
  731#undef SCALED_NUMBER_BOP 
  733template <
class DigitsT>
 
  734ScaledNumber<DigitsT> 
operator<<(
const ScaledNumber<DigitsT> &L,
 
  736  return ScaledNumber<DigitsT>(L) <<= Shift;
 
  739template <
class DigitsT>
 
  745template <
class DigitsT>
 
  747  return X.print(OS, 10);
 
 
  750#define SCALED_NUMBER_COMPARE_TO_TYPE(op, T1, T2)                              \ 
  751  template <class DigitsT>                                                     \ 
  752  bool operator op(const ScaledNumber<DigitsT> &L, T1 R) {                     \ 
  753    return L.compareTo(T2(R)) op 0;                                            \ 
  755  template <class DigitsT>                                                     \ 
  756  bool operator op(T1 L, const ScaledNumber<DigitsT> &R) {                     \ 
  757    return 0 op R.compareTo(T2(L));                                            \ 
 
  759#define SCALED_NUMBER_COMPARE_TO(op)                                           \ 
  760  SCALED_NUMBER_COMPARE_TO_TYPE(op, uint64_t, uint64_t)                        \ 
  761  SCALED_NUMBER_COMPARE_TO_TYPE(op, uint32_t, uint64_t)                        \ 
  762  SCALED_NUMBER_COMPARE_TO_TYPE(op, int64_t, int64_t)                          \ 
  763  SCALED_NUMBER_COMPARE_TO_TYPE(op, int32_t, int64_t) 
 
  770#undef SCALED_NUMBER_COMPARE_TO 
  771#undef SCALED_NUMBER_COMPARE_TO_TYPE 
  773template <
class DigitsT>
 
  775  if (Width == 64 || 
N <= DigitsLimits::max())
 
 
  782template <
class DigitsT>
 
  785  using Limits = std::numeric_limits<IntT>;
 
  788  if (*
this >= Limits::max())
 
  789    return Limits::max();
 
  793    assert(
size_t(Scale) < 
sizeof(IntT) * 8);
 
  797    assert(
size_t(-Scale) < 
sizeof(IntT) * 8);
 
 
  803template <
class DigitsT>
 
  812  int32_t Scales = int32_t(Scale) + int32_t(
X.Scale);
 
  815  *
this = getProduct(Digits, 
X.Digits);
 
  818  return *
this <<= Scales;
 
 
  820template <
class DigitsT>
 
  829  int32_t Scales = int32_t(Scale) - int32_t(
X.Scale);
 
  832  *
this = getQuotient(Digits, 
X.Digits);
 
  835  return *
this <<= Scales;
 
 
  837template <
class DigitsT> 
void ScaledNumber<DigitsT>::shiftLeft(int32_t Shift) {
 
  840  assert(Shift != INT32_MIN);
 
  849  if (ScaleShift == Shift)
 
  858  if (Shift > countLeadingZerosWidth(Digits)) {
 
  860    *
this = getLargest();
 
  867template <
class DigitsT> 
void ScaledNumber<DigitsT>::shiftRight(int32_t Shift) {
 
  870  assert(Shift != INT32_MIN);
 
  879  if (ScaleShift == Shift)
 
  884  if (Shift >= Width) {
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
 
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
 
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
 
#define SCALED_NUMBER_BOP(op, base)
 
#define SCALED_NUMBER_COMPARE_TO(op)
 
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
 
static int countLeadingZeros64(uint64_t N)
 
static int countLeadingZeros32(uint32_t N)
 
static constexpr int DefaultPrecision
 
static int64_t joinSigned(uint64_t U, bool IsNeg)
 
static LLVM_ABI raw_ostream & print(raw_ostream &OS, uint64_t D, int16_t E, int Width, unsigned Precision)
 
static LLVM_ABI std::string toString(uint64_t D, int16_t E, int Width, unsigned Precision)
 
static LLVM_ABI void dump(uint64_t D, int16_t E, int Width)
 
static uint64_t getHalf(uint64_t N)
 
static std::pair< uint64_t, bool > splitSigned(int64_t N)
 
Simple representation of a scaled number.
 
bool operator!=(const ScaledNumber &X) const
 
raw_ostream & print(raw_ostream &OS, unsigned Precision=DefaultPrecision) const
Print a decimal representation.
 
ScaledNumber & operator*=(const ScaledNumber &X)
 
static ScaledNumber getLargest()
 
ScaledNumber & operator/=(const ScaledNumber &X)
 
ScaledNumber & operator<<=(int16_t Shift)
 
int32_t lgFloor() const
The log base 2, rounded towards INT32_MIN.
 
ScaledNumber inverse() const
 
bool operator<=(const ScaledNumber &X) const
 
ScaledNumber & operator+=(const ScaledNumber &X)
 
bool operator==(const ScaledNumber &X) const
 
int compare(const ScaledNumber &X) const
 
std::string toString(unsigned Precision=DefaultPrecision)
Convert to a decimal representation in a string.
 
static ScaledNumber get(uint64_t N)
 
static ScaledNumber getZero()
 
DigitsType getDigits() const
 
static ScaledNumber getOne()
 
uint64_t scale(uint64_t N) const
Scale a large number accurately.
 
bool operator>(const ScaledNumber &X) const
 
ScaledNumber & operator>>=(int16_t Shift)
 
static ScaledNumber getFraction(DigitsType N, DigitsType D)
 
int64_t scaleByInverse(int64_t N) const
 
constexpr ScaledNumber(DigitsType Digits, int16_t Scale)
 
int32_t lgCeiling() const
The log base 2, rounded towards INT32_MAX.
 
uint64_t scaleByInverse(uint64_t N) const
 
bool operator<(const ScaledNumber &X) const
 
bool operator>=(const ScaledNumber &X) const
 
int32_t lg() const
The log base 2, rounded.
 
int compareTo(uint64_t N) const
 
static ScaledNumber getInverse(uint64_t N)
 
IntT toInt() const
Convert to the given integer type.
 
ScaledNumber & operator-=(const ScaledNumber &X)
 
int64_t scale(int64_t N) const
 
int compareTo(int64_t N) const
 
This class implements an extremely fast bulk output stream that can only output to a stream.
 
int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale)
Compare two scaled numbers.
 
LLVM_ABI std::pair< uint64_t, int16_t > divide64(uint64_t Dividend, uint64_t Divisor)
Divide two 64-bit integers to create a 64-bit scaled number.
 
int32_t getLgFloor(DigitsT Digits, int16_t Scale)
Get the lg floor of a scaled number.
 
LLVM_ABI std::pair< uint64_t, int16_t > multiply64(uint64_t LHS, uint64_t RHS)
Multiply two 64-bit integers to create a 64-bit scaled number.
 
std::pair< DigitsT, int16_t > getSum(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale)
Get the sum of two scaled numbers.
 
std::pair< uint32_t, int16_t > getAdjusted32(uint64_t Digits, int16_t Scale=0)
Convenience helper for adjusting to 32 bits.
 
const int32_t MinScale
Maximum scale; same as APFloat for easy debug printing.
 
std::pair< DigitsT, int16_t > getAdjusted(uint64_t Digits, int16_t Scale=0)
Adjust a 64-bit scaled number down to the appropriate width.
 
std::pair< uint64_t, int16_t > getAdjusted64(uint64_t Digits, int16_t Scale=0)
Convenience helper for adjusting to 64 bits.
 
std::pair< uint32_t, int16_t > getQuotient32(uint32_t Dividend, uint32_t Divisor)
Convenience helper for 32-bit quotient.
 
std::pair< int32_t, int > getLgImpl(DigitsT Digits, int16_t Scale)
Implementation of getLg() and friends.
 
std::pair< uint32_t, int16_t > getSum32(uint32_t LDigits, int16_t LScale, uint32_t RDigits, int16_t RScale)
Convenience helper for 32-bit sum.
 
std::pair< DigitsT, int16_t > getProduct(DigitsT LHS, DigitsT RHS)
Multiply two 32-bit integers to create a 32-bit scaled number.
 
std::pair< DigitsT, int16_t > getRounded(DigitsT Digits, int16_t Scale, bool ShouldRound)
Conditionally round up a scaled number.
 
std::pair< uint32_t, int16_t > getDifference32(uint32_t LDigits, int16_t LScale, uint32_t RDigits, int16_t RScale)
Convenience helper for 32-bit difference.
 
std::pair< uint64_t, int16_t > getQuotient64(uint64_t Dividend, uint64_t Divisor)
Convenience helper for 64-bit quotient.
 
std::pair< uint32_t, int16_t > getRounded32(uint32_t Digits, int16_t Scale, bool ShouldRound)
Convenience helper for 32-bit rounding.
 
int16_t matchScales(DigitsT &LDigits, int16_t &LScale, DigitsT &RDigits, int16_t &RScale)
Match scales of two numbers.
 
LLVM_ABI std::pair< uint32_t, int16_t > divide32(uint32_t Dividend, uint32_t Divisor)
Divide two 32-bit integers to create a 32-bit scaled number.
 
const int32_t MaxScale
Maximum scale; same as APFloat for easy debug printing.
 
std::pair< uint32_t, int16_t > getProduct32(uint32_t LHS, uint32_t RHS)
Convenience helper for 32-bit product.
 
int32_t getLg(DigitsT Digits, int16_t Scale)
Get the lg (rounded) of a scaled number.
 
std::pair< uint64_t, int16_t > getSum64(uint64_t LDigits, int16_t LScale, uint64_t RDigits, int16_t RScale)
Convenience helper for 64-bit sum.
 
std::pair< DigitsT, int16_t > getDifference(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale)
Get the difference of two scaled numbers.
 
std::pair< DigitsT, int16_t > getQuotient(DigitsT Dividend, DigitsT Divisor)
Divide two 32-bit numbers to create a 32-bit scaled number.
 
LLVM_ABI int compareImpl(uint64_t L, uint64_t R, int ScaleDiff)
Implementation for comparing scaled numbers.
 
int getWidth()
Get the width of a number.
 
std::pair< uint64_t, int16_t > getDifference64(uint64_t LDigits, int16_t LScale, uint64_t RDigits, int16_t RScale)
Convenience helper for 64-bit difference.
 
int32_t getLgCeiling(DigitsT Digits, int16_t Scale)
Get the lg ceiling of a scaled number.
 
std::pair< uint64_t, int16_t > getRounded64(uint64_t Digits, int16_t Scale, bool ShouldRound)
Convenience helper for 64-bit rounding.
 
std::pair< uint64_t, int16_t > getProduct64(uint64_t LHS, uint64_t RHS)
Convenience helper for 64-bit product.
 
This is an optimization pass for GlobalISel generic memory operations.
 
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
 
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
 
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
 
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
 
static lostFraction shiftRight(APFloatBase::integerPart *dst, unsigned int parts, unsigned int bits)
 
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
 
ScaledNumber< DigitsT > operator>>(const ScaledNumber< DigitsT > &L, int16_t Shift)