[llvm-commits] [llvm] r67562 - in /llvm/trunk: lib/AsmParser/LLLexer.cpp lib/AsmParser/LLLexer.h lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Writer/BitcodeWriter.cpp lib/CodeGen/AsmPrinter/AsmPrinter.cpp lib/Support/APFloat.cpp lib/Target/CBackend/CBackend.cpp lib/VMCore/AsmWriter.cpp test/CodeGen/X86/2009-03-23-i80-fp80.ll

Dale Johannesen dalej at apple.com
Mon Mar 23 14:16:54 PDT 2009


Author: johannes
Date: Mon Mar 23 16:16:53 2009
New Revision: 67562

URL: http://llvm.org/viewvc/llvm-project?rev=67562&view=rev
Log:
Fix internal representation of fp80 to be the
same as a normal i80 {low64, high16} rather
than its own {high64, low16}.  A depressing number
of places know about this; I think I got them all.
Bitcode readers and writers convert back to the old
form to avoid breaking compatibility.


Added:
    llvm/trunk/test/CodeGen/X86/2009-03-23-i80-fp80.ll
Modified:
    llvm/trunk/lib/AsmParser/LLLexer.cpp
    llvm/trunk/lib/AsmParser/LLLexer.h
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/Support/APFloat.cpp
    llvm/trunk/lib/Target/CBackend/CBackend.cpp
    llvm/trunk/lib/VMCore/AsmWriter.cpp

Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=67562&r1=67561&r2=67562&view=diff

==============================================================================
--- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLLexer.cpp Mon Mar 23 16:16:53 2009
@@ -115,6 +115,37 @@
     Error("constant bigger than 128 bits detected!");
 }
 
+/// FP80HexToIntPair - translate an 80 bit FP80 number (20 hexits) into
+/// { low64, high16 } as usual for an APInt.
+void LLLexer::FP80HexToIntPair(const char *Buffer, const char *End,
+                           uint64_t Pair[2]) {
+  Pair[1] = 0;
+  for (int i=0; i<4 && Buffer != End; i++, Buffer++) {
+    assert(Buffer != End);
+    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;
+  }
+  Pair[0] = 0;
+  for (int i=0; i<16; i++, 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;
+  }
+  if (Buffer != End)
+    Error("constant bigger than 128 bits detected!");
+}
+
 // UnEscapeLexed - Run through the specified buffer and change \xx codes to the
 // appropriate character.
 static void UnEscapeLexed(std::string &Str) {
@@ -670,19 +701,21 @@
   }
 
   uint64_t Pair[2];
-  HexToIntPair(TokStart+3, CurPtr, Pair);
   switch (Kind) {
   default: assert(0 && "Unknown kind!");
   case 'K':
     // F80HexFPConstant - x87 long double in hexadecimal format (10 bytes)
+    FP80HexToIntPair(TokStart+3, CurPtr, Pair);
     APFloatVal = APFloat(APInt(80, 2, Pair));
     return lltok::APFloat;
   case 'L':
     // F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes)
+    HexToIntPair(TokStart+3, CurPtr, Pair);
     APFloatVal = APFloat(APInt(128, 2, Pair), true);
     return lltok::APFloat;
   case 'M':
     // PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes)
+    HexToIntPair(TokStart+3, CurPtr, Pair);
     APFloatVal = APFloat(APInt(128, 2, Pair));
     return lltok::APFloat;
   }

Modified: llvm/trunk/lib/AsmParser/LLLexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.h?rev=67562&r1=67561&r2=67562&view=diff

==============================================================================
--- llvm/trunk/lib/AsmParser/LLLexer.h (original)
+++ llvm/trunk/lib/AsmParser/LLLexer.h Mon Mar 23 16:16:53 2009
@@ -77,6 +77,7 @@
     uint64_t atoull(const char *Buffer, const char *End);
     uint64_t HexIntToVal(const char *Buffer, const char *End);
     void HexToIntPair(const char *Buffer, const char *End, uint64_t Pair[2]);
