Next PPC long double bits. First cut at constants.
authorDale Johannesen <dalej@apple.com>
Thu, 11 Oct 2007 18:07:22 +0000 (18:07 +0000)
committerDale Johannesen <dalej@apple.com>
Thu, 11 Oct 2007 18:07:22 +0000 (18:07 +0000)
No compile-time support for constant operations yet,
just format transformations.  Make readers and
writers work.  Split constants into 2 doubles in
Legalize.

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

include/llvm/ADT/APFloat.h
lib/AsmParser/Lexer.cpp.cvs
lib/AsmParser/Lexer.l
lib/AsmParser/Lexer.l.cvs
lib/Bitcode/Reader/BitcodeReader.cpp
lib/Bitcode/Writer/BitcodeWriter.cpp
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/Support/APFloat.cpp
lib/VMCore/AsmWriter.cpp
lib/VMCore/Constants.cpp

index f5511f42805ea292f8d2fbd5e17ee9d23e0b95ab..38d110d6e145a4ad7c4bba3c56c33d192b35014f 100644 (file)
@@ -126,6 +126,7 @@ namespace llvm {
     static const fltSemantics IEEEsingle;
     static const fltSemantics IEEEdouble;
     static const fltSemantics IEEEquad;
+    static const fltSemantics PPCDoubleDouble;
     static const fltSemantics x87DoubleExtended;
     /* And this psuedo, used to construct APFloats that cannot
        conflict with anything real. */
@@ -175,7 +176,7 @@ namespace llvm {
     APFloat(const fltSemantics &, fltCategory, bool negative);
     explicit APFloat(double d);
     explicit APFloat(float f);
-    explicit APFloat(const APInt &);
+    explicit APFloat(const APInt &, bool isIEEE = false);
     APFloat(const APFloat &);
     ~APFloat();
 
@@ -276,10 +277,12 @@ namespace llvm {
     APInt convertFloatAPFloatToAPInt() const;
     APInt convertDoubleAPFloatToAPInt() const;
     APInt convertF80LongDoubleAPFloatToAPInt() const;
-    void initFromAPInt(const APInt& api);
+    APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
+    void initFromAPInt(const APInt& api, bool isIEEE = false);
     void initFromFloatAPInt(const APInt& api);
     void initFromDoubleAPInt(const APInt& api);
     void initFromF80LongDoubleAPInt(const APInt& api);
+    void initFromPPCDoubleDoubleAPInt(const APInt& api);
 
     void assign(const APFloat &);
     void copySignificand(const APFloat &);
@@ -306,6 +309,13 @@ namespace llvm {
 
     /* The sign bit of this number.  */
     unsigned int sign: 1;
+
+    /* For PPCDoubleDouble, we have a second exponent and sign (the second
+       significand is appended to the first one, although it would be wrong to
+       regard these as a single number for arithmetic purposes).  These fields
+       are not meaningful for any other type. */
+    exponent_t exponent2 : 11;
+    unsigned int sign2: 1;
   };
 } /* namespace llvm */
 
index 6e2819f3f55dc46e4d46df311d9959aedf2cf3e5..536d5696482bc0a1442d4bd0dc1bc1b60036b469 100644 (file)
@@ -2199,7 +2199,7 @@ YY_RULE_SETUP
 #line 488 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l"
 { uint64_t Pair[2];
                     HexToIntPair(yytext+3, Pair);
-                    llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair));
+                    llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair), true);
                     return FPVAL;
                 }
        YY_BREAK
