Whether arithmetic is supported is a property of the semantics. Make it
authorNeil Booth <neil@daikokuya.co.uk>
Sun, 14 Oct 2007 10:29:28 +0000 (10:29 +0000)
committerNeil Booth <neil@daikokuya.co.uk>
Sun, 14 Oct 2007 10:29:28 +0000 (10:29 +0000)
so, and clean up the checks by putting them in an inline function.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42965 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/APFloat.cpp

index 4a24b487952a5e4cf6c4d4ab9a0fbda885e3173b..e6f6b504e7a4f33c223e2a80f3e4a19596a4cd97 100644 (file)
@@ -40,18 +40,21 @@ namespace llvm {
     /* Number of bits in the significand.  This includes the integer
        bit.  */
     unsigned int precision;
+
+    /* True if arithmetic is supported.  */
+    unsigned int arithmeticOK;
   };
 
-  const fltSemantics APFloat::IEEEsingle = { 127, -126, 24 };
-  const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53 };
-  const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113 };
-  const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64 };
-  const fltSemantics APFloat::Bogus = { 0, 0, 0 };
+  const fltSemantics APFloat::IEEEsingle = { 127, -126, 24, true };
+  const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53, true };
+  const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, true };
+  const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64, true };
+  const fltSemantics APFloat::Bogus = { 0, 0, 0, true };
 
   // The PowerPC format consists of two doubles.  It does not map cleanly
   // onto the usual format above.  For now only storage of constants of
   // this type is supported, no arithmetic.
-  const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022, 106 };
+  const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022, 106, false };
 
   /* A tight upper bound on number of parts required to hold the value
      pow(5, power) is
@@ -107,6 +110,12 @@ namespace {
     return -1U;
   }
 
+  inline void
+  assertArithmeticOK(const llvm::fltSemantics &semantics) {
+    assert(semantics.arithmeticOK
+           && "Compile-time arithmetic does not support these semantics");
+  }
+
   /* Return the value of a decimal exponent of the form
      [+-]ddddddd.
 
@@ -623,8 +632,7 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
 
 APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value)
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
+  assertArithmeticOK(ourSemantics);
   initialize(&ourSemantics);
   sign = 0;
   zeroSignificand();
@@ -636,8 +644,7 @@ APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value)
 APFloat::APFloat(const fltSemantics &ourSemantics,
                  fltCategory ourCategory, bool negative)
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
+  assertArithmeticOK(ourSemantics);
   initialize(&ourSemantics);
   category = ourCategory;
   sign = negative;
@@ -647,8 +654,7 @@ APFloat::APFloat(const fltSemantics &ourSemantics,
 
 APFloat::APFloat(const fltSemantics &ourSemantics, const char *text)
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
+  assertArithmeticOK(ourSemantics);
   initialize(&ourSemantics);
   convertFromString(text, rmNearestTiesToEven);
 }
@@ -1405,6 +1411,8 @@ APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode,
 {
   opStatus fs;
 
+  assertArithmeticOK(*semantics);
+
   fs = addOrSubtractSpecials(rhs, subtract);
 
   /* This return code means it was not a simple case.  */
@@ -1433,8 +1441,6 @@ APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode,
 APFloat::opStatus
 APFloat::add(const APFloat &rhs, roundingMode rounding_mode)
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
   return addOrSubtract(rhs, rounding_mode, false);
 }
 
@@ -1442,8 +1448,6 @@ APFloat::add(const APFloat &rhs, roundingMode rounding_mode)
 APFloat::opStatus
 APFloat::subtract(const APFloat &rhs, roundingMode rounding_mode)
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
   return addOrSubtract(rhs, rounding_mode, true);
 }
 
@@ -1451,10 +1455,9 @@ APFloat::subtract(const APFloat &rhs, roundingMode rounding_mode)
 APFloat::opStatus
 APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode)
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
   opStatus fs;
 
+  assertArithmeticOK(*semantics);
   sign ^= rhs.sign;
   fs = multiplySpecials(rhs);
 
@@ -1472,10 +1475,9 @@ APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode)
 APFloat::opStatus
 APFloat::divide(const APFloat &rhs, roundingMode rounding_mode)
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
   opStatus fs;
 
+  assertArithmeticOK(*semantics);
   sign ^= rhs.sign;
   fs = divideSpecials(rhs);
 
