Add APInt interfaces to APFloat (allows directly
authorDale Johannesen <dalej@apple.com>
Tue, 11 Sep 2007 18:32:33 +0000 (18:32 +0000)
committerDale Johannesen <dalej@apple.com>
Tue, 11 Sep 2007 18:32:33 +0000 (18:32 +0000)
access to bits).  Use them in place of float and
double interfaces where appropriate.
First bits of x86 long double constants handling
(untested, probably does not work).

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

16 files changed:
include/llvm/ADT/APFloat.h
lib/AsmParser/Lexer.l
lib/AsmParser/llvmAsmParser.y
lib/Bitcode/Reader/BitcodeReader.cpp
lib/Bitcode/Writer/BitcodeWriter.cpp
lib/CodeGen/AsmPrinter.cpp
lib/CodeGen/MachOWriter.cpp
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/Support/APFloat.cpp
lib/Target/CBackend/CBackend.cpp
lib/Target/MSIL/MSILWriter.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/VMCore/ConstantFold.cpp
tools/llvm2cpp/CppWriter.cpp

index 83c370eb74595a5862a87e2abd27fadff02e3d6b..baa9de025789103d1da2ddfe9064efbb1c0ccc46 100644 (file)
@@ -170,6 +170,7 @@ namespace llvm {
     APFloat(const fltSemantics &, fltCategory, bool negative);
     APFloat(double d);
     APFloat(float f);
+    APFloat(const APInt &);
     APFloat(const APFloat &);
     ~APFloat();
 
@@ -191,6 +192,7 @@ namespace llvm {
     opStatus convertFromInteger(const integerPart *, unsigned int, bool,
                                roundingMode);
     opStatus convertFromString(const char *, roundingMode);
+    APInt convertToAPInt() const;
     double convertToDouble() const;
     float convertToFloat() const;
 
@@ -256,6 +258,13 @@ namespace llvm {
                                        roundingMode);
     lostFraction combineLostFractions(lostFraction, lostFraction);
     opStatus convertFromHexadecimalString(const char *, roundingMode);
+    APInt convertFloatAPFloatToAPInt() const;
+    APInt convertDoubleAPFloatToAPInt() const;
+    APInt convertF80LongDoubleAPFloatToAPInt() const;
+    void initFromAPInt(const APInt& api);
+    void initFromFloatAPInt(const APInt& api);
+    void initFromDoubleAPInt(const APInt& api);
+    void initFromF80LongDoubleAPInt(const APInt& api);
 
     void assign(const APFloat &);
     void copySignificand(const APFloat &);
index 390544d8c3d99f4f1a6b641e59a01e39b32137ef..5acbbacf60fdb7ce2b69edbcb0d1b45890c5bc4d 100644 (file)
@@ -91,14 +91,40 @@ static uint64_t HexIntToVal(const char *Buffer) {
   return Result;
 }
 
-
-// HexToFP - Convert the ascii string in hexidecimal format to the floating
+// HexToFP - Convert the ascii string in hexadecimal format to the floating
 // point representation of it.
 //
 static double HexToFP(const char *Buffer) {
   return BitsToDouble(HexIntToVal(Buffer));   // Cast Hex constant to double
 }
 
+static void HexToIntPair(const char *Buffer, uint64_t Pair[2]) {
+  Pair[0] = 0;
+  for (int i=0; i<16; i++, Buffer++) {
+    assert(*Buffer);
+    Pair[0] *= 16;
+    char C = *Buffer;
+    if (C >= '0' && C <= '9')
+      Pair[0] += C-'0';
+    else if (C >= 'A' && C <= 'F')
+      Pair[0] += C-'A'+10;
+    else if (C >= 'a' && C <= 'f')
+      Pair[0] += C-'a'+10;
+  }
+  Pair[1] = 0;
+  for (int i=0; i<16 && *Buffer; i++, Buffer++) {
+    Pair[1] *= 16;
+    char C = *Buffer;
+    if (C >= '0' && C <= '9')
+      Pair[1] += C-'0';
+    else if (C >= 'A' && C <= 'F')
+      Pair[1] += C-'A'+10;
+    else if (C >= 'a' && C <= 'f')
+      Pair[1] += C-'a'+10;
+  }
+  if (*Buffer)
+    GenerateError("constant bigger than 128 bits detected!");
+}
 
 // UnEscapeLexed - Run through the specified buffer and change \xx codes to the
 // appropriate character.
@@ -163,15 +189,28 @@ IntegerType i[0-9]+
 PInteger   [0-9]+
 NInteger  -[0-9]+
 
-/* FPConstant - A Floating point constant.
+/* FPConstant - A Floating point constant.  Float and double only.
  */
 FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
 
 /* HexFPConstant - Floating point constant represented in IEEE format as a
  *  hexadecimal number for when exponential notation is not precise enough.
+ *  Float and double only.
  */
 HexFPConstant 0x[0-9A-Fa-f]+
 
+/* F80HexFPConstant - x87 long double in hexadecimal format (10 bytes)
+ */
+HexFP80Constant 0xK[0-9A-Fa-f]+
+
+/* F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes)
+ */
+HexFP128Constant 0xL[0-9A-Fa-f]+
+
+/* PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes)
+ */
+HexPPC128Constant 0xM[0-9A-Fa-f]+
+
 /* HexIntConstant - Hexadecimal constant generated by the CFE to avoid forcing
  * it to deal with 64 bit numbers.
  */
@@ -441,6 +480,21 @@ shufflevector   { RET_TOK(OtherOpVal, ShuffleVector, SHUFFLEVECTOR); }
 {HexFPConstant} { llvmAsmlval.FPVal = new APFloat(HexToFP(yytext)); 
                   return FPVAL; 
                 }
+{HexFP80Constant} { uint64_t Pair[2];
+                    HexToIntPair(yytext, Pair);
+                    llvmAsmlval.FPVal = new APFloat(APInt(80, 2, Pair));
+                    return FPVAL;
+                }
+{HexFP128Constant} { uint64_t Pair[2];
+                    HexToIntPair(yytext, Pair);
+                    llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair));
+                    return FPVAL;
+                }
+{HexPPC128Constant} { uint64_t Pair[2];
+                    HexToIntPair(yytext, Pair);
+                    llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair));
+                    return FPVAL;
+                }
 
 <<EOF>>         {
                   /* Make sure to free the internal buffers for flex when we are
index 6364b29bcd77d53f850fd7361ed77945c0ae99b4..c0374daf3f1c02d236266f7e2ab2e101ff907383 100644 (file)
@@ -416,9 +416,10 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) {
       GenerateError("FP constant invalid for type");
       return 0;
     }
-    // Lexer has no type info, so builds all FP constants as double.
-    // Fix this here.
-    if (Ty==Type::FloatTy)
+    // Lexer has no type info, so builds all float and double  FP constants 
+    // as double.  Fix this here.  Long double does not need this.
+    if (&D.ConstPoolFP->getSemantics() == &APFloat::IEEEdouble &&
+        Ty==Type::FloatTy)
       D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven);
     return ConstantFP::get(Ty, *D.ConstPoolFP);
 
@@ -1868,9 +1869,9 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
   | FPType FPVAL {                   // Float & Double constants
     if (!ConstantFP::isValueValidForType($1, *$2))
       GEN_ERROR("Floating point constant invalid for type");
-    // Lexer has no type info, so builds all FP constants as double.
-    // Fix this here.
-    if ($1==Type::FloatTy)
+    // Lexer has no type info, so builds all float and double FP constants 
+    // as double.  Fix this here.  Long double is done right.
+    if (&$2->getSemantics()==&APFloat::IEEEdouble && $1==Type::FloatTy)
       $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven);
     $$ = ConstantFP::get($1, *$2);
     delete $2;
index 8715f89c2574b044207e5251200bc66691d1a74c..06429931dbdf33353618afb016aa4a1d3d44a97e 100644 (file)
@@ -622,23 +622,24 @@ bool BitcodeReader::ParseConstants() {
                                  NumWords, &Words[0]));
       break;
     }
-    case bitc::CST_CODE_FLOAT:     // FLOAT: [fpval]
+    case bitc::CST_CODE_FLOAT: {    // FLOAT: [fpval]
       if (Record.empty())
         return Error("Invalid FLOAT record");
       if (CurTy == Type::FloatTy)
-        V = ConstantFP::get(CurTy, APFloat(BitsToFloat(Record[0])));
+        V = ConstantFP::get(CurTy, APFloat(APInt(32, (uint32_t)Record[0])));
       else if (CurTy == Type::DoubleTy)
-        V = ConstantFP::get(CurTy, APFloat(BitsToDouble(Record[0])));
+        V = ConstantFP::get(CurTy, APFloat(APInt(64, Record[0])));
       // FIXME: Make long double constants work.  BitsToDouble does not make it.
       else if (CurTy == Type::X86_FP80Ty)
-        V = ConstantFP::get(CurTy, APFloat(BitsToDouble(Record[0])));
+        V = ConstantFP::get(CurTy, APFloat(APInt(80, 2, &Record[0])));
       else if (CurTy == Type::FP128Ty)
-        V = ConstantFP::get(CurTy, APFloat(BitsToDouble(Record[0])));
+        V = ConstantFP::get(CurTy, APFloat(APInt(128, 2, &Record[0])));
       else if (CurTy == Type::PPC_FP128Ty)
         assert(0 && "PowerPC long double constants not handled yet.");
       else
         V = UndefValue::get(CurTy);
       break;
+    }
       
     case bitc::CST_CODE_AGGREGATE: {// AGGREGATE: [n x value number]
       if (Record.empty())
index 73f5338dccebaafcbc51293146a129aa4501a07a..78a16d8f627378af4b495caad04dc90fc52bec9a 100644 (file)
@@ -527,13 +527,20 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
       Code = bitc::CST_CODE_FLOAT;
       const Type *Ty = CFP->getType();
       if (Ty == Type::FloatTy)
-        Record.push_back(FloatToBits(CFP->getValueAPF().convertToFloat()));
+        Record.push_back((uint32_t)*CFP->getValueAPF().convertToAPInt().
+                                      getRawData());
       else if (Ty == Type::DoubleTy) {
-        Record.push_back(DoubleToBits(CFP->getValueAPF().convertToDouble()));
-      // FIXME: make long double constants work.
-      } else if (Ty == Type::X86_FP80Ty ||
-                 Ty == Type::FP128Ty || Ty == Type::PPC_FP128Ty) {
-        assert (0 && "Long double constants not handled yet.");
+        Record.push_back(*CFP->getValueAPF().convertToAPInt().getRawData());
+      } else if (Ty == Type::X86_FP80Ty) {
+        const uint64_t *p = CFP->getValueAPF().convertToAPInt().getRawData();
+        Record.push_back(p[0]);
+        Record.push_back((uint16_t)p[1]);
+      } else if (Ty == Type::FP128Ty) {
+        const uint64_t *p = CFP->getValueAPF().convertToAPInt().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 e80afd40eeda1d1145d05af1836a09c90aeb1ebf..49bcba7814182a1d38cbe707a1929df9c02ca495 100644 (file)
@@ -830,29 +830,31 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
     // FP Constants are printed as integer constants to avoid losing
     // precision...
     if (CFP->getType() == Type::DoubleTy) {
-      double Val = CFP->getValueAPF().convertToDouble();
+      double Val = CFP->getValueAPF().convertToDouble();  // for comment only
+      uint64_t i = *CFP->getValueAPF().convertToAPInt().getRawData();
       if (TAI->getData64bitsDirective())
-        O << TAI->getData64bitsDirective() << DoubleToBits(Val) << "\t"
+        O << TAI->getData64bitsDirective() << i << "\t"
           << TAI->getCommentString() << " double value: " << Val << "\n";
       else if (TD->isBigEndian()) {
-        O << TAI->getData32bitsDirective() << unsigned(DoubleToBits(Val) >> 32)
+        O << TAI->getData32bitsDirective() << unsigned(i >> 32)
           << "\t" << TAI->getCommentString()
           << " double most significant word " << Val << "\n";
-        O << TAI->getData32bitsDirective() << unsigned(DoubleToBits(Val))
+        O << TAI->getData32bitsDirective() << unsigned(i)
           << "\t" << TAI->getCommentString()
           << " double least significant word " << Val << "\n";
       } else {
-        O << TAI->getData32bitsDirective() << unsigned(DoubleToBits(Val))
+        O << TAI->getData32bitsDirective() << unsigned(i)
           << "\t" << TAI->getCommentString()
           << " double least significant word " << Val << "\n";
-        O << TAI->getData32bitsDirective() << unsigned(DoubleToBits(Val) >> 32)
+        O << TAI->getData32bitsDirective() << unsigned(i >> 32)
           << "\t" << TAI->getCommentString()
           << " double most significant word " << Val << "\n";
       }
       return;
     } else {
-      float Val = CFP->getValueAPF().convertToFloat();
-      O << TAI->getData32bitsDirective() << FloatToBits(Val)
+      float Val = CFP->getValueAPF().convertToFloat();  // for comment only
+      O << TAI->getData32bitsDirective()
+        << (uint32_t)*CFP->getValueAPF().convertToAPInt().getRawData()
         << "\t" << TAI->getCommentString() << " float " << Val << "\n";
       return;
     }
index af2555d3eed92cdddb5fc7baf574cbca9014762c..1c9b0feff54e34ef8af29fa997c697bf45250727 100644 (file)
@@ -861,8 +861,8 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
         break;
       }
       case Type::FloatTyID: {
-        uint64_t val = FloatToBits(cast<ConstantFP>(PC)->
-                                   getValueAPF().convertToFloat());
+        uint32_t val = (uint32_t)*cast<ConstantFP>(PC)->
+                                  getValueAPF().convertToAPInt().getRawData();
         if (TD->isBigEndian())
           val = ByteSwap_32(val);
         ptr[0] = val;
@@ -872,8 +872,8 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
         break;
       }
       case Type::DoubleTyID: {
-        uint64_t val = DoubleToBits(cast<ConstantFP>(PC)->
-                                    getValueAPF().convertToDouble());
+        uint64_t val = *cast<ConstantFP>(PC)->getValueAPF().convertToAPInt().
+                         getRawData();
         if (TD->isBigEndian())
           val = ByteSwap_64(val);
         ptr[0] = val;
index 32f81d38f266e96517b0da435d4cf14b739f1fa3..2050d23ad72b6c21504bb356f31171ec823f9c34 100644 (file)
@@ -3800,7 +3800,8 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
       default: assert(0 && "Unknown FP type");
       case MVT::f32:
         if (!AfterLegalize || TLI.isTypeLegal(MVT::i32)) {
-          Tmp = DAG.getConstant(FloatToBits(CFP->getValueAPF().convertToFloat()), MVT::i32);
+          Tmp = DAG.getConstant((uint32_t)*CFP->getValueAPF().
+                              convertToAPInt().getRawData(), MVT::i32);
           return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(),
                               ST->getSrcValueOffset(), ST->isVolatile(),
                               ST->getAlignment());
@@ -3808,7 +3809,8 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
         break;
       case MVT::f64:
         if (!AfterLegalize || TLI.isTypeLegal(MVT::i64)) {
-          Tmp = DAG.getConstant(DoubleToBits(CFP->getValueAPF().convertToDouble()), MVT::i64);
+          Tmp = DAG.getConstant(*CFP->getValueAPF().convertToAPInt().
+                                  getRawData(), MVT::i64);
           return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(),
                               ST->getSrcValueOffset(), ST->isVolatile(),
                               ST->getAlignment());
@@ -3816,7 +3818,7 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
           // Many FP stores are not make apparent until after legalize, e.g. for
           // argument passing.  Since this is so common, custom legalize the
           // 64-bit integer store into two 32-bit stores.
-          uint64_t Val = DoubleToBits(CFP->getValueAPF().convertToDouble());
+          uint64_t Val = *CFP->getValueAPF().convertToAPInt().getRawData();
           SDOperand Lo = DAG.getConstant(Val & 0xFFFFFFFF, MVT::i32);
           SDOperand Hi = DAG.getConstant(Val >> 32, MVT::i32);
           if (!TLI.isLittleEndian()) std::swap(Lo, Hi);
index 31e29470e803b00ebc945558683c115477634b15..d7eb85bd8fb06208fdebeb8ea1bc9badf59565c9 100644 (file)
@@ -491,8 +491,9 @@ static SDOperand ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP,
   if (!UseCP) {
     const APFloat& Val = LLVMC->getValueAPF();
     return isDouble
-      ? DAG.getConstant(DoubleToBits(Val.convertToDouble()), MVT::i64)
-      : DAG.getConstant(FloatToBits(Val.convertToFloat()), MVT::i32);
+      ? DAG.getConstant(*Val.convertToAPInt().getRawData(), MVT::i64)
+      : DAG.getConstant((uint32_t )*Val.convertToAPInt().getRawData(), 
+                        MVT::i32);
   }
 
   if (isDouble && CFP->isValueValidForType(MVT::f32, CFP->getValueAPF()) &&
@@ -1980,12 +1981,13 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       // together.
       if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(ST->getValue())) {
         if (CFP->getValueType(0) == MVT::f32) {
-          Tmp3 = DAG.getConstant(FloatToBits(CFP->getValueAPF().
-                                             convertToFloat()), MVT::i32);
+          Tmp3 = DAG.getConstant((uint32_t)*CFP->getValueAPF().
+                                          convertToAPInt().getRawData(),
+                                  MVT::i32);
         } else {
           assert(CFP->getValueType(0) == MVT::f64 && "Unknown FP type!");
-          Tmp3 = DAG.getConstant(DoubleToBits(CFP->getValueAPF().
-                                              convertToDouble()), MVT::i64);
+          Tmp3 = DAG.getConstant(*CFP->getValueAPF().convertToAPInt().
+                                   getRawData(), MVT::i64);
         }
         Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
                               SVOffset, isVolatile, Alignment);
index 01ec5c968aa04956508ecd45f90805a912f6cde2..85a76f436b1b421393e2d076b1c9696227effde6 100644 (file)
@@ -109,13 +109,12 @@ bool ISD::isBuildVectorAllOnes(const SDNode *N) {
   } else if (isa<ConstantFPSDNode>(NotZero)) {
     MVT::ValueType VT = NotZero.getValueType();
     if (VT== MVT::f64) {
-      if (DoubleToBits(cast<ConstantFPSDNode>(NotZero)->
-                       getValueAPF().convertToDouble()) !=
-          (uint64_t)-1)
+      if (*((cast<ConstantFPSDNode>(NotZero)->getValueAPF().
+                  convertToAPInt().getRawData())) != (uint64_t)-1)
         return false;
     } else {
-      if (FloatToBits(cast<ConstantFPSDNode>(NotZero)->
-                      getValueAPF().convertToFloat()) !=
+      if ((uint32_t)*cast<ConstantFPSDNode>(NotZero)->
+                      getValueAPF().convertToAPInt().getRawData() != 
           (uint32_t)-1)
         return false;
     }
@@ -1698,9 +1697,9 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
     }
     case ISD::BIT_CONVERT:
       if (VT == MVT::i32 && C->getValueType(0) == MVT::f32)
-        return getConstant(FloatToBits(V.convertToFloat()), VT);
+        return getConstant((uint32_t)*V.convertToAPInt().getRawData(), VT);
       else if (VT == MVT::i64 && C->getValueType(0) == MVT::f64)
-        return getConstant(DoubleToBits(V.convertToDouble()), VT);
+        return getConstant(*V.convertToAPInt().getRawData(), VT);
       break;
     }
   }
index 9b8caa89ffcbf9397a3414562894f3f9111d49a7..96fdc42fb26a5c4503139a34ecd49674530bef5f 100644 (file)
@@ -339,7 +339,8 @@ APFloat::~APFloat()
 unsigned int
 APFloat::partCount() const
 {
-  return partCountForBits(semantics->precision + 1);
+  return partCountForBits(semantics->precision + 
+                          semantics->implicitIntegerBit ? 1 : 0);
 }
 
 unsigned int
@@ -1593,8 +1594,41 @@ APFloat::getHashValue() const {
 // Denormals have exponent minExponent in APFloat, but minExponent-1 in
 // the actual IEEE respresentation.  We compensate for that here.
 
-double
-APFloat::convertToDouble() const {
+APInt
+APFloat::convertF80LongDoubleAPFloatToAPInt() const {
+  assert(semantics == (const llvm::fltSemantics* const)&x87DoubleExtended);
+  assert (partCount()==1);
+
+  uint64_t myexponent, mysignificand;
+
+  if (category==fcNormal) {
+    myexponent = exponent+16383; //bias
+    mysignificand = *significandParts();
+    if (myexponent==1 && !(mysignificand & 0x8000000000000000ULL))
+      myexponent = 0;   // denormal
+  } else if (category==fcZero) {
+    myexponent = 0;
+    mysignificand = 0;
+  } else if (category==fcInfinity) {
+    myexponent = 0x7fff;
+    mysignificand = 0x8000000000000000ULL;
+  } else if (category==fcNaN) {
+    myexponent = 0x7fff;
+    mysignificand = *significandParts();
+  } else
+    assert(0);
+
+  uint64_t words[2];
+  words[0] =  (((uint64_t)sign & 1) << 63) | 
+              ((myexponent & 0x7fff) <<  48) | 
+              ((mysignificand >>16) & 0xffffffffffffLL);
+  words[1] = mysignificand & 0xffff;
+  APInt api(80, 2, words);
+  return api;
+}
+
+APInt
+APFloat::convertDoubleAPFloatToAPInt() const {
   assert(semantics == (const llvm::fltSemantics* const)&IEEEdouble);
   assert (partCount()==1);
 
@@ -1617,16 +1651,17 @@ APFloat::convertToDouble() const {
   } else
     assert(0);
 
-  return BitsToDouble((((uint64_t)sign & 1) << 63) | 
-        ((myexponent & 0x7ff) <<  52) | 
-        (mysignificand & 0xfffffffffffffLL));
+  APInt api(64, (((((uint64_t)sign & 1) << 63) | 
+                 ((myexponent & 0x7ff) <<  52) | 
+                 (mysignificand & 0xfffffffffffffLL))));
+  return api;
 }
 
-float
-APFloat::convertToFloat() const {
+APInt
+APFloat::convertFloatAPFloatToAPInt() const {
   assert(semantics == (const llvm::fltSemantics* const)&IEEEsingle);
   assert (partCount()==1);
-
+  
   uint32_t myexponent, mysignificand;
 
   if (category==fcNormal) {
@@ -1646,12 +1681,78 @@ APFloat::convertToFloat() const {
   } else
     assert(0);
 
-  return BitsToFloat(((sign&1) << 31) | ((myexponent&0xff) << 23) | 
-        (mysignificand & 0x7fffff));
+  APInt api(32, (((sign&1) << 31) | ((myexponent&0xff) << 23) | 
+                 (mysignificand & 0x7fffff)));
+  return api;
 }
 
-APFloat::APFloat(double d) {
-  uint64_t i = DoubleToBits(d);
+APInt
+APFloat::convertToAPInt() const {
+  if (semantics == (const llvm::fltSemantics* const)&IEEEsingle)
+    return convertFloatAPFloatToAPInt();
+  else if (semantics == (const llvm::fltSemantics* const)&IEEEdouble)
+    return convertDoubleAPFloatToAPInt();
+  else if (semantics == (const llvm::fltSemantics* const)&x87DoubleExtended)
+    return convertF80LongDoubleAPFloatToAPInt();
+  else 
+    assert(0);
+}
+
+float 
+APFloat::convertToFloat() const {
+  assert(semantics == (const llvm::fltSemantics* const)&IEEEsingle);
+  APInt api = convertToAPInt();
+  return api.bitsToFloat();
+}
+
+double 
+APFloat::convertToDouble() const {
+  assert(semantics == (const llvm::fltSemantics* const)&IEEEdouble);
+  APInt api = convertToAPInt();
+  return api.bitsToDouble();
+}
+
+/// Integer bit is explicit in this format.  Current Intel book does not
+/// define meaning of:
+///  exponent = all 1's, integer bit not set.
+///  exponent = 0, integer bit set. (formerly "psuedodenormals")
+///  exponent!=0 nor all 1's, integer bit not set. (formerly "unnormals")
+void
+APFloat::initFromF80LongDoubleAPInt(const APInt &api) {
+  assert(api.getBitWidth()==80);
+  uint64_t i1 = api.getRawData()[0];
+  uint64_t i2 = api.getRawData()[1];
+  uint64_t myexponent = (i1 >> 48) & 0x7fff;
+  uint64_t mysignificand = ((i1 << 16) &  0xffffffffffff0000ULL) |
+                          (i2 & 0xffff);
+
+  initialize(&APFloat::x87DoubleExtended);
+  assert(partCount()==1);
+
+  sign = i1>>63;
+  if (myexponent==0 && mysignificand==0) {
+    // exponent, significand meaningless
+    category = fcZero;
+  } else if (myexponent==0x7fff && mysignificand==0x8000000000000000ULL) {
+    // exponent, significand meaningless
+    category = fcInfinity;
+  } else if (myexponent==0x7fff && mysignificand!=0x8000000000000000ULL) {
+    // exponent meaningless
+    category = fcNaN;
+    *significandParts() = mysignificand;
+  } else {
+    category = fcNormal;
+    exponent = myexponent - 16383;
+    *significandParts() = mysignificand;
+    if (myexponent==0)          // denormal
+      exponent = -16382;
+ }
+}
+
+void
+APFloat::initFromDoubleAPInt(const APInt &api) {
+  assert(api.getBitWidth()==64);
+  uint64_t i = *api.getRawData();
   uint64_t myexponent = (i >> 52) & 0x7ff;
   uint64_t mysignificand = i & 0xfffffffffffffLL;
 
@@ -1680,8 +1781,10 @@ APFloat::APFloat(double d) {
  }
 }
 
-APFloat::APFloat(float f) {
-  uint32_t i = FloatToBits(f);
+void
+APFloat::initFromFloatAPInt(const APInt & api) {
+  assert(api.getBitWidth()==32);
+  uint32_t i = (uint32_t)*api.getRawData();
   uint32_t myexponent = (i >> 23) & 0xff;
   uint32_t mysignificand = i & 0x7fffff;
 
@@ -1709,3 +1812,34 @@ APFloat::APFloat(float f) {
       *significandParts() |= 0x800000; // integer bit
   }
 }
+
+/// 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...)
+void
+APFloat::initFromAPInt(const APInt& api) {
+  if (api.getBitWidth() == 32)
+    return initFromFloatAPInt(api);
+  else if (api.getBitWidth()==64)
+    return initFromDoubleAPInt(api);
+  else if (api.getBitWidth()==80)
+    return initFromF80LongDoubleAPInt(api);
+  else
+    assert(0);
+}
+
+APFloat::APFloat(const APInt& api) {
+  initFromAPInt(api);
+}
+
+APFloat::APFloat(float f) {
+  APInt api = APInt(32, 0);
+  initFromAPInt(api.floatToBits(f));
+}
+
+APFloat::APFloat(double d) {
+  APInt api = APInt(64, 0);
+  initFromAPInt(api.doubleToBits(d));
+}
+
index 0221174e5cfd6f0f65562cb257a36154dc083d4d..f25b1133b24d5a2206669a06ba973b9b6d96c8c3 100644 (file)
@@ -1715,13 +1715,16 @@ void CWriter::printFloatingPointConstants(Function &F) {
 
         if (FPC->getType() == Type::DoubleTy) {
           double Val = FPC->getValueAPF().convertToDouble();
+          uint64_t i = *FPC->getValueAPF().convertToAPInt().getRawData();
           Out << "static const ConstantDoubleTy FPConstant" << FPCounter++
-              << " = 0x" << std::hex << DoubleToBits(Val) << std::dec
+              << " = 0x" << std::hex << i << std::dec
               << "ULL;    /* " << Val << " */\n";
         } else if (FPC->getType() == Type::FloatTy) {
           float Val = FPC->getValueAPF().convertToFloat();
+          uint32_t i = (uint32_t)*FPC->getValueAPF().convertToAPInt().
+                                    getRawData();
           Out << "static const ConstantFloatTy FPConstant" << FPCounter++
-              << " = 0x" << std::hex << FloatToBits(Val) << std::dec
+              << " = 0x" << std::hex << i << std::dec
               << "U;    /* " << Val << " */\n";
         } else
           assert(0 && "Unknown float type!");