index 73e9c5477127f9d287e7f83e977ddfcdf3ed695d..0591cd99f3f1eecfc3ed4e62fa9e5ca5f96ff3b0 100644 (file)
@@ -487,7 +487,7 @@ shufflevector   { RET_TOK(OtherOpVal, ShuffleVector, SHUFFLEVECTOR); }
                 }
 {HexFP128Constant} { uint64_t Pair[2];
                     HexToIntPair(yytext+3, Pair);
-                    llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair));
+                    llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair), true);
                     return FPVAL;
                 }
 {HexPPC128Constant} { uint64_t Pair[2];
index 73e9c5477127f9d287e7f83e977ddfcdf3ed695d..0591cd99f3f1eecfc3ed4e62fa9e5ca5f96ff3b0 100644 (file)
@@ -487,7 +487,7 @@ shufflevector   { RET_TOK(OtherOpVal, ShuffleVector, SHUFFLEVECTOR); }
                 }
 {HexFP128Constant} { uint64_t Pair[2];
                     HexToIntPair(yytext+3, Pair);
-                    llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair));
+                    llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair), true);
                     return FPVAL;
                 }
 {HexPPC128Constant} { uint64_t Pair[2];
index 9e4a3dee60f3f0636567d1cb8fe88452c105bace..727855799678b744806659d9f6b41974de7a78b4 100644 (file)
@@ -632,9 +632,9 @@ bool BitcodeReader::ParseConstants() {
       else if (CurTy == Type::X86_FP80Ty)
         V = ConstantFP::get(CurTy, APFloat(APInt(80, 2, &Record[0])));
       else if (CurTy == Type::FP128Ty)
-        V = ConstantFP::get(CurTy, APFloat(APInt(128, 2, &Record[0])));
+        V = ConstantFP::get(CurTy, APFloat(APInt(128, 2, &Record[0]), true));
       else if (CurTy == Type::PPC_FP128Ty)
-        assert(0 && "PowerPC long double constants not handled yet.");
+        V = ConstantFP::get(CurTy, APFloat(APInt(128, 2, &Record[0])));
       else
         V = UndefValue::get(CurTy);
       break;
index 7999907c18560b37b6692639a79072438e3d4b92..6bf27123c96bfaac1169bcb83ad43b165d297235 100644 (file)
@@ -534,13 +534,11 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
         const uint64_t *p = api.getRawData();
         Record.push_back(p[0]);
         Record.push_back((uint16_t)p[1]);
-      } else if (Ty == Type::FP128Ty) {
+      } else if (Ty == Type::FP128Ty || Ty == Type::PPC_FP128Ty) {
         APInt api = CFP->getValueAPF().convertToAPInt();
         const uint64_t *p = api.getRawData();
         Record.push_back(p[0]);
         Record.push_back(p[1]);
-      } else if (Ty == Type::PPC_FP128Ty) {
-        assert(0 && "PowerPC long double constants not handled yet.");
       } else {
         assert (0 && "Unknown FP type!");
       }
index ce28c79dc9cbd829b6916687086ef9fbeae57de2..87f39483cf622b1fd420eb051f9964126a55c29e 100644 (file)
@@ -5196,6 +5196,14 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
   }
   case ISD::ConstantFP: {
     ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Node);
+    if (CFP->getValueType(0) == MVT::ppcf128) {
+      APInt api = CFP->getValueAPF().convertToAPInt();
+      Lo = DAG.getConstantFP(APFloat(APInt(64, 1, &api.getRawData()[1])),
+                             MVT::f64);
+      Hi = DAG.getConstantFP(APFloat(APInt(64, 1, &api.getRawData()[0])), 
+                             MVT::f64);
+      break;
+    }
     Lo = ExpandConstantFP(CFP, false, DAG, TLI);
     if (getTypeAction(Lo.getValueType()) == Expand)
       ExpandOp(Lo, Lo, Hi);
index d05c24e2e156918e3e38c88cadccfaad61330a92..ab30a030a2bcdd8d2af542184737f4803954b212 100644 (file)
@@ -50,6 +50,11 @@ namespace llvm {
   const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, true };
   const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64, false };
   const fltSemantics APFloat::Bogus = { 0, 0, 0, false };
+
+  // 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, true };
 }
 
 /* Put a bunch of private, handy routines in an anonymous namespace.  */
@@ -325,6 +330,8 @@ APFloat::assign(const APFloat &rhs)
   sign = rhs.sign;
   category = rhs.category;
   exponent = rhs.exponent;
+  sign2 = rhs.sign2;
+  exponent2 = rhs.exponent2;
   if(category == fcNormal || category == fcNaN)
     copySignificand(rhs);
 }
