aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 83c370e..baa9de0 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 390544d..5acbbac 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 6364b29..c0374da 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 8715f89..0642993 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 73f5338..78a16d8 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 e80afd4..49bcba7 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 af2555d..1c9b0fe 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 32f81d3..2050d23 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 31e2947..d7eb85b 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 01ec5c9..85a76f4 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 9b8caa8..96fdc42 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 0221174..f25b113 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 7178970..cd67df1 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 6d3bcf7..95450ac 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 4dc1340..e11b749 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 1551dc3..a56c7cd 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