[llvm-commits] [llvm] r41858 - in /llvm/trunk: include/llvm/ADT/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/ lib/CodeGen/SelectionDAG/ lib/Support/ lib/Target/CBackend/ lib/Target/MSIL/ lib/Target/X86/ lib/VMCore/ tools/llvm2cpp/

Dale Johannesen dalej at apple.com
Tue Sep 11 11:32:34 PDT 2007


Author: johannes
Date: Tue Sep 11 13:32:33 2007
New Revision: 41858

URL: http://llvm.org/viewvc/llvm-project?rev=41858&view=rev
Log:
Add APInt interfaces to APFloat (allows directly
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).


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

Modified: llvm/trunk/include/llvm/ADT/APFloat.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/include/llvm/ADT/APFloat.h (original)
+++ llvm/trunk/include/llvm/ADT/APFloat.h Tue Sep 11 13:32:33 2007
@@ -170,6 +170,7 @@
     APFloat(const fltSemantics &, fltCategory, bool negative);
     APFloat(double d);
     APFloat(float f);
+    APFloat(const APInt &);
     APFloat(const APFloat &);
     ~APFloat();
 
@@ -191,6 +192,7 @@
     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 @@
 					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 &);

Modified: llvm/trunk/lib/AsmParser/Lexer.l
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/Lexer.l?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/lib/AsmParser/Lexer.l (original)
+++ llvm/trunk/lib/AsmParser/Lexer.l Tue Sep 11 13:32:33 2007
@@ -91,14 +91,40 @@
   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 @@
 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 @@
 {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

Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.y?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/lib/AsmParser/llvmAsmParser.y (original)
+++ llvm/trunk/lib/AsmParser/llvmAsmParser.y Tue Sep 11 13:32:33 2007
@@ -416,9 +416,10 @@
       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 @@
   | 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;

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Tue Sep 11 13:32:33 2007
@@ -622,23 +622,24 @@
                                  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())

Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Tue Sep 11 13:32:33 2007
@@ -527,13 +527,20 @@
       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!");
       }

Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter.cpp?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter.cpp Tue Sep 11 13:32:33 2007
@@ -830,29 +830,31 @@
     // 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;
     }

Modified: llvm/trunk/lib/CodeGen/MachOWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachOWriter.cpp?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/MachOWriter.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachOWriter.cpp Tue Sep 11 13:32:33 2007
@@ -861,8 +861,8 @@
         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 @@
         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;

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Sep 11 13:32:33 2007
@@ -3800,7 +3800,8 @@
       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 @@
         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 @@
           // 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);

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Sep 11 13:32:33 2007
@@ -491,8 +491,9 @@
   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 @@
       // 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);

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Sep 11 13:32:33 2007
@@ -109,13 +109,12 @@
   } 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 @@
     }
     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;
     }
   }

Modified: llvm/trunk/lib/Support/APFloat.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/lib/Support/APFloat.cpp (original)
+++ llvm/trunk/lib/Support/APFloat.cpp Tue Sep 11 13:32:33 2007
@@ -339,7 +339,8 @@
 unsigned int
 APFloat::partCount() const
 {
-  return partCountForBits(semantics->precision + 1);
+  return partCountForBits(semantics->precision + 
+                          semantics->implicitIntegerBit ? 1 : 0);
 }
 
 unsigned int
@@ -1593,8 +1594,41 @@
 // 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 @@
   } 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 @@
   } 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(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 @@
       *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));
+}
+

Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original)
+++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Tue Sep 11 13:32:33 2007
@@ -1715,13 +1715,16 @@
 
         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!");

Modified: llvm/trunk/lib/Target/MSIL/MSILWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSIL/MSILWriter.cpp?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/lib/Target/MSIL/MSILWriter.cpp (original)
+++ llvm/trunk/lib/Target/MSIL/MSILWriter.cpp Tue Sep 11 13:32:33 2007
@@ -428,10 +428,10 @@
     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 @@
     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:

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Sep 11 13:32:33 2007
@@ -3410,11 +3410,11 @@
   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 @@
   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 @@
   // 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 @@
   // 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);

Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/ConstantFold.cpp (original)
+++ llvm/trunk/lib/VMCore/ConstantFold.cpp Tue Sep 11 13:32:33 2007
@@ -87,9 +87,8 @@
     
     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 @@
 
     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 @@
 
       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 @@
     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;

Modified: llvm/trunk/tools/llvm2cpp/CppWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm2cpp/CppWriter.cpp?rev=41858&r1=41857&r2=41858&view=diff

==============================================================================
--- llvm/trunk/tools/llvm2cpp/CppWriter.cpp (original)
+++ llvm/trunk/tools/llvm2cpp/CppWriter.cpp Tue Sep 11 13:32:33 2007
@@ -250,11 +250,11 @@
       }
     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





More information about the llvm-commits mailing list