@@ -361,10 +368,16 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
       category != rhs.category ||
       sign != rhs.sign)
     return false;
+  if (semantics==(const llvm::fltSemantics* const)&PPCDoubleDouble &&
+      sign2 != rhs.sign2)
+    return false;
   if (category==fcZero || category==fcInfinity)
     return true;
   else if (category==fcNormal && exponent!=rhs.exponent)
     return false;
+  else if (semantics==(const llvm::fltSemantics* const)&PPCDoubleDouble &&
+           exponent2!=rhs.exponent2)
+    return false;
   else {
     int i= partCount();
     const integerPart* p=significandParts();
@@ -379,6 +392,8 @@ 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");
   initialize(&ourSemantics);
   sign = 0;
   zeroSignificand();
@@ -390,6 +405,8 @@ 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");
   initialize(&ourSemantics);
   category = ourCategory;
   sign = negative;
@@ -399,6 +416,8 @@ 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");
   initialize(&ourSemantics);
   convertFromString(text, rmNearestTiesToEven);
 }
@@ -1181,6 +1200,8 @@ 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);
 }
 
@@ -1188,6 +1209,8 @@ 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);
 }
 
@@ -1195,6 +1218,8 @@ 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;
 
   sign ^= rhs.sign;
@@ -1214,6 +1239,8 @@ 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;
 
   sign ^= rhs.sign;
@@ -1233,6 +1260,8 @@ 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;
@@ -1269,6 +1298,8 @@ 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;
 
   /* Post-multiplication sign, before addition.  */
@@ -1312,6 +1343,8 @@ 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;
 
   assert(semantics == rhs.semantics);
@@ -1385,6 +1418,8 @@ 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;
@@ -1462,6 +1497,8 @@ 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;
@@ -1591,6 +1628,8 @@ 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;
 
   if (isSigned
@@ -1618,6 +1657,8 @@ 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);
 
@@ -1634,6 +1675,8 @@ 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;
@@ -1713,6 +1756,8 @@ APFloat::convertFromHexadecimalString(const char *p,
 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");
   /* Handle a leading minus sign.  */
   if(*p == '-')
     sign = 1, p++;
@@ -1754,6 +1799,8 @@ 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;
 
   p = dst;
@@ -1961,6 +2008,51 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const
   return APInt(80, 2, words);
 }
 
+APInt
+APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const
+{
+  assert(semantics == (const llvm::fltSemantics* const)&PPCDoubleDouble);
+  assert (partCount()==2);
+
+  uint64_t myexponent, mysignificand, myexponent2, mysignificand2;
+
+  if (category==fcNormal) {
+    myexponent = exponent + 1023; //bias
+    myexponent2 = exponent2 + 1023;
+    mysignificand = significandParts()[0];
+    mysignificand2 = significandParts()[1];
+    if (myexponent==1 && !(mysignificand & 0x10000000000000LL))
+      myexponent = 0;   // denormal
+    if (myexponent2==1 && !(mysignificand2 & 0x10000000000000LL))
+      myexponent2 = 0;   // denormal
+  } else if (category==fcZero) {
+    myexponent = 0;
+    mysignificand = 0;
+    myexponent2 = 0;
+    mysignificand2 = 0;
+  } else if (category==fcInfinity) {
+    myexponent = 0x7ff;
+    myexponent2 = 0;
+    mysignificand = 0;
+    mysignificand2 = 0;
+  } else {
+    assert(category == fcNaN && "Unknown category");
+    myexponent = 0x7ff;
+    mysignificand = significandParts()[0];
+    myexponent2 = exponent2;
+    mysignificand2 = significandParts()[1];
+  }
+
+  uint64_t words[2];
+  words[0] =  (((uint64_t)sign & 1) << 63) |
+              ((myexponent & 0x7ff) <<  52) |
+              (mysignificand & 0xfffffffffffffLL);
+  words[1] =  (((uint64_t)sign2 & 1) << 63) |
+              ((myexponent2 & 0x7ff) <<  52) |
+              (mysignificand2 & 0xfffffffffffffLL);
+  return APInt(128, 2, words);
+}
+
 APInt
 APFloat::convertDoubleAPFloatToAPInt() const
 {
@@ -2020,6 +2112,10 @@ APFloat::convertFloatAPFloatToAPInt() const
                     (mysignificand & 0x7fffff)));
 }
 
