diff options
author | Dale Johannesen <dalej@apple.com> | 2007-09-11 18:32:33 +0000 |
---|---|---|
committer | Dale Johannesen <dalej@apple.com> | 2007-09-11 18:32:33 +0000 |
commit | 3f6eb7419de437436265831fce92f62498556e08 (patch) | |
tree | cb752d4a86ec5c5dd783cfc421e30d0cf7600e87 | |
parent | 6320260e060ce4fc5d199d757b15a0f43be66029 (diff) | |
download | external_llvm-3f6eb7419de437436265831fce92f62498556e08.zip external_llvm-3f6eb7419de437436265831fce92f62498556e08.tar.gz external_llvm-3f6eb7419de437436265831fce92f62498556e08.tar.bz2 |
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.h | 9 | ||||
-rw-r--r-- | lib/AsmParser/Lexer.l | 60 | ||||
-rw-r--r-- | lib/AsmParser/llvmAsmParser.y | 13 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 11 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 19 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter.cpp | 18 | ||||
-rw-r--r-- | lib/CodeGen/MachOWriter.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 14 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 13 | ||||
-rw-r--r-- | lib/Support/APFloat.cpp | 164 | ||||
-rw-r--r-- | lib/Target/CBackend/CBackend.cpp | 7 | ||||
-rw-r--r-- | lib/Target/MSIL/MSILWriter.cpp | 8 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 32 | ||||
-rw-r--r-- | lib/VMCore/ConstantFold.cpp | 21 | ||||
-rw-r--r-- | tools/llvm2cpp/CppWriter.cpp | 4 |
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 |