File indexing completed on 2026-05-10 08:43:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_ADT_APFLOAT_H
0016 #define LLVM_ADT_APFLOAT_H
0017
0018 #include "llvm/ADT/APInt.h"
0019 #include "llvm/ADT/ArrayRef.h"
0020 #include "llvm/ADT/FloatingPointMode.h"
0021 #include "llvm/Support/ErrorHandling.h"
0022 #include "llvm/Support/float128.h"
0023 #include <memory>
0024
0025 #define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL) \
0026 do { \
0027 if (usesLayout<IEEEFloat>(getSemantics())) \
0028 return U.IEEE.METHOD_CALL; \
0029 if (usesLayout<DoubleAPFloat>(getSemantics())) \
0030 return U.Double.METHOD_CALL; \
0031 llvm_unreachable("Unexpected semantics"); \
0032 } while (false)
0033
0034 namespace llvm {
0035
0036 struct fltSemantics;
0037 class APSInt;
0038 class StringRef;
0039 class APFloat;
0040 class raw_ostream;
0041
0042 template <typename T> class Expected;
0043 template <typename T> class SmallVectorImpl;
0044
0045
0046
0047
0048
0049 enum lostFraction {
0050 lfExactlyZero,
0051 lfLessThanHalf,
0052 lfExactlyHalf,
0053 lfMoreThanHalf
0054 };
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143 struct APFloatBase {
0144 typedef APInt::WordType integerPart;
0145 static constexpr unsigned integerPartWidth = APInt::APINT_BITS_PER_WORD;
0146
0147
0148 typedef int32_t ExponentType;
0149
0150
0151
0152 enum Semantics {
0153 S_IEEEhalf,
0154 S_BFloat,
0155 S_IEEEsingle,
0156 S_IEEEdouble,
0157 S_IEEEquad,
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167 S_PPCDoubleDouble,
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192 S_PPCDoubleDoubleLegacy,
0193
0194
0195 S_Float8E5M2,
0196
0197
0198
0199
0200
0201
0202 S_Float8E5M2FNUZ,
0203
0204
0205 S_Float8E4M3,
0206
0207
0208
0209
0210 S_Float8E4M3FN,
0211
0212
0213
0214
0215
0216
0217 S_Float8E4M3FNUZ,
0218
0219
0220
0221
0222
0223
0224 S_Float8E4M3B11FNUZ,
0225
0226
0227 S_Float8E3M4,
0228
0229
0230
0231 S_FloatTF32,
0232
0233
0234
0235
0236
0237
0238 S_Float8E8M0FNU,
0239
0240
0241
0242 S_Float6E3M2FN,
0243
0244
0245
0246 S_Float6E2M3FN,
0247
0248
0249
0250 S_Float4E2M1FN,
0251
0252 S_x87DoubleExtended,
0253 S_MaxSemantics = S_x87DoubleExtended,
0254 };
0255
0256 static const llvm::fltSemantics &EnumToSemantics(Semantics S);
0257 static Semantics SemanticsToEnum(const llvm::fltSemantics &Sem);
0258
0259 static const fltSemantics &IEEEhalf() LLVM_READNONE;
0260 static const fltSemantics &BFloat() LLVM_READNONE;
0261 static const fltSemantics &IEEEsingle() LLVM_READNONE;
0262 static const fltSemantics &IEEEdouble() LLVM_READNONE;
0263 static const fltSemantics &IEEEquad() LLVM_READNONE;
0264 static const fltSemantics &PPCDoubleDouble() LLVM_READNONE;
0265 static const fltSemantics &PPCDoubleDoubleLegacy() LLVM_READNONE;
0266 static const fltSemantics &Float8E5M2() LLVM_READNONE;
0267 static const fltSemantics &Float8E5M2FNUZ() LLVM_READNONE;
0268 static const fltSemantics &Float8E4M3() LLVM_READNONE;
0269 static const fltSemantics &Float8E4M3FN() LLVM_READNONE;
0270 static const fltSemantics &Float8E4M3FNUZ() LLVM_READNONE;
0271 static const fltSemantics &Float8E4M3B11FNUZ() LLVM_READNONE;
0272 static const fltSemantics &Float8E3M4() LLVM_READNONE;
0273 static const fltSemantics &FloatTF32() LLVM_READNONE;
0274 static const fltSemantics &Float8E8M0FNU() LLVM_READNONE;
0275 static const fltSemantics &Float6E3M2FN() LLVM_READNONE;
0276 static const fltSemantics &Float6E2M3FN() LLVM_READNONE;
0277 static const fltSemantics &Float4E2M1FN() LLVM_READNONE;
0278 static const fltSemantics &x87DoubleExtended() LLVM_READNONE;
0279
0280
0281
0282 static const fltSemantics &Bogus() LLVM_READNONE;
0283
0284
0285
0286
0287 static bool isRepresentableBy(const fltSemantics &A, const fltSemantics &B);
0288
0289
0290
0291
0292 enum cmpResult {
0293 cmpLessThan,
0294 cmpEqual,
0295 cmpGreaterThan,
0296 cmpUnordered
0297 };
0298
0299
0300 using roundingMode = llvm::RoundingMode;
0301
0302 static constexpr roundingMode rmNearestTiesToEven =
0303 RoundingMode::NearestTiesToEven;
0304 static constexpr roundingMode rmTowardPositive = RoundingMode::TowardPositive;
0305 static constexpr roundingMode rmTowardNegative = RoundingMode::TowardNegative;
0306 static constexpr roundingMode rmTowardZero = RoundingMode::TowardZero;
0307 static constexpr roundingMode rmNearestTiesToAway =
0308 RoundingMode::NearestTiesToAway;
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318 enum opStatus {
0319 opOK = 0x00,
0320 opInvalidOp = 0x01,
0321 opDivByZero = 0x02,
0322 opOverflow = 0x04,
0323 opUnderflow = 0x08,
0324 opInexact = 0x10
0325 };
0326
0327
0328 enum fltCategory {
0329 fcInfinity,
0330 fcNaN,
0331 fcNormal,
0332 fcZero
0333 };
0334
0335
0336 enum uninitializedTag {
0337 uninitialized
0338 };
0339
0340
0341 enum IlogbErrorKinds {
0342 IEK_Zero = INT_MIN + 1,
0343 IEK_NaN = INT_MIN,
0344 IEK_Inf = INT_MAX
0345 };
0346
0347 static unsigned int semanticsPrecision(const fltSemantics &);
0348 static ExponentType semanticsMinExponent(const fltSemantics &);
0349 static ExponentType semanticsMaxExponent(const fltSemantics &);
0350 static unsigned int semanticsSizeInBits(const fltSemantics &);
0351 static unsigned int semanticsIntSizeInBits(const fltSemantics&, bool);
0352 static bool semanticsHasZero(const fltSemantics &);
0353 static bool semanticsHasSignedRepr(const fltSemantics &);
0354 static bool semanticsHasInf(const fltSemantics &);
0355 static bool semanticsHasNaN(const fltSemantics &);
0356 static bool isIEEELikeFP(const fltSemantics &);
0357
0358
0359
0360 static bool isRepresentableAsNormalIn(const fltSemantics &Src,
0361 const fltSemantics &Dst);
0362
0363
0364
0365 static unsigned getSizeInBits(const fltSemantics &Sem);
0366 };
0367
0368 namespace detail {
0369
0370 using integerPart = APFloatBase::integerPart;
0371 using uninitializedTag = APFloatBase::uninitializedTag;
0372 using roundingMode = APFloatBase::roundingMode;
0373 using opStatus = APFloatBase::opStatus;
0374 using cmpResult = APFloatBase::cmpResult;
0375 using fltCategory = APFloatBase::fltCategory;
0376 using ExponentType = APFloatBase::ExponentType;
0377 static constexpr uninitializedTag uninitialized = APFloatBase::uninitialized;
0378 static constexpr roundingMode rmNearestTiesToEven =
0379 APFloatBase::rmNearestTiesToEven;
0380 static constexpr roundingMode rmNearestTiesToAway =
0381 APFloatBase::rmNearestTiesToAway;
0382 static constexpr roundingMode rmTowardNegative = APFloatBase::rmTowardNegative;
0383 static constexpr roundingMode rmTowardPositive = APFloatBase::rmTowardPositive;
0384 static constexpr roundingMode rmTowardZero = APFloatBase::rmTowardZero;
0385 static constexpr unsigned integerPartWidth = APFloatBase::integerPartWidth;
0386 static constexpr cmpResult cmpEqual = APFloatBase::cmpEqual;
0387 static constexpr cmpResult cmpLessThan = APFloatBase::cmpLessThan;
0388 static constexpr cmpResult cmpGreaterThan = APFloatBase::cmpGreaterThan;
0389 static constexpr cmpResult cmpUnordered = APFloatBase::cmpUnordered;
0390 static constexpr opStatus opOK = APFloatBase::opOK;
0391 static constexpr opStatus opInvalidOp = APFloatBase::opInvalidOp;
0392 static constexpr opStatus opDivByZero = APFloatBase::opDivByZero;
0393 static constexpr opStatus opOverflow = APFloatBase::opOverflow;
0394 static constexpr opStatus opUnderflow = APFloatBase::opUnderflow;
0395 static constexpr opStatus opInexact = APFloatBase::opInexact;
0396 static constexpr fltCategory fcInfinity = APFloatBase::fcInfinity;
0397 static constexpr fltCategory fcNaN = APFloatBase::fcNaN;
0398 static constexpr fltCategory fcNormal = APFloatBase::fcNormal;
0399 static constexpr fltCategory fcZero = APFloatBase::fcZero;
0400
0401 class IEEEFloat final {
0402 public:
0403
0404
0405
0406 IEEEFloat(const fltSemantics &);
0407 IEEEFloat(const fltSemantics &, integerPart);
0408 IEEEFloat(const fltSemantics &, uninitializedTag);
0409 IEEEFloat(const fltSemantics &, const APInt &);
0410 explicit IEEEFloat(double d);
0411 explicit IEEEFloat(float f);
0412 IEEEFloat(const IEEEFloat &);
0413 IEEEFloat(IEEEFloat &&);
0414 ~IEEEFloat();
0415
0416
0417
0418
0419 bool needsCleanup() const { return partCount() > 1; }
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429 opStatus add(const IEEEFloat &, roundingMode);
0430 opStatus subtract(const IEEEFloat &, roundingMode);
0431 opStatus multiply(const IEEEFloat &, roundingMode);
0432 opStatus divide(const IEEEFloat &, roundingMode);
0433
0434 opStatus remainder(const IEEEFloat &);
0435
0436 opStatus mod(const IEEEFloat &);
0437 opStatus fusedMultiplyAdd(const IEEEFloat &, const IEEEFloat &, roundingMode);
0438 opStatus roundToIntegral(roundingMode);
0439
0440 opStatus next(bool nextDown);
0441
0442
0443
0444
0445
0446
0447 void changeSign();
0448
0449
0450
0451
0452
0453
0454 opStatus convert(const fltSemantics &, roundingMode, bool *);
0455 opStatus convertToInteger(MutableArrayRef<integerPart>, unsigned int, bool,
0456 roundingMode, bool *) const;
0457 opStatus convertFromAPInt(const APInt &, bool, roundingMode);
0458 opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
0459 bool, roundingMode);
0460 opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
0461 bool, roundingMode);
0462 Expected<opStatus> convertFromString(StringRef, roundingMode);
0463 APInt bitcastToAPInt() const;
0464 double convertToDouble() const;
0465 #ifdef HAS_IEE754_FLOAT128
0466 float128 convertToQuad() const;
0467 #endif
0468 float convertToFloat() const;
0469
0470
0471
0472
0473
0474
0475 bool operator==(const IEEEFloat &) const = delete;
0476
0477
0478
0479 cmpResult compare(const IEEEFloat &) const;
0480
0481
0482 bool bitwiseIsEqual(const IEEEFloat &) const;
0483
0484
0485
0486
0487 unsigned int convertToHexString(char *dst, unsigned int hexDigits,
0488 bool upperCase, roundingMode) const;
0489
0490
0491
0492
0493
0494
0495
0496
0497 bool isNegative() const { return sign; }
0498
0499
0500
0501
0502
0503 bool isNormal() const { return !isDenormal() && isFiniteNonZero(); }
0504
0505
0506
0507
0508
0509 bool isFinite() const { return !isNaN() && !isInfinity(); }
0510
0511
0512 bool isZero() const { return category == fltCategory::fcZero; }
0513
0514
0515
0516 bool isDenormal() const;
0517
0518
0519 bool isInfinity() const { return category == fcInfinity; }
0520
0521
0522 bool isNaN() const { return category == fcNaN; }
0523
0524
0525 bool isSignaling() const;
0526
0527
0528
0529
0530
0531
0532 fltCategory getCategory() const { return category; }
0533 const fltSemantics &getSemantics() const { return *semantics; }
0534 bool isNonZero() const { return category != fltCategory::fcZero; }
0535 bool isFiniteNonZero() const { return isFinite() && !isZero(); }
0536 bool isPosZero() const { return isZero() && !isNegative(); }
0537 bool isNegZero() const { return isZero() && isNegative(); }
0538
0539
0540
0541 bool isSmallest() const;
0542
0543
0544
0545 bool isSmallestNormalized() const;
0546
0547
0548
0549 bool isLargest() const;
0550
0551
0552 bool isInteger() const;
0553
0554
0555
0556 IEEEFloat &operator=(const IEEEFloat &);
0557 IEEEFloat &operator=(IEEEFloat &&);
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568 friend hash_code hash_value(const IEEEFloat &Arg);
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596 void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
0597 unsigned FormatMaxPadding = 3, bool TruncateZero = true) const;
0598
0599
0600
0601 bool getExactInverse(APFloat *inv) const;
0602
0603
0604
0605 LLVM_READONLY
0606 int getExactLog2Abs() const;
0607
0608
0609
0610 LLVM_READONLY
0611 int getExactLog2() const {
0612 return isNegative() ? INT_MIN : getExactLog2Abs();
0613 }
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624 friend int ilogb(const IEEEFloat &Arg);
0625
0626
0627 friend IEEEFloat scalbn(IEEEFloat X, int Exp, roundingMode);
0628
0629 friend IEEEFloat frexp(const IEEEFloat &X, int &Exp, roundingMode);
0630
0631
0632
0633
0634 void makeLargest(bool Neg = false);
0635 void makeSmallest(bool Neg = false);
0636 void makeNaN(bool SNaN = false, bool Neg = false,
0637 const APInt *fill = nullptr);
0638 void makeInf(bool Neg = false);
0639 void makeZero(bool Neg = false);
0640 void makeQuiet();
0641
0642
0643
0644
0645
0646 void makeSmallestNormalized(bool Negative = false);
0647
0648
0649
0650 cmpResult compareAbsoluteValue(const IEEEFloat &) const;
0651
0652 private:
0653
0654
0655
0656 integerPart *significandParts();
0657 const integerPart *significandParts() const;
0658 unsigned int partCount() const;
0659
0660
0661
0662
0663
0664
0665 integerPart addSignificand(const IEEEFloat &);
0666 integerPart subtractSignificand(const IEEEFloat &, integerPart);
0667 lostFraction addOrSubtractSignificand(const IEEEFloat &, bool subtract);
0668 lostFraction multiplySignificand(const IEEEFloat &, IEEEFloat,
0669 bool ignoreAddend = false);
0670 lostFraction multiplySignificand(const IEEEFloat&);
0671 lostFraction divideSignificand(const IEEEFloat &);
0672 void incrementSignificand();
0673 void initialize(const fltSemantics *);
0674 void shiftSignificandLeft(unsigned int);
0675 lostFraction shiftSignificandRight(unsigned int);
0676 unsigned int significandLSB() const;
0677 unsigned int significandMSB() const;
0678 void zeroSignificand();
0679 unsigned int getNumHighBits() const;
0680
0681 bool isSignificandAllOnes() const;
0682 bool isSignificandAllOnesExceptLSB() const;
0683
0684 bool isSignificandAllZeros() const;
0685 bool isSignificandAllZerosExceptMSB() const;
0686
0687
0688
0689
0690
0691
0692 opStatus addOrSubtractSpecials(const IEEEFloat &, bool subtract);
0693 opStatus divideSpecials(const IEEEFloat &);
0694 opStatus multiplySpecials(const IEEEFloat &);
0695 opStatus modSpecials(const IEEEFloat &);
0696 opStatus remainderSpecials(const IEEEFloat&);
0697
0698
0699
0700
0701
0702
0703 bool convertFromStringSpecials(StringRef str);
0704 opStatus normalize(roundingMode, lostFraction);
0705 opStatus addOrSubtract(const IEEEFloat &, roundingMode, bool subtract);
0706 opStatus handleOverflow(roundingMode);
0707 bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
0708 opStatus convertToSignExtendedInteger(MutableArrayRef<integerPart>,
0709 unsigned int, bool, roundingMode,
0710 bool *) const;
0711 opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
0712 roundingMode);
0713 Expected<opStatus> convertFromHexadecimalString(StringRef, roundingMode);
0714 Expected<opStatus> convertFromDecimalString(StringRef, roundingMode);
0715 char *convertNormalToHexString(char *, unsigned int, bool,
0716 roundingMode) const;
0717 opStatus roundSignificandWithExponent(const integerPart *, unsigned int, int,
0718 roundingMode);
0719 ExponentType exponentNaN() const;
0720 ExponentType exponentInf() const;
0721 ExponentType exponentZero() const;
0722
0723
0724
0725 template <const fltSemantics &S> APInt convertIEEEFloatToAPInt() const;
0726 APInt convertHalfAPFloatToAPInt() const;
0727 APInt convertBFloatAPFloatToAPInt() const;
0728 APInt convertFloatAPFloatToAPInt() const;
0729 APInt convertDoubleAPFloatToAPInt() const;
0730 APInt convertQuadrupleAPFloatToAPInt() const;
0731 APInt convertF80LongDoubleAPFloatToAPInt() const;
0732 APInt convertPPCDoubleDoubleLegacyAPFloatToAPInt() const;
0733 APInt convertFloat8E5M2APFloatToAPInt() const;
0734 APInt convertFloat8E5M2FNUZAPFloatToAPInt() const;
0735 APInt convertFloat8E4M3APFloatToAPInt() const;
0736 APInt convertFloat8E4M3FNAPFloatToAPInt() const;
0737 APInt convertFloat8E4M3FNUZAPFloatToAPInt() const;
0738 APInt convertFloat8E4M3B11FNUZAPFloatToAPInt() const;
0739 APInt convertFloat8E3M4APFloatToAPInt() const;
0740 APInt convertFloatTF32APFloatToAPInt() const;
0741 APInt convertFloat8E8M0FNUAPFloatToAPInt() const;
0742 APInt convertFloat6E3M2FNAPFloatToAPInt() const;
0743 APInt convertFloat6E2M3FNAPFloatToAPInt() const;
0744 APInt convertFloat4E2M1FNAPFloatToAPInt() const;
0745 void initFromAPInt(const fltSemantics *Sem, const APInt &api);
0746 template <const fltSemantics &S> void initFromIEEEAPInt(const APInt &api);
0747 void initFromHalfAPInt(const APInt &api);
0748 void initFromBFloatAPInt(const APInt &api);
0749 void initFromFloatAPInt(const APInt &api);
0750 void initFromDoubleAPInt(const APInt &api);
0751 void initFromQuadrupleAPInt(const APInt &api);
0752 void initFromF80LongDoubleAPInt(const APInt &api);
0753 void initFromPPCDoubleDoubleLegacyAPInt(const APInt &api);
0754 void initFromFloat8E5M2APInt(const APInt &api);
0755 void initFromFloat8E5M2FNUZAPInt(const APInt &api);
0756 void initFromFloat8E4M3APInt(const APInt &api);
0757 void initFromFloat8E4M3FNAPInt(const APInt &api);
0758 void initFromFloat8E4M3FNUZAPInt(const APInt &api);
0759 void initFromFloat8E4M3B11FNUZAPInt(const APInt &api);
0760 void initFromFloat8E3M4APInt(const APInt &api);
0761 void initFromFloatTF32APInt(const APInt &api);
0762 void initFromFloat8E8M0FNUAPInt(const APInt &api);
0763 void initFromFloat6E3M2FNAPInt(const APInt &api);
0764 void initFromFloat6E2M3FNAPInt(const APInt &api);
0765 void initFromFloat4E2M1FNAPInt(const APInt &api);
0766
0767 void assign(const IEEEFloat &);
0768 void copySignificand(const IEEEFloat &);
0769 void freeSignificand();
0770
0771
0772
0773 const fltSemantics *semantics;
0774
0775
0776
0777
0778 union Significand {
0779 integerPart part;
0780 integerPart *parts;
0781 } significand;
0782
0783
0784 ExponentType exponent;
0785
0786
0787
0788
0789
0790 fltCategory category : 3;
0791
0792
0793 unsigned int sign : 1;
0794 };
0795
0796 hash_code hash_value(const IEEEFloat &Arg);
0797 int ilogb(const IEEEFloat &Arg);
0798 IEEEFloat scalbn(IEEEFloat X, int Exp, roundingMode);
0799 IEEEFloat frexp(const IEEEFloat &Val, int &Exp, roundingMode RM);
0800
0801
0802
0803
0804
0805 class DoubleAPFloat final {
0806
0807 const fltSemantics *Semantics;
0808 std::unique_ptr<APFloat[]> Floats;
0809
0810 opStatus addImpl(const APFloat &a, const APFloat &aa, const APFloat &c,
0811 const APFloat &cc, roundingMode RM);
0812
0813 opStatus addWithSpecial(const DoubleAPFloat &LHS, const DoubleAPFloat &RHS,
0814 DoubleAPFloat &Out, roundingMode RM);
0815
0816 public:
0817 DoubleAPFloat(const fltSemantics &S);
0818 DoubleAPFloat(const fltSemantics &S, uninitializedTag);
0819 DoubleAPFloat(const fltSemantics &S, integerPart);
0820 DoubleAPFloat(const fltSemantics &S, const APInt &I);
0821 DoubleAPFloat(const fltSemantics &S, APFloat &&First, APFloat &&Second);
0822 DoubleAPFloat(const DoubleAPFloat &RHS);
0823 DoubleAPFloat(DoubleAPFloat &&RHS);
0824
0825 DoubleAPFloat &operator=(const DoubleAPFloat &RHS);
0826 inline DoubleAPFloat &operator=(DoubleAPFloat &&RHS);
0827
0828 bool needsCleanup() const { return Floats != nullptr; }
0829
0830 inline APFloat &getFirst();
0831 inline const APFloat &getFirst() const;
0832 inline APFloat &getSecond();
0833 inline const APFloat &getSecond() const;
0834
0835 opStatus add(const DoubleAPFloat &RHS, roundingMode RM);
0836 opStatus subtract(const DoubleAPFloat &RHS, roundingMode RM);
0837 opStatus multiply(const DoubleAPFloat &RHS, roundingMode RM);
0838 opStatus divide(const DoubleAPFloat &RHS, roundingMode RM);
0839 opStatus remainder(const DoubleAPFloat &RHS);
0840 opStatus mod(const DoubleAPFloat &RHS);
0841 opStatus fusedMultiplyAdd(const DoubleAPFloat &Multiplicand,
0842 const DoubleAPFloat &Addend, roundingMode RM);
0843 opStatus roundToIntegral(roundingMode RM);
0844 void changeSign();
0845 cmpResult compareAbsoluteValue(const DoubleAPFloat &RHS) const;
0846
0847 fltCategory getCategory() const;
0848 bool isNegative() const;
0849
0850 void makeInf(bool Neg);
0851 void makeZero(bool Neg);
0852 void makeLargest(bool Neg);
0853 void makeSmallest(bool Neg);
0854 void makeSmallestNormalized(bool Neg);
0855 void makeNaN(bool SNaN, bool Neg, const APInt *fill);
0856
0857 cmpResult compare(const DoubleAPFloat &RHS) const;
0858 bool bitwiseIsEqual(const DoubleAPFloat &RHS) const;
0859 APInt bitcastToAPInt() const;
0860 Expected<opStatus> convertFromString(StringRef, roundingMode);
0861 opStatus next(bool nextDown);
0862
0863 opStatus convertToInteger(MutableArrayRef<integerPart> Input,
0864 unsigned int Width, bool IsSigned, roundingMode RM,
0865 bool *IsExact) const;
0866 opStatus convertFromAPInt(const APInt &Input, bool IsSigned, roundingMode RM);
0867 opStatus convertFromSignExtendedInteger(const integerPart *Input,
0868 unsigned int InputSize, bool IsSigned,
0869 roundingMode RM);
0870 opStatus convertFromZeroExtendedInteger(const integerPart *Input,
0871 unsigned int InputSize, bool IsSigned,
0872 roundingMode RM);
0873 unsigned int convertToHexString(char *DST, unsigned int HexDigits,
0874 bool UpperCase, roundingMode RM) const;
0875
0876 bool isDenormal() const;
0877 bool isSmallest() const;
0878 bool isSmallestNormalized() const;
0879 bool isLargest() const;
0880 bool isInteger() const;
0881
0882 void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
0883 unsigned FormatMaxPadding, bool TruncateZero = true) const;
0884
0885 bool getExactInverse(APFloat *inv) const;
0886
0887 LLVM_READONLY
0888 int getExactLog2() const;
0889 LLVM_READONLY
0890 int getExactLog2Abs() const;
0891
0892 friend DoubleAPFloat scalbn(const DoubleAPFloat &X, int Exp, roundingMode);
0893 friend DoubleAPFloat frexp(const DoubleAPFloat &X, int &Exp, roundingMode);
0894 friend hash_code hash_value(const DoubleAPFloat &Arg);
0895 };
0896
0897 hash_code hash_value(const DoubleAPFloat &Arg);
0898 DoubleAPFloat scalbn(const DoubleAPFloat &Arg, int Exp, roundingMode RM);
0899 DoubleAPFloat frexp(const DoubleAPFloat &X, int &Exp, roundingMode);
0900
0901 }
0902
0903
0904
0905 class APFloat : public APFloatBase {
0906 typedef detail::IEEEFloat IEEEFloat;
0907 typedef detail::DoubleAPFloat DoubleAPFloat;
0908
0909 static_assert(std::is_standard_layout<IEEEFloat>::value);
0910
0911 union Storage {
0912 const fltSemantics *semantics;
0913 IEEEFloat IEEE;
0914 DoubleAPFloat Double;
0915
0916 explicit Storage(IEEEFloat F, const fltSemantics &S);
0917 explicit Storage(DoubleAPFloat F, const fltSemantics &S)
0918 : Double(std::move(F)) {
0919 assert(&S == &PPCDoubleDouble());
0920 }
0921
0922 template <typename... ArgTypes>
0923 Storage(const fltSemantics &Semantics, ArgTypes &&... Args) {
0924 if (usesLayout<IEEEFloat>(Semantics)) {
0925 new (&IEEE) IEEEFloat(Semantics, std::forward<ArgTypes>(Args)...);
0926 return;
0927 }
0928 if (usesLayout<DoubleAPFloat>(Semantics)) {
0929 new (&Double) DoubleAPFloat(Semantics, std::forward<ArgTypes>(Args)...);
0930 return;
0931 }
0932 llvm_unreachable("Unexpected semantics");
0933 }
0934
0935 ~Storage() {
0936 if (usesLayout<IEEEFloat>(*semantics)) {
0937 IEEE.~IEEEFloat();
0938 return;
0939 }
0940 if (usesLayout<DoubleAPFloat>(*semantics)) {
0941 Double.~DoubleAPFloat();
0942 return;
0943 }
0944 llvm_unreachable("Unexpected semantics");
0945 }
0946
0947 Storage(const Storage &RHS) {
0948 if (usesLayout<IEEEFloat>(*RHS.semantics)) {
0949 new (this) IEEEFloat(RHS.IEEE);
0950 return;
0951 }
0952 if (usesLayout<DoubleAPFloat>(*RHS.semantics)) {
0953 new (this) DoubleAPFloat(RHS.Double);
0954 return;
0955 }
0956 llvm_unreachable("Unexpected semantics");
0957 }
0958
0959 Storage(Storage &&RHS) {
0960 if (usesLayout<IEEEFloat>(*RHS.semantics)) {
0961 new (this) IEEEFloat(std::move(RHS.IEEE));
0962 return;
0963 }
0964 if (usesLayout<DoubleAPFloat>(*RHS.semantics)) {
0965 new (this) DoubleAPFloat(std::move(RHS.Double));
0966 return;
0967 }
0968 llvm_unreachable("Unexpected semantics");
0969 }
0970
0971 Storage &operator=(const Storage &RHS) {
0972 if (usesLayout<IEEEFloat>(*semantics) &&
0973 usesLayout<IEEEFloat>(*RHS.semantics)) {
0974 IEEE = RHS.IEEE;
0975 } else if (usesLayout<DoubleAPFloat>(*semantics) &&
0976 usesLayout<DoubleAPFloat>(*RHS.semantics)) {
0977 Double = RHS.Double;
0978 } else if (this != &RHS) {
0979 this->~Storage();
0980 new (this) Storage(RHS);
0981 }
0982 return *this;
0983 }
0984
0985 Storage &operator=(Storage &&RHS) {
0986 if (usesLayout<IEEEFloat>(*semantics) &&
0987 usesLayout<IEEEFloat>(*RHS.semantics)) {
0988 IEEE = std::move(RHS.IEEE);
0989 } else if (usesLayout<DoubleAPFloat>(*semantics) &&
0990 usesLayout<DoubleAPFloat>(*RHS.semantics)) {
0991 Double = std::move(RHS.Double);
0992 } else if (this != &RHS) {
0993 this->~Storage();
0994 new (this) Storage(std::move(RHS));
0995 }
0996 return *this;
0997 }
0998 } U;
0999
1000 template <typename T> static bool usesLayout(const fltSemantics &Semantics) {
1001 static_assert(std::is_same<T, IEEEFloat>::value ||
1002 std::is_same<T, DoubleAPFloat>::value);
1003 if (std::is_same<T, DoubleAPFloat>::value) {
1004 return &Semantics == &PPCDoubleDouble();
1005 }
1006 return &Semantics != &PPCDoubleDouble();
1007 }
1008
1009 IEEEFloat &getIEEE() {
1010 if (usesLayout<IEEEFloat>(*U.semantics))
1011 return U.IEEE;
1012 if (usesLayout<DoubleAPFloat>(*U.semantics))
1013 return U.Double.getFirst().U.IEEE;
1014 llvm_unreachable("Unexpected semantics");
1015 }
1016
1017 const IEEEFloat &getIEEE() const {
1018 if (usesLayout<IEEEFloat>(*U.semantics))
1019 return U.IEEE;
1020 if (usesLayout<DoubleAPFloat>(*U.semantics))
1021 return U.Double.getFirst().U.IEEE;
1022 llvm_unreachable("Unexpected semantics");
1023 }
1024
1025 void makeZero(bool Neg) { APFLOAT_DISPATCH_ON_SEMANTICS(makeZero(Neg)); }
1026
1027 void makeInf(bool Neg) { APFLOAT_DISPATCH_ON_SEMANTICS(makeInf(Neg)); }
1028
1029 void makeNaN(bool SNaN, bool Neg, const APInt *fill) {
1030 APFLOAT_DISPATCH_ON_SEMANTICS(makeNaN(SNaN, Neg, fill));
1031 }
1032
1033 void makeLargest(bool Neg) {
1034 APFLOAT_DISPATCH_ON_SEMANTICS(makeLargest(Neg));
1035 }
1036
1037 void makeSmallest(bool Neg) {
1038 APFLOAT_DISPATCH_ON_SEMANTICS(makeSmallest(Neg));
1039 }
1040
1041 void makeSmallestNormalized(bool Neg) {
1042 APFLOAT_DISPATCH_ON_SEMANTICS(makeSmallestNormalized(Neg));
1043 }
1044
1045 explicit APFloat(IEEEFloat F, const fltSemantics &S) : U(std::move(F), S) {}
1046 explicit APFloat(DoubleAPFloat F, const fltSemantics &S)
1047 : U(std::move(F), S) {}
1048
1049 cmpResult compareAbsoluteValue(const APFloat &RHS) const {
1050 assert(&getSemantics() == &RHS.getSemantics() &&
1051 "Should only compare APFloats with the same semantics");
1052 if (usesLayout<IEEEFloat>(getSemantics()))
1053 return U.IEEE.compareAbsoluteValue(RHS.U.IEEE);
1054 if (usesLayout<DoubleAPFloat>(getSemantics()))
1055 return U.Double.compareAbsoluteValue(RHS.U.Double);
1056 llvm_unreachable("Unexpected semantics");
1057 }
1058
1059 public:
1060 APFloat(const fltSemantics &Semantics) : U(Semantics) {}
1061 APFloat(const fltSemantics &Semantics, StringRef S);
1062 APFloat(const fltSemantics &Semantics, integerPart I) : U(Semantics, I) {}
1063 template <typename T,
1064 typename = std::enable_if_t<std::is_floating_point<T>::value>>
1065 APFloat(const fltSemantics &Semantics, T V) = delete;
1066
1067 APFloat(const fltSemantics &Semantics, uninitializedTag)
1068 : U(Semantics, uninitialized) {}
1069 APFloat(const fltSemantics &Semantics, const APInt &I) : U(Semantics, I) {}
1070 explicit APFloat(double d) : U(IEEEFloat(d), IEEEdouble()) {}
1071 explicit APFloat(float f) : U(IEEEFloat(f), IEEEsingle()) {}
1072 APFloat(const APFloat &RHS) = default;
1073 APFloat(APFloat &&RHS) = default;
1074
1075 ~APFloat() = default;
1076
1077 bool needsCleanup() const { APFLOAT_DISPATCH_ON_SEMANTICS(needsCleanup()); }
1078
1079
1080
1081
1082 static APFloat getZero(const fltSemantics &Sem, bool Negative = false) {
1083 APFloat Val(Sem, uninitialized);
1084 Val.makeZero(Negative);
1085 return Val;
1086 }
1087
1088
1089
1090
1091 static APFloat getOne(const fltSemantics &Sem, bool Negative = false) {
1092 APFloat Val(Sem, 1U);
1093 if (Negative)
1094 Val.changeSign();
1095 return Val;
1096 }
1097
1098
1099
1100
1101 static APFloat getInf(const fltSemantics &Sem, bool Negative = false) {
1102 APFloat Val(Sem, uninitialized);
1103 Val.makeInf(Negative);
1104 return Val;
1105 }
1106
1107
1108
1109
1110
1111
1112 static APFloat getNaN(const fltSemantics &Sem, bool Negative = false,
1113 uint64_t payload = 0) {
1114 if (payload) {
1115 APInt intPayload(64, payload);
1116 return getQNaN(Sem, Negative, &intPayload);
1117 } else {
1118 return getQNaN(Sem, Negative, nullptr);
1119 }
1120 }
1121
1122
1123 static APFloat getQNaN(const fltSemantics &Sem, bool Negative = false,
1124 const APInt *payload = nullptr) {
1125 APFloat Val(Sem, uninitialized);
1126 Val.makeNaN(false, Negative, payload);
1127 return Val;
1128 }
1129
1130
1131 static APFloat getSNaN(const fltSemantics &Sem, bool Negative = false,
1132 const APInt *payload = nullptr) {
1133 APFloat Val(Sem, uninitialized);
1134 Val.makeNaN(true, Negative, payload);
1135 return Val;
1136 }
1137
1138
1139
1140
1141 static APFloat getLargest(const fltSemantics &Sem, bool Negative = false) {
1142 APFloat Val(Sem, uninitialized);
1143 Val.makeLargest(Negative);
1144 return Val;
1145 }
1146
1147
1148
1149
1150
1151 static APFloat getSmallest(const fltSemantics &Sem, bool Negative = false) {
1152 APFloat Val(Sem, uninitialized);
1153 Val.makeSmallest(Negative);
1154 return Val;
1155 }
1156
1157
1158
1159
1160
1161 static APFloat getSmallestNormalized(const fltSemantics &Sem,
1162 bool Negative = false) {
1163 APFloat Val(Sem, uninitialized);
1164 Val.makeSmallestNormalized(Negative);
1165 return Val;
1166 }
1167
1168
1169
1170
1171 static APFloat getAllOnesValue(const fltSemantics &Semantics);
1172
1173
1174
1175
1176 static bool hasSignificand(const fltSemantics &Sem) {
1177 return &Sem != &Float8E8M0FNU();
1178 }
1179
1180
1181
1182 void Profile(FoldingSetNodeID &NID) const;
1183
1184 opStatus add(const APFloat &RHS, roundingMode RM) {
1185 assert(&getSemantics() == &RHS.getSemantics() &&
1186 "Should only call on two APFloats with the same semantics");
1187 if (usesLayout<IEEEFloat>(getSemantics()))
1188 return U.IEEE.add(RHS.U.IEEE, RM);
1189 if (usesLayout<DoubleAPFloat>(getSemantics()))
1190 return U.Double.add(RHS.U.Double, RM);
1191 llvm_unreachable("Unexpected semantics");
1192 }
1193 opStatus subtract(const APFloat &RHS, roundingMode RM) {
1194 assert(&getSemantics() == &RHS.getSemantics() &&
1195 "Should only call on two APFloats with the same semantics");
1196 if (usesLayout<IEEEFloat>(getSemantics()))
1197 return U.IEEE.subtract(RHS.U.IEEE, RM);
1198 if (usesLayout<DoubleAPFloat>(getSemantics()))
1199 return U.Double.subtract(RHS.U.Double, RM);
1200 llvm_unreachable("Unexpected semantics");
1201 }
1202 opStatus multiply(const APFloat &RHS, roundingMode RM) {
1203 assert(&getSemantics() == &RHS.getSemantics() &&
1204 "Should only call on two APFloats with the same semantics");
1205 if (usesLayout<IEEEFloat>(getSemantics()))
1206 return U.IEEE.multiply(RHS.U.IEEE, RM);
1207 if (usesLayout<DoubleAPFloat>(getSemantics()))
1208 return U.Double.multiply(RHS.U.Double, RM);
1209 llvm_unreachable("Unexpected semantics");
1210 }
1211 opStatus divide(const APFloat &RHS, roundingMode RM) {
1212 assert(&getSemantics() == &RHS.getSemantics() &&
1213 "Should only call on two APFloats with the same semantics");
1214 if (usesLayout<IEEEFloat>(getSemantics()))
1215 return U.IEEE.divide(RHS.U.IEEE, RM);
1216 if (usesLayout<DoubleAPFloat>(getSemantics()))
1217 return U.Double.divide(RHS.U.Double, RM);
1218 llvm_unreachable("Unexpected semantics");
1219 }
1220 opStatus remainder(const APFloat &RHS) {
1221 assert(&getSemantics() == &RHS.getSemantics() &&
1222 "Should only call on two APFloats with the same semantics");
1223 if (usesLayout<IEEEFloat>(getSemantics()))
1224 return U.IEEE.remainder(RHS.U.IEEE);
1225 if (usesLayout<DoubleAPFloat>(getSemantics()))
1226 return U.Double.remainder(RHS.U.Double);
1227 llvm_unreachable("Unexpected semantics");
1228 }
1229 opStatus mod(const APFloat &RHS) {
1230 assert(&getSemantics() == &RHS.getSemantics() &&
1231 "Should only call on two APFloats with the same semantics");
1232 if (usesLayout<IEEEFloat>(getSemantics()))
1233 return U.IEEE.mod(RHS.U.IEEE);
1234 if (usesLayout<DoubleAPFloat>(getSemantics()))
1235 return U.Double.mod(RHS.U.Double);
1236 llvm_unreachable("Unexpected semantics");
1237 }
1238 opStatus fusedMultiplyAdd(const APFloat &Multiplicand, const APFloat &Addend,
1239 roundingMode RM) {
1240 assert(&getSemantics() == &Multiplicand.getSemantics() &&
1241 "Should only call on APFloats with the same semantics");
1242 assert(&getSemantics() == &Addend.getSemantics() &&
1243 "Should only call on APFloats with the same semantics");
1244 if (usesLayout<IEEEFloat>(getSemantics()))
1245 return U.IEEE.fusedMultiplyAdd(Multiplicand.U.IEEE, Addend.U.IEEE, RM);
1246 if (usesLayout<DoubleAPFloat>(getSemantics()))
1247 return U.Double.fusedMultiplyAdd(Multiplicand.U.Double, Addend.U.Double,
1248 RM);
1249 llvm_unreachable("Unexpected semantics");
1250 }
1251 opStatus roundToIntegral(roundingMode RM) {
1252 APFLOAT_DISPATCH_ON_SEMANTICS(roundToIntegral(RM));
1253 }
1254
1255
1256
1257 opStatus next(bool nextDown) {
1258 APFLOAT_DISPATCH_ON_SEMANTICS(next(nextDown));
1259 }
1260
1261
1262 APFloat operator-() const {
1263 APFloat Result(*this);
1264 Result.changeSign();
1265 return Result;
1266 }
1267
1268
1269
1270 APFloat operator+(const APFloat &RHS) const {
1271 APFloat Result(*this);
1272 (void)Result.add(RHS, rmNearestTiesToEven);
1273 return Result;
1274 }
1275
1276
1277
1278 APFloat operator-(const APFloat &RHS) const {
1279 APFloat Result(*this);
1280 (void)Result.subtract(RHS, rmNearestTiesToEven);
1281 return Result;
1282 }
1283
1284
1285
1286 APFloat operator*(const APFloat &RHS) const {
1287 APFloat Result(*this);
1288 (void)Result.multiply(RHS, rmNearestTiesToEven);
1289 return Result;
1290 }
1291
1292
1293
1294 APFloat operator/(const APFloat &RHS) const {
1295 APFloat Result(*this);
1296 (void)Result.divide(RHS, rmNearestTiesToEven);
1297 return Result;
1298 }
1299
1300 void changeSign() { APFLOAT_DISPATCH_ON_SEMANTICS(changeSign()); }
1301 void clearSign() {
1302 if (isNegative())
1303 changeSign();
1304 }
1305 void copySign(const APFloat &RHS) {
1306 if (isNegative() != RHS.isNegative())
1307 changeSign();
1308 }
1309
1310
1311
1312 static APFloat copySign(APFloat Value, const APFloat &Sign) {
1313 Value.copySign(Sign);
1314 return Value;
1315 }
1316
1317
1318
1319 APFloat makeQuiet() const {
1320 APFloat Result(*this);
1321 Result.getIEEE().makeQuiet();
1322 return Result;
1323 }
1324
1325 opStatus convert(const fltSemantics &ToSemantics, roundingMode RM,
1326 bool *losesInfo);
1327 opStatus convertToInteger(MutableArrayRef<integerPart> Input,
1328 unsigned int Width, bool IsSigned, roundingMode RM,
1329 bool *IsExact) const {
1330 APFLOAT_DISPATCH_ON_SEMANTICS(
1331 convertToInteger(Input, Width, IsSigned, RM, IsExact));
1332 }
1333 opStatus convertToInteger(APSInt &Result, roundingMode RM,
1334 bool *IsExact) const;
1335 opStatus convertFromAPInt(const APInt &Input, bool IsSigned,
1336 roundingMode RM) {
1337 APFLOAT_DISPATCH_ON_SEMANTICS(convertFromAPInt(Input, IsSigned, RM));
1338 }
1339 opStatus convertFromSignExtendedInteger(const integerPart *Input,
1340 unsigned int InputSize, bool IsSigned,
1341 roundingMode RM) {
1342 APFLOAT_DISPATCH_ON_SEMANTICS(
1343 convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM));
1344 }
1345 opStatus convertFromZeroExtendedInteger(const integerPart *Input,
1346 unsigned int InputSize, bool IsSigned,
1347 roundingMode RM) {
1348 APFLOAT_DISPATCH_ON_SEMANTICS(
1349 convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM));
1350 }
1351 Expected<opStatus> convertFromString(StringRef, roundingMode);
1352 APInt bitcastToAPInt() const {
1353 APFLOAT_DISPATCH_ON_SEMANTICS(bitcastToAPInt());
1354 }
1355
1356
1357
1358
1359
1360
1361 double convertToDouble() const;
1362
1363
1364
1365
1366
1367
1368 #ifdef HAS_IEE754_FLOAT128
1369 float128 convertToQuad() const;
1370 #endif
1371
1372
1373
1374
1375
1376
1377 float convertToFloat() const;
1378
1379 bool operator==(const APFloat &RHS) const { return compare(RHS) == cmpEqual; }
1380
1381 bool operator!=(const APFloat &RHS) const { return compare(RHS) != cmpEqual; }
1382
1383 bool operator<(const APFloat &RHS) const {
1384 return compare(RHS) == cmpLessThan;
1385 }
1386
1387 bool operator>(const APFloat &RHS) const {
1388 return compare(RHS) == cmpGreaterThan;
1389 }
1390
1391 bool operator<=(const APFloat &RHS) const {
1392 cmpResult Res = compare(RHS);
1393 return Res == cmpLessThan || Res == cmpEqual;
1394 }
1395
1396 bool operator>=(const APFloat &RHS) const {
1397 cmpResult Res = compare(RHS);
1398 return Res == cmpGreaterThan || Res == cmpEqual;
1399 }
1400
1401 cmpResult compare(const APFloat &RHS) const {
1402 assert(&getSemantics() == &RHS.getSemantics() &&
1403 "Should only compare APFloats with the same semantics");
1404 if (usesLayout<IEEEFloat>(getSemantics()))
1405 return U.IEEE.compare(RHS.U.IEEE);
1406 if (usesLayout<DoubleAPFloat>(getSemantics()))
1407 return U.Double.compare(RHS.U.Double);
1408 llvm_unreachable("Unexpected semantics");
1409 }
1410
1411 bool bitwiseIsEqual(const APFloat &RHS) const {
1412 if (&getSemantics() != &RHS.getSemantics())
1413 return false;
1414 if (usesLayout<IEEEFloat>(getSemantics()))
1415 return U.IEEE.bitwiseIsEqual(RHS.U.IEEE);
1416 if (usesLayout<DoubleAPFloat>(getSemantics()))
1417 return U.Double.bitwiseIsEqual(RHS.U.Double);
1418 llvm_unreachable("Unexpected semantics");
1419 }
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429 bool isExactlyValue(double V) const {
1430 bool ignored;
1431 APFloat Tmp(V);
1432 Tmp.convert(getSemantics(), APFloat::rmNearestTiesToEven, &ignored);
1433 return bitwiseIsEqual(Tmp);
1434 }
1435
1436 unsigned int convertToHexString(char *DST, unsigned int HexDigits,
1437 bool UpperCase, roundingMode RM) const {
1438 APFLOAT_DISPATCH_ON_SEMANTICS(
1439 convertToHexString(DST, HexDigits, UpperCase, RM));
1440 }
1441
1442 bool isZero() const { return getCategory() == fcZero; }
1443 bool isInfinity() const { return getCategory() == fcInfinity; }
1444 bool isNaN() const { return getCategory() == fcNaN; }
1445
1446 bool isNegative() const { return getIEEE().isNegative(); }
1447 bool isDenormal() const { APFLOAT_DISPATCH_ON_SEMANTICS(isDenormal()); }
1448 bool isSignaling() const { return getIEEE().isSignaling(); }
1449
1450 bool isNormal() const { return !isDenormal() && isFiniteNonZero(); }
1451 bool isFinite() const { return !isNaN() && !isInfinity(); }
1452
1453 fltCategory getCategory() const { return getIEEE().getCategory(); }
1454 const fltSemantics &getSemantics() const { return *U.semantics; }
1455 bool isNonZero() const { return !isZero(); }
1456 bool isFiniteNonZero() const { return isFinite() && !isZero(); }
1457 bool isPosZero() const { return isZero() && !isNegative(); }
1458 bool isNegZero() const { return isZero() && isNegative(); }
1459 bool isPosInfinity() const { return isInfinity() && !isNegative(); }
1460 bool isNegInfinity() const { return isInfinity() && isNegative(); }
1461 bool isSmallest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isSmallest()); }
1462 bool isLargest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isLargest()); }
1463 bool isInteger() const { APFLOAT_DISPATCH_ON_SEMANTICS(isInteger()); }
1464 bool isIEEE() const { return usesLayout<IEEEFloat>(getSemantics()); }
1465
1466 bool isSmallestNormalized() const {
1467 APFLOAT_DISPATCH_ON_SEMANTICS(isSmallestNormalized());
1468 }
1469
1470
1471 FPClassTest classify() const;
1472
1473 APFloat &operator=(const APFloat &RHS) = default;
1474 APFloat &operator=(APFloat &&RHS) = default;
1475
1476 void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
1477 unsigned FormatMaxPadding = 3, bool TruncateZero = true) const {
1478 APFLOAT_DISPATCH_ON_SEMANTICS(
1479 toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero));
1480 }
1481
1482 void print(raw_ostream &) const;
1483 void dump() const;
1484
1485 bool getExactInverse(APFloat *inv) const {
1486 APFLOAT_DISPATCH_ON_SEMANTICS(getExactInverse(inv));
1487 }
1488
1489 LLVM_READONLY
1490 int getExactLog2Abs() const {
1491 APFLOAT_DISPATCH_ON_SEMANTICS(getExactLog2Abs());
1492 }
1493
1494 LLVM_READONLY
1495 int getExactLog2() const {
1496 APFLOAT_DISPATCH_ON_SEMANTICS(getExactLog2());
1497 }
1498
1499 friend hash_code hash_value(const APFloat &Arg);
1500 friend int ilogb(const APFloat &Arg) { return ilogb(Arg.getIEEE()); }
1501 friend APFloat scalbn(APFloat X, int Exp, roundingMode RM);
1502 friend APFloat frexp(const APFloat &X, int &Exp, roundingMode RM);
1503 friend IEEEFloat;
1504 friend DoubleAPFloat;
1505 };
1506
1507 static_assert(sizeof(APFloat) == sizeof(detail::IEEEFloat),
1508 "Empty base class optimization is not performed.");
1509
1510
1511
1512
1513
1514 hash_code hash_value(const APFloat &Arg);
1515 inline APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM) {
1516 if (APFloat::usesLayout<detail::IEEEFloat>(X.getSemantics()))
1517 return APFloat(scalbn(X.U.IEEE, Exp, RM), X.getSemantics());
1518 if (APFloat::usesLayout<detail::DoubleAPFloat>(X.getSemantics()))
1519 return APFloat(scalbn(X.U.Double, Exp, RM), X.getSemantics());
1520 llvm_unreachable("Unexpected semantics");
1521 }
1522
1523
1524
1525
1526
1527 inline APFloat frexp(const APFloat &X, int &Exp, APFloat::roundingMode RM) {
1528 if (APFloat::usesLayout<detail::IEEEFloat>(X.getSemantics()))
1529 return APFloat(frexp(X.U.IEEE, Exp, RM), X.getSemantics());
1530 if (APFloat::usesLayout<detail::DoubleAPFloat>(X.getSemantics()))
1531 return APFloat(frexp(X.U.Double, Exp, RM), X.getSemantics());
1532 llvm_unreachable("Unexpected semantics");
1533 }
1534
1535 inline APFloat abs(APFloat X) {
1536 X.clearSign();
1537 return X;
1538 }
1539
1540
1541 inline APFloat neg(APFloat X) {
1542 X.changeSign();
1543 return X;
1544 }
1545
1546
1547
1548
1549 LLVM_READONLY
1550 inline APFloat minnum(const APFloat &A, const APFloat &B) {
1551 if (A.isNaN())
1552 return B;
1553 if (B.isNaN())
1554 return A;
1555 if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative()))
1556 return A.isNegative() ? A : B;
1557 return B < A ? B : A;
1558 }
1559
1560
1561
1562
1563 LLVM_READONLY
1564 inline APFloat maxnum(const APFloat &A, const APFloat &B) {
1565 if (A.isNaN())
1566 return B;
1567 if (B.isNaN())
1568 return A;
1569 if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative()))
1570 return A.isNegative() ? B : A;
1571 return A < B ? B : A;
1572 }
1573
1574
1575
1576
1577 LLVM_READONLY
1578 inline APFloat minimum(const APFloat &A, const APFloat &B) {
1579 if (A.isNaN())
1580 return A.makeQuiet();
1581 if (B.isNaN())
1582 return B.makeQuiet();
1583 if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative()))
1584 return A.isNegative() ? A : B;
1585 return B < A ? B : A;
1586 }
1587
1588
1589
1590 LLVM_READONLY
1591 inline APFloat minimumnum(const APFloat &A, const APFloat &B) {
1592 if (A.isNaN())
1593 return B.isNaN() ? B.makeQuiet() : B;
1594 if (B.isNaN())
1595 return A;
1596 if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative()))
1597 return A.isNegative() ? A : B;
1598 return B < A ? B : A;
1599 }
1600
1601
1602
1603
1604 LLVM_READONLY
1605 inline APFloat maximum(const APFloat &A, const APFloat &B) {
1606 if (A.isNaN())
1607 return A.makeQuiet();
1608 if (B.isNaN())
1609 return B.makeQuiet();
1610 if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative()))
1611 return A.isNegative() ? B : A;
1612 return A < B ? B : A;
1613 }
1614
1615
1616
1617 LLVM_READONLY
1618 inline APFloat maximumnum(const APFloat &A, const APFloat &B) {
1619 if (A.isNaN())
1620 return B.isNaN() ? B.makeQuiet() : B;
1621 if (B.isNaN())
1622 return A;
1623 if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative()))
1624 return A.isNegative() ? B : A;
1625 return A < B ? B : A;
1626 }
1627
1628 inline raw_ostream &operator<<(raw_ostream &OS, const APFloat &V) {
1629 V.print(OS);
1630 return OS;
1631 }
1632
1633
1634
1635
1636
1637 namespace detail {
1638
1639 DoubleAPFloat &DoubleAPFloat::operator=(DoubleAPFloat &&RHS) {
1640 if (this != &RHS) {
1641 this->~DoubleAPFloat();
1642 new (this) DoubleAPFloat(std::move(RHS));
1643 }
1644 return *this;
1645 }
1646
1647 APFloat &DoubleAPFloat::getFirst() { return Floats[0]; }
1648 const APFloat &DoubleAPFloat::getFirst() const { return Floats[0]; }
1649 APFloat &DoubleAPFloat::getSecond() { return Floats[1]; }
1650 const APFloat &DoubleAPFloat::getSecond() const { return Floats[1]; }
1651
1652 }
1653
1654 }
1655
1656 #undef APFLOAT_DISPATCH_ON_SEMANTICS
1657 #endif