aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2009-03-23 21:16:53 +0000
committerDale Johannesen <dalej@apple.com>2009-03-23 21:16:53 +0000
commit1b25cb2416c46a6cebf2a6c52235e9fe46a10d11 (patch)
tree70fbe0beb7dc9d7c44f2216bcc8cb4822f7460e5 /lib
parentad20778705d7568eb5db8c5214d7e01ebc28dd8b (diff)
downloadexternal_llvm-1b25cb2416c46a6cebf2a6c52235e9fe46a10d11.zip
external_llvm-1b25cb2416c46a6cebf2a6c52235e9fe46a10d11.tar.gz
external_llvm-1b25cb2416c46a6cebf2a6c52235e9fe46a10d11.tar.bz2
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67562 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AsmParser/LLLexer.cpp35
-rw-r--r--lib/AsmParser/LLLexer.h1
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp10
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp5
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp16
-rw-r--r--lib/Support/APFloat.cpp14
-rw-r--r--lib/Target/CBackend/CBackend.cpp5
-rw-r--r--lib/VMCore/AsmWriter.cpp24
8 files changed, 83 insertions, 27 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 5a38e60..95e6c90 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -115,6 +115,37 @@ void LLLexer::HexToIntPair(const char *Buffer, const char *End,
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 @@ lltok::Kind LLLexer::Lex0x() {
}
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;
}
diff --git a/lib/AsmParser/LLLexer.h b/lib/AsmParser/LLLexer.h
index adf053c..995aa4e 100644
--- a/lib/AsmParser/LLLexer.h
+++ b/lib/AsmParser/LLLexer.h
@@ -77,6 +77,7 @@ namespace llvm {
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
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 299ce0b..69eadd9 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -801,9 +801,13 @@ bool BitcodeReader::ParseConstants() {
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])));
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index 1055564..d4d3443 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -559,10 +559,11 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
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();
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 2a64524..79d14f7 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1046,10 +1046,13 @@ void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP,
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 @@ void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP,
<< " 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 @@ void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP,
<< " 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) -
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index d7f0d82..2ee6a27 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -2603,10 +2603,9 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const
}
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 @@ 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);
+ 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;
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 53c9864..fc99f50 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -2087,9 +2087,8 @@ void CWriter::printFloatingPointConstants(const Constant *C) {
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();
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index 1d52d63..3f8be47 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -797,9 +797,29 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
// 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';