@@ -1493,11 +1495,11 @@ APFloat::divide(const APFloat &rhs, roundingMode rounding_mode)
 APFloat::opStatus
 APFloat::mod(const APFloat &rhs, roundingMode rounding_mode)
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
   opStatus fs;
   APFloat V = *this;
   unsigned int origSign = sign;
+
+  assertArithmeticOK(*semantics);
   fs = V.divide(rhs, rmNearestTiesToEven);
   if (fs == opDivByZero)
     return fs;
@@ -1531,10 +1533,10 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
                           const APFloat &addend,
                           roundingMode rounding_mode)
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
   opStatus fs;
 
+  assertArithmeticOK(*semantics);
+
   /* Post-multiplication sign, before addition.  */
   sign ^= multiplicand.sign;
 
@@ -1576,10 +1578,9 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
 APFloat::cmpResult
 APFloat::compare(const APFloat &rhs) const
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
   cmpResult result;
 
+  assertArithmeticOK(*semantics);
   assert(semantics == rhs.semantics);
 
   switch(convolve(category, rhs.category)) {
@@ -1651,12 +1652,11 @@ APFloat::opStatus
 APFloat::convert(const fltSemantics &toSemantics,
                  roundingMode rounding_mode)
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
   lostFraction lostFraction;
   unsigned int newPartCount, oldPartCount;
   opStatus fs;
 
+  assertArithmeticOK(*semantics);
   lostFraction = lfExactlyZero;
   newPartCount = partCountForBits(toSemantics.precision + 1);
   oldPartCount = partCount();
@@ -1730,12 +1730,11 @@ APFloat::convertToInteger(integerPart *parts, unsigned int width,
                           bool isSigned,
                           roundingMode rounding_mode) const
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
   lostFraction lost_fraction;
   unsigned int msb, partsCount;
   int bits;
 
+  assertArithmeticOK(*semantics);
   partsCount = partCountForBits(width);
 
   /* Handle the three special cases first.  We produce
@@ -1830,6 +1829,7 @@ APFloat::convertFromUnsignedParts(const integerPart *src,
   integerPart *dst;
   lostFraction lost_fraction;
 
+  assertArithmeticOK(*semantics);
   category = fcNormal;
   omsb = APInt::tcMSB(src, srcCount) + 1;
   dst = significandParts();
@@ -1861,10 +1861,9 @@ APFloat::convertFromSignExtendedInteger(const integerPart *src,
                                         bool isSigned,
                                         roundingMode rounding_mode)
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
   opStatus status;
 
+  assertArithmeticOK(*semantics);
   if (isSigned
       && APInt::tcExtractBit(src, srcCount * integerPartWidth - 1)) {
     integerPart *copy;
@@ -1890,8 +1889,6 @@ APFloat::convertFromZeroExtendedInteger(const integerPart *parts,
                                         unsigned int width, bool isSigned,
                                         roundingMode rounding_mode)
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
   unsigned int partCount = partCountForBits(width);
   APInt api = APInt(width, partCount, parts);
 
@@ -1908,8 +1905,6 @@ APFloat::opStatus
 APFloat::convertFromHexadecimalString(const char *p,
                                       roundingMode rounding_mode)
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
   lostFraction lost_fraction;
   integerPart *significand;
   unsigned int bitPos, partsCount;
@@ -1992,7 +1987,7 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts,
                                       roundingMode rounding_mode)
 {
   unsigned int parts, pow5PartCount;
-  fltSemantics calcSemantics = { 32767, -32767, 0 };
+  fltSemantics calcSemantics = { 32767, -32767, 0, true };
   integerPart pow5Parts[maxPowerOfFiveParts];
   bool isNearest;
 
@@ -2139,8 +2134,8 @@ APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode)
 APFloat::opStatus
 APFloat::convertFromString(const char *p, roundingMode rounding_mode)
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
+  assertArithmeticOK(*semantics);
+
   /* Handle a leading minus sign.  */
   if(*p == '-')
     sign = 1, p++;
@@ -2181,10 +2176,10 @@ unsigned int
 APFloat::convertToHexString(char *dst, unsigned int hexDigits,
                             bool upperCase, roundingMode rounding_mode) const
 {
-  assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
-         "Compile-time arithmetic on PPC long double not supported yet");
   char *p;
 
+  assertArithmeticOK(*semantics);
+
   p = dst;
   if (sign)
     *dst++ = '-';