+// This function creates an APInt that is just a bit map of the floating
+// point constant as it would appear in memory.  It is not a conversion,
+// and treating the result as a normal integer is unlikely to be useful.
+
 APInt
 APFloat::convertToAPInt() const
 {
@@ -2029,6 +2125,9 @@ APFloat::convertToAPInt() const
   if (semantics == (const llvm::fltSemantics* const)&IEEEdouble)
     return convertDoubleAPFloatToAPInt();
 
+  if (semantics == (const llvm::fltSemantics* const)&PPCDoubleDouble)
+    return convertPPCDoubleDoubleAPFloatToAPInt();
+
   assert(semantics == (const llvm::fltSemantics* const)&x87DoubleExtended &&
          "unknown format!");
   return convertF80LongDoubleAPFloatToAPInt();
@@ -2090,6 +2189,56 @@ APFloat::initFromF80LongDoubleAPInt(const APInt &api)
   }
 }
 
+void
+APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api)
+{
+  assert(api.getBitWidth()==128);
+  uint64_t i1 = api.getRawData()[0];
+  uint64_t i2 = api.getRawData()[1];
+  uint64_t myexponent = (i1 >> 52) & 0x7ff;
+  uint64_t mysignificand = i1 & 0xfffffffffffffLL;
+  uint64_t myexponent2 = (i2 >> 52) & 0x7ff;
+  uint64_t mysignificand2 = i2 & 0xfffffffffffffLL;
+
+  initialize(&APFloat::PPCDoubleDouble);
+  assert(partCount()==2);
+
+  sign = i1>>63;
+  sign2 = i2>>63;
+  if (myexponent==0 && mysignificand==0) {
+    // exponent, significand meaningless
+    // exponent2 and significand2 are required to be 0; we don't check
+    category = fcZero;
+  } else if (myexponent==0x7ff && mysignificand==0) {
+    // exponent, significand meaningless
+    // exponent2 and significand2 are required to be 0; we don't check
+    category = fcInfinity;
+  } else if (myexponent==0x7ff && mysignificand!=0) {
+    // exponent meaningless.  So is the whole second word, but keep it 
+    // for determinism.
+    category = fcNaN;
+    exponent2 = myexponent2;
+    significandParts()[0] = mysignificand;
+    significandParts()[1] = mysignificand2;
+  } else {
+    category = fcNormal;
+    // Note there is no category2; the second word is treated as if it is
+    // fcNormal, although it might be something else considered by itself.
+    exponent = myexponent - 1023;
+    exponent2 = myexponent2 - 1023;
+    significandParts()[0] = mysignificand;
+    significandParts()[1] = mysignificand2;
+    if (myexponent==0)          // denormal
+      exponent = -1022;
+    else
+      significandParts()[0] |= 0x10000000000000LL;  // integer bit
+    if (myexponent2==0) 
+      exponent2 = -1022;
+    else
+      significandParts()[1] |= 0x10000000000000LL;  // integer bit
+  }
+}
+
 void
 APFloat::initFromDoubleAPInt(const APInt &api)
 {
@@ -2157,11 +2306,11 @@ APFloat::initFromFloatAPInt(const APInt & api)
 }
 
 /// Treat api as containing the bits of a floating point number.  Currently
-/// we infer the floating point type from the size of the APInt.  FIXME: This
-/// breaks when we get to PPC128 and IEEE128 (but both cannot exist in the
-/// same compile...)
+/// we infer the floating point type from the size of the APInt.  The
+/// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful
+/// when the size is anything else).
 void
-APFloat::initFromAPInt(const APInt& api)
+APFloat::initFromAPInt(const APInt& api, bool isIEEE)
 {
   if (api.getBitWidth() == 32)
     return initFromFloatAPInt(api);
@@ -2169,13 +2318,15 @@ APFloat::initFromAPInt(const APInt& api)
     return initFromDoubleAPInt(api);
   else if (api.getBitWidth()==80)
     return initFromF80LongDoubleAPInt(api);
+  else if (api.getBitWidth()==128 && !isIEEE)
+    return initFromPPCDoubleDoubleAPInt(api);
   else
     assert(0);
 }
 
-APFloat::APFloat(const APInt& api)
+APFloat::APFloat(const APInt& api, bool isIEEE)
 {
-  initFromAPInt(api);
+  initFromAPInt(api, isIEEE);
 }
 
 APFloat::APFloat(float f)
index 6fb55165be7e70cf8f3aa7792c8e1dc4c67f3a29..9592151c6d924aed9b7865330e1c42882eb6f466 100644 (file)
@@ -519,6 +519,8 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
         Out << 'K';
       else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad)
         Out << 'L';
+      else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble)
+        Out << 'M';
       else
         assert(0 && "Unsupported floating point type");
       // api needed to prevent premature destruction
@@ -526,7 +528,7 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
       const uint64_t* p = api.getRawData();
       uint64_t word = *p;
       int shiftcount=60;
-      int width = CFP->getValueAPF().convertToAPInt().getBitWidth();
+      int width = api.getBitWidth();
       for (int j=0; j<width; j+=4, shiftcount-=4) {
         unsigned int nibble = (word>>shiftcount) & 15;
         if (nibble < 10)
@@ -535,7 +537,7 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
           Out << (unsigned char)(nibble - 10 + 'A');
         if (shiftcount == 0) {
           word = *(++p);
-          shiftcount = 60;
+          shiftcount = 64;
           if (width-j-4 < 64)
             shiftcount = width-j-4;
         }
index 7de823b1ba5f37f3f0bc36acc68e76c9cee9a587..350a306d797a968fa06c695b6e4f70de49400fb2 100644 (file)
@@ -114,6 +114,7 @@ Constant *Constant::getNullValue(const Type *Ty) {
   case Type::X86_FP80TyID:
     return ConstantFP::get(Ty, APFloat(APInt(80, 2, zero)));
   case Type::FP128TyID:
+    return ConstantFP::get(Ty, APFloat(APInt(128, 2, zero), true));
   case Type::PPC_FP128TyID:
     return ConstantFP::get(Ty, APFloat(APInt(128, 2, zero)));
   case Type::PointerTyID:
@@ -256,6 +257,8 @@ ConstantFP::ConstantFP(const Type *Ty, const APFloat& V)
     assert(&V.getSemantics()==&APFloat::x87DoubleExtended);
   else if (Ty==Type::FP128Ty)
     assert(&V.getSemantics()==&APFloat::IEEEquad);
+  else if (Ty==Type::PPC_FP128Ty)
+    assert(&V.getSemantics()==&APFloat::PPCDoubleDouble);
   else
     assert(0);
 }
@@ -320,6 +323,8 @@ ConstantFP *ConstantFP::get(const Type *Ty, const APFloat& V) {
     assert(&V.getSemantics()==&APFloat::x87DoubleExtended);
   else if (Ty==Type::FP128Ty)
     assert(&V.getSemantics()==&APFloat::IEEEquad);
+  else if (Ty==Type::PPC_FP128Ty)
+    assert(&V.getSemantics()==&APFloat::PPCDoubleDouble);
   else
     assert(0);
   
@@ -747,6 +752,10 @@ bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) {
     return &Val2.getSemantics() == &APFloat::IEEEsingle || 
            &Val2.getSemantics() == &APFloat::IEEEdouble ||
            &Val2.getSemantics() == &APFloat::IEEEquad;
+  case Type::PPC_FP128TyID:
+    return &Val2.getSemantics() == &APFloat::IEEEsingle || 
+           &Val2.getSemantics() == &APFloat::IEEEdouble ||
+           &Val2.getSemantics() == &APFloat::PPCDoubleDouble;
   }
 }