+    void FP80HexToIntPair(const char *Buff, const char *End, uint64_t Pair[2]);
   };
 } // end namespace llvm
 

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

==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Mar 23 16:16:53 2009
@@ -801,9 +801,13 @@
         V = ConstantFP::get(APFloat(APInt(32, (uint32_t)Record[0])));
       else if (CurTy == Type::DoubleTy)
         V = ConstantFP::get(APFloat(APInt(64, Record[0])));
-      else if (CurTy == Type::X86_FP80Ty)
-        V = ConstantFP::get(APFloat(APInt(80, 2, &Record[0])));
-      else if (CurTy == Type::FP128Ty)
+      else if (CurTy == Type::X86_FP80Ty) {
+        // Bits are not stored the same way as a normal i80 APInt, compensate.
+        uint64_t Rearrange[2];
+        Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16);
+        Rearrange[1] = Record[0] >> 48;
+        V = ConstantFP::get(APFloat(APInt(80, 2, Rearrange)));
+      } else if (CurTy == Type::FP128Ty)
         V = ConstantFP::get(APFloat(APInt(128, 2, &Record[0]), true));
       else if (CurTy == Type::PPC_FP128Ty)
         V = ConstantFP::get(APFloat(APInt(128, 2, &Record[0])));

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

==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Mar 23 16:16:53 2009
@@ -559,10 +559,11 @@
         Record.push_back(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
       } else if (Ty == Type::X86_FP80Ty) {
         // api needed to prevent premature destruction
+        // bits are not in the same order as a normal i80 APInt, compensate.
         APInt api = CFP->getValueAPF().bitcastToAPInt();
         const uint64_t *p = api.getRawData();
-        Record.push_back(p[0]);
-        Record.push_back((uint16_t)p[1]);
+        Record.push_back((p[1] << 48) | (p[0] >> 16));
+        Record.push_back(p[0] & 0xffffLL);
       } else if (Ty == Type::FP128Ty || Ty == Type::PPC_FP128Ty) {
         APInt api = CFP->getValueAPF().bitcastToAPInt();
         const uint64_t *p = api.getRawData();

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

==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Mon Mar 23 16:16:53 2009
@@ -1046,10 +1046,13 @@
     DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
                       &ignored);
     if (TD->isBigEndian()) {
-      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48)
+      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1])
         << '\t' << TAI->getCommentString()
         << " long double most significant halfword of ~"
         << DoubleVal.convertToDouble() << '\n';
+      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48)
+        << '\t' << TAI->getCommentString()
+        << " long double next halfword\n";
       O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 32)
         << '\t' << TAI->getCommentString()
         << " long double next halfword\n";
@@ -1058,18 +1061,12 @@
         << " long double next halfword\n";
       O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0])
         << '\t' << TAI->getCommentString()
-        << " long double next halfword\n";
-      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1])
-        << '\t' << TAI->getCommentString()
         << " long double least significant halfword\n";
      } else {
-      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1])
+      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0])
         << '\t' << TAI->getCommentString()
         << " long double least significant halfword of ~"
         << DoubleVal.convertToDouble() << '\n';
-      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0])
-        << '\t' << TAI->getCommentString()
-        << " long double next halfword\n";
       O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 16)
         << '\t' << TAI->getCommentString()
         << " long double next halfword\n";
@@ -1078,6 +1075,9 @@
         << " long double next halfword\n";
       O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48)
         << '\t' << TAI->getCommentString()
+        << " long double next halfword\n";
+      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1])
+        << '\t' << TAI->getCommentString()
         << " long double most significant halfword\n";
     }
     EmitZeros(TD->getTypePaddedSize(Type::X86_FP80Ty) -

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

==============================================================================
--- llvm/trunk/lib/Support/APFloat.cpp (original)
+++ llvm/trunk/lib/Support/APFloat.cpp Mon Mar 23 16:16:53 2009
@@ -2603,10 +2603,9 @@
   }
 
   uint64_t words[2];
