summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2007-09-11 18:32:33 +0000
committerDale Johannesen <dalej@apple.com>2007-09-11 18:32:33 +0000
commit3f6eb7419de437436265831fce92f62498556e08 (patch)
treecb752d4a86ec5c5dd783cfc421e30d0cf7600e87
parent6320260e060ce4fc5d199d757b15a0f43be66029 (diff)
downloadllvm-3f6eb7419de437436265831fce92f62498556e08.tar.gz
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). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41858 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/ADT/APFloat.h9
-rw-r--r--lib/AsmParser/Lexer.l60
-rw-r--r--lib/AsmParser/llvmAsmParser.y13
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp11
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp19
-rw-r--r--lib/CodeGen/AsmPrinter.cpp18
-rw-r--r--lib/CodeGen/MachOWriter.cpp8
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp8
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp14
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp13
-rw-r--r--lib/Support/APFloat.cpp164
-rw-r--r--lib/Target/CBackend/CBackend.cpp7
-rw-r--r--lib/Target/MSIL/MSILWriter.cpp8
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp32
-rw-r--r--lib/VMCore/ConstantFold.cpp21
-rw-r--r--tools/llvm2cpp/CppWriter.cpp4
16 files changed, 309 insertions, 100 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index 83c370eb7459..baa9de025789 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -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 &);
diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l
index 390544d8c3d9..5acbbacf60fd 100644
--- a/lib/AsmParser/Lexer.l
+++ b/lib/AsmParser/Lexer.l
@@ -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
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index 6364b29bcd77..c0374daf3f1c 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -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;
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 8715f89c2574..06429931dbdf 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -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())
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index 73f5338dcceb..78a16d8f6273 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -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!");
}
diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp
index e80afd40eeda..49bcba781418 100644
--- a/lib/CodeGen/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter.cpp
@@ -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;
}
diff --git a/lib/CodeGen/MachOWriter.cpp b/lib/CodeGen/MachOWriter.cpp
index af2555d3eed9..1c9b0feff54e 100644
--- a/lib/CodeGen/MachOWriter.cpp
+++ b/lib/CodeGen/MachOWriter.cpp
@@ -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;
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 32f81d38f266..2050d23ad72b 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -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);
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 31e29470e803..d7eb85bd8fb0 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -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);
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 01ec5c968aa0..85a76f436b1b 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -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;
}
}
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index 9b8caa89ffcb..96fdc42fb26a 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -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));
+}
+
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 0221174e5cfd..f25b1133b24d 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -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!");
diff --git a/lib/Target/MSIL/MSILWriter.cpp b/lib/Target/MSIL/MSILWriter.cpp
index 71789703ff39..cd67df17a6fb 100644
--- a/lib/Target/MSIL/MSILWriter.cpp
+++ b/lib/Target/MSIL/MSILWriter.cpp
@@ -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:
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 6d3bcf7bb51c..95450ac97fac 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -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);
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 4dc1340f908c..e11b749f9be8 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -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;
diff --git a/tools/llvm2cpp/CppWriter.cpp b/tools/llvm2cpp/CppWriter.cpp
index 1551dc3be780..a56c7cdd41a8 100644
--- a/tools/llvm2cpp/CppWriter.cpp
+++ b/tools/llvm2cpp/CppWriter.cpp
@@ -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