index 71789703ff39ab12d0a89fa51f72cfdca10f5e80..cd67df17a6fbae2b75e4c48cec901650f0cbcd31 100644 (file)
@@ -428,10 +428,10 @@ void MSILWriter::printConstLoad(const Constant* C) {
     uint64_t X;
     unsigned Size;
     if (FP->getType()->getTypeID()==Type::FloatTyID) {
-      X = FloatToBits(FP->getValueAPF().convertToFloat());
+      X = (uint32_t)*FP->getValueAPF().convertToAPInt().getRawData();
       Size = 4;  
     } else {
-      X = DoubleToBits(FP->getValueAPF().convertToDouble());
+      X = *FP->getValueAPF().convertToAPInt().getRawData();
       Size = 8;  
     }
     Out << "\tldc.r" << Size << "\t( " << utohexstr(X) << ')';
@@ -1473,10 +1473,10 @@ void MSILWriter::printStaticConstant(const Constant* C, uint64_t& Offset) {
     const ConstantFP* FP = cast<ConstantFP>(C);
     if (Ty->getTypeID() == Type::FloatTyID)
       Out << "int32 (" << 
-        FloatToBits(FP->getValueAPF().convertToFloat()) << ')';
+        (uint32_t)*FP->getValueAPF().convertToAPInt().getRawData() << ')';
     else
       Out << "int64 (" << 
-        DoubleToBits(FP->getValueAPF().convertToDouble()) << ')';
+        *FP->getValueAPF().convertToAPInt().getRawData() << ')';
     break;
   }
   case Type::ArrayTyID:
index 6d3bcf7bb51c19b7eb5ca979499cb3e2f7ef3a2b..95450ac97fac28b2bef11356e3663de00551aff0 100644 (file)
@@ -3410,11 +3410,11 @@ SDOperand X86TargetLowering::LowerFABS(SDOperand Op, SelectionDAG &DAG) {
   const Type *OpNTy =  MVT::getTypeForValueType(EltVT);
   std::vector<Constant*> CV;
   if (EltVT == MVT::f64) {
-    Constant *C = ConstantFP::get(OpNTy, APFloat(BitsToDouble(~(1ULL << 63))));
+    Constant *C = ConstantFP::get(OpNTy, APFloat(APInt(64, ~(1ULL << 63))));
     CV.push_back(C);
     CV.push_back(C);
   } else {
-    Constant *C = ConstantFP::get(OpNTy, APFloat(BitsToFloat(~(1U << 31))));
+    Constant *C = ConstantFP::get(OpNTy, APFloat(APInt(32, ~(1U << 31))));
     CV.push_back(C);
     CV.push_back(C);
     CV.push_back(C);
@@ -3438,11 +3438,11 @@ SDOperand X86TargetLowering::LowerFNEG(SDOperand Op, SelectionDAG &DAG) {
   const Type *OpNTy =  MVT::getTypeForValueType(EltVT);
   std::vector<Constant*> CV;
   if (EltVT == MVT::f64) {
-    Constant *C = ConstantFP::get(OpNTy, APFloat(BitsToDouble(1ULL << 63)));
+    Constant *C = ConstantFP::get(OpNTy, APFloat(APInt(64, 1ULL << 63)));
     CV.push_back(C);
     CV.push_back(C);
   } else {
-    Constant *C = ConstantFP::get(OpNTy, APFloat(BitsToFloat(1U << 31)));
+    Constant *C = ConstantFP::get(OpNTy, APFloat(APInt(32, 1U << 31)));
     CV.push_back(C);
     CV.push_back(C);
     CV.push_back(C);
@@ -3479,13 +3479,13 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
   // First get the sign bit of second operand.
   std::vector<Constant*> CV;
   if (SrcVT == MVT::f64) {
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(BitsToDouble(1ULL << 63))));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0)));
+    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(64, 1ULL << 63))));
+    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(64, 0))));
   } else {
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(BitsToFloat(1U << 31))));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0f)));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0f)));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0f)));
+    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, 1U << 31))));
+    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, 0))));
+    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, 0))));
+    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, 0))));
   }
   Constant *C = ConstantVector::get(CV);
   SDOperand CPIdx = DAG.getConstantPool(C, getPointerTy(), 4);
@@ -3507,13 +3507,13 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
   // Clear first operand sign bit.
   CV.clear();
   if (VT == MVT::f64) {
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(BitsToDouble(~(1ULL << 63)))));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0)));
+    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(64, ~(1ULL << 63)))));
+    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(64, 0))));
   } else {
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(BitsToFloat(~(1U << 31)))));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0f)));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0f)));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0f)));
+    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, ~(1U << 31)))));
+    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, 0))));
+    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, 0))));
+    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, 0))));
   }
   C = ConstantVector::get(CV);
   CPIdx = DAG.getConstantPool(C, getPointerTy(), 4);
index 4dc1340f908cc0ffc9c40b23471e81e4543fa666..e11b749f9be8f600f381077e224641cce8f474ed 100644 (file)
@@ -87,9 +87,8 @@ static Constant *CastConstantVector(ConstantVector *CV,
     
     if (SrcEltTy->getTypeID() == Type::DoubleTyID) {
       for (unsigned i = 0; i != SrcNumElts; ++i) {
-        uint64_t V =
-          DoubleToBits(cast<ConstantFP>(CV->getOperand(i))->
-                       getValueAPF().convertToDouble());
+        uint64_t V = *cast<ConstantFP>(CV->getOperand(i))->
+                       getValueAPF().convertToAPInt().getRawData();
         Constant *C = ConstantInt::get(Type::Int64Ty, V);
         Result.push_back(ConstantExpr::getBitCast(C, DstEltTy ));
       }
@@ -98,8 +97,8 @@ static Constant *CastConstantVector(ConstantVector *CV,
 
     assert(SrcEltTy->getTypeID() == Type::FloatTyID);
     for (unsigned i = 0; i != SrcNumElts; ++i) {
-      uint32_t V = FloatToBits(cast<ConstantFP>(CV->getOperand(i))->
-                               getValueAPF().convertToFloat());
+      uint32_t V = (uint32_t)*cast<ConstantFP>(CV->getOperand(i))->
+                               getValueAPF().convertToAPInt().getRawData();
       Constant *C = ConstantInt::get(Type::Int32Ty, V);
       Result.push_back(ConstantExpr::getBitCast(C, DstEltTy));
     }
@@ -333,9 +332,9 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
 
       if (DestTy->isFloatingPoint()) {
         if (DestTy == Type::FloatTy)
-          return ConstantFP::get(DestTy, APFloat(CI->getValue().bitsToFloat()));
+          return ConstantFP::get(DestTy, APFloat(CI->getValue()));
         assert(DestTy == Type::DoubleTy && "Unknown FP type!");
-        return ConstantFP::get(DestTy, APFloat(CI->getValue().bitsToDouble()));
+        return ConstantFP::get(DestTy, APFloat(CI->getValue()));
       }
       // Otherwise, can't fold this (vector?)
       return 0;
@@ -345,14 +344,10 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
     if (const ConstantFP *FP = dyn_cast<ConstantFP>(V)) {
       // FP -> Integral.
       if (DestTy == Type::Int32Ty) {
-        APInt Val(32, 0);
-        return ConstantInt::get(Val.floatToBits(FP->
-                                getValueAPF().convertToFloat()));
+        return ConstantInt::get(FP->getValueAPF().convertToAPInt());
       } else {
         assert(DestTy == Type::Int64Ty && "only support f32/f64 for now!");
-        APInt Val(64, 0);
-        return ConstantInt::get(Val.doubleToBits(FP->
-                                getValueAPF().convertToDouble()));
+        return ConstantInt::get(FP->getValueAPF().convertToAPInt());
       }
     }
     return 0;
index 1551dc3be780b35c1a5e6e0bb555af5686429196..a56c7cdd41a8186ed487d9fa75839d45eb5be5a7 100644 (file)
@@ -250,11 +250,11 @@ CppWriter::printCFP(const ConstantFP *CFP) {
       }
     else if (CFP->getType() == Type::DoubleTy)
       Out << "BitsToDouble(0x" << std::hex 
-          << DoubleToBits(CFP->getValueAPF().convertToDouble()) 
+          << *CFP->getValueAPF().convertToAPInt().getRawData()
           << std::dec << "ULL) /* " << StrVal << " */";
     else 
       Out << "BitsToFloat(0x" << std::hex 
-          << FloatToBits(CFP->getValueAPF().convertToFloat())
+          << (uint32_t)*CFP->getValueAPF().convertToAPInt().getRawData()
           << std::dec << "U) /* " << StrVal << " */";
     Out << ")";
 #if HAVE_PRINTF_A