-  words[0] =  ((uint64_t)(sign & 1) << 63) |
-              ((myexponent & 0x7fffLL) <<  48) |
-              ((mysignificand >>16) & 0xffffffffffffLL);
-  words[1] = mysignificand & 0xffff;
+  words[0] = mysignificand;
+  words[1] =  ((uint64_t)(sign & 1) << 15) |
+              (myexponent & 0x7fffLL);
   return APInt(80, 2, words);
 }
 
@@ -2764,14 +2763,13 @@
   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);
+  uint64_t myexponent = (i2 & 0x7fff);
+  uint64_t mysignificand = i1;
 
   initialize(&APFloat::x87DoubleExtended);
   assert(partCount()==2);
 
-  sign = static_cast<unsigned int>(i1>>63);
+  sign = static_cast<unsigned int>(i2>>15);
   if (myexponent==0 && mysignificand==0) {
     // exponent, significand meaningless
     category = fcZero;

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

==============================================================================
--- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original)
+++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Mon Mar 23 16:16:53 2009
@@ -2087,9 +2087,8 @@
     APInt api = FPC->getValueAPF().bitcastToAPInt();
     const uint64_t *p = api.getRawData();
     Out << "static const ConstantFP80Ty FPConstant" << FPCounter++
-    << " = { 0x"
-    << utohexstr((uint16_t)p[1] | (p[0] & 0xffffffffffffLL)<<16)
-    << "ULL, 0x" << utohexstr((uint16_t)(p[0] >> 48)) << ",{0,0,0}"
+    << " = { 0x" << utohexstr(p[0]) 
+    << "ULL, 0x" << utohexstr((uint16_t)p[1]) << ",{0,0,0}"
     << "}; /* Long double constant */\n";
   } else if (FPC->getType() == Type::PPC_FP128Ty) {
     APInt api = FPC->getValueAPF().bitcastToAPInt();

Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=67562&r1=67561&r2=67562&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/AsmWriter.cpp (original)
+++ llvm/trunk/lib/VMCore/AsmWriter.cpp Mon Mar 23 16:16:53 2009
@@ -797,9 +797,29 @@
     // Some form of long double.  These appear as a magic letter identifying
     // the type, then a fixed number of hex digits.
     Out << "0x";
-    if (&CFP->getValueAPF().getSemantics() == &APFloat::x87DoubleExtended)
+    if (&CFP->getValueAPF().getSemantics() == &APFloat::x87DoubleExtended) {
       Out << 'K';
-    else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad)
+      // api needed to prevent premature destruction
+      APInt api = CFP->getValueAPF().bitcastToAPInt();
+      const uint64_t* p = api.getRawData();
+      uint64_t word = p[1];
+      int shiftcount=12;
+      int width = api.getBitWidth();
+      for (int j=0; j<width; j+=4, shiftcount-=4) {
+        unsigned int nibble = (word>>shiftcount) & 15;
+        if (nibble < 10)
+          Out << (unsigned char)(nibble + '0');
+        else
+          Out << (unsigned char)(nibble - 10 + 'A');
+        if (shiftcount == 0 && j+4 < width) {
+          word = *p;
+          shiftcount = 64;
+          if (width-j-4 < 64)
+            shiftcount = width-j-4;
+        }
+      }
+      return;
+    } else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad)
       Out << 'L';
     else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble)
       Out << 'M';

Added: llvm/trunk/test/CodeGen/X86/2009-03-23-i80-fp80.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-03-23-i80-fp80.ll?rev=67562&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/2009-03-23-i80-fp80.ll (added)
+++ llvm/trunk/test/CodeGen/X86/2009-03-23-i80-fp80.ll Mon Mar 23 16:16:53 2009
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep 302245289961712575840256
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep K40018000000000000000
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i686-apple-darwin9"
+
+define i80 @from() {
+  %tmp = bitcast x86_fp80 0xK4000C000000000000000 to i80
+  ret i80 %tmp
+}
+
+define x86_fp80 @to() {
+  %tmp = bitcast i80 302259125019767858003968 to x86_fp80
+  ret x86_fp80 %tmp
+}





More information about the llvm-